From: Gollu Appalanaidu Date: Fri, 28 May 2021 18:11:33 +0000 (+0530) Subject: nvme: add json, binary and human readable output format for id iocs X-Git-Tag: v1.15~50 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7f9f9b95dbec6f988ff0724d6947fa39c6c0e058;p=users%2Fsagi%2Fnvme-cli.git nvme: add json, binary and human readable output format for id iocs Signed-off-by: Gollu Appalanaidu --- diff --git a/Documentation/nvme-id-iocs.1 b/Documentation/nvme-id-iocs.1 index f79b4de2..2320de32 100644 --- a/Documentation/nvme-id-iocs.1 +++ b/Documentation/nvme-id-iocs.1 @@ -1,13 +1,13 @@ '\" t .\" Title: nvme-id-iocs -.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author] -.\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 10/20/2020 +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Date: 05/28/2021 .\" Manual: NVMe Manual .\" Source: NVMe .\" Language: English .\" -.TH "NVME\-ID\-IOCS" "1" "10/20/2020" "NVMe" "NVMe Manual" +.TH "NVME\-ID\-IOCS" "1" "05/28/2021" "NVMe" "NVMe Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -33,6 +33,7 @@ nvme-id-iocs \- Send NVMe Identify I/O Command Set, return result and structure .sp .nf \fInvme id\-iocs\fR [\-\-controller\-id= | \-c ] + [\-o | \-\-output\-format=] .fi .SH "DESCRIPTION" .sp @@ -45,6 +46,19 @@ The parameter is mandatory and may be either the NVMe character device .RS 4 Retrieve the identify I/O Command set data structure for the given cntid\&. If this value is not given, cntid will be 0xffff\&. .RE +.PP +\-H, \-\-human\-readable +.RS 4 +This option will parse and format many of the bit fields into human\-readable formats\&. +.RE +.PP +\-o , \-\-output\-format= +.RS 4 +Set the reporting format to +\fInormal\fR, +\fIjson\fR, or +\fIbinary\fR\&. Only one output format can be used at a time\&. +.RE .SH "EXAMPLES" .sp .RS 4 @@ -67,6 +81,27 @@ Have the program interpret the returned buffer and display the known fields in a .RE .\} .RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +show the fields in human readable format +.sp +.if n \{\ +.RS 4 +.\} +.nf +# nvme id\-iocs /dev/nvme0 \-H +.fi +.if n \{\ +.RE +.\} +.RE .SH "NVME" .sp Part of the nvme\-user suite diff --git a/Documentation/nvme-id-iocs.html b/Documentation/nvme-id-iocs.html index 6bc983f7..159f3063 100644 --- a/Documentation/nvme-id-iocs.html +++ b/Documentation/nvme-id-iocs.html @@ -749,7 +749,8 @@ nvme-id-iocs(1) Manual Page

SYNOPSIS

-
nvme id-iocs <device> [--controller-id=<cntid> | -c <cntid>]
+
nvme id-iocs <device> [--controller-id=<cntid> | -c <cntid>]
+                        [-o <fmt> | --output-format=<fmt>]
@@ -779,6 +780,30 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).

+
+-H +
+
+--human-readable +
+
+

+ This option will parse and format many of the bit fields + into human-readable formats. +

+
+
+-o <format> +
+
+--output-format=<format> +
+
+

+ Set the reporting format to normal, json, or + binary. Only one output format can be used at a time. +

+
@@ -796,6 +821,15 @@ fields in a human readable format:
# nvme id-iocs /dev/nvme0
+
  • +

    +show the fields in human readable format +

    +
    +
    +
    # nvme id-iocs /dev/nvme0 -H
    +
    +
  • @@ -810,7 +844,7 @@ fields in a human readable format: diff --git a/Documentation/nvme-id-iocs.txt b/Documentation/nvme-id-iocs.txt index 9e53207a..a35217e1 100644 --- a/Documentation/nvme-id-iocs.txt +++ b/Documentation/nvme-id-iocs.txt @@ -9,6 +9,7 @@ SYNOPSIS -------- [verse] 'nvme id-iocs' [--controller-id= | -c ] + [-o | --output-format=] DESCRIPTION ----------- @@ -24,6 +25,15 @@ OPTIONS --controller-id=:: Retrieve the identify I/O Command set data structure for the given cntid. If this value is not given, cntid will be 0xffff. +-H:: +--human-readable:: + This option will parse and format many of the bit fields + into human-readable formats. + +-o :: +--output-format=:: + Set the reporting format to 'normal', 'json', or + 'binary'. Only one output format can be used at a time. EXAMPLES -------- @@ -33,7 +43,12 @@ fields in a human readable format: ------------ # nvme id-iocs /dev/nvme0 ------------ - ++ +* show the fields in human readable format ++ +------------ +# nvme id-iocs /dev/nvme0 -H +------------ NVME ---- Part of the nvme-user suite diff --git a/linux/nvme.h b/linux/nvme.h index f3cbe734..5ec2cd37 100644 --- a/linux/nvme.h +++ b/linux/nvme.h @@ -147,6 +147,8 @@ enum { NVME_IOCS_ZONED = 0x02, }; +#define NVME_NUM_IOCS_COMBINATIONS 512 + #define NVME_AQ_DEPTH 32 #define NVME_NR_AEN_COMMANDS 1 #define NVME_AQ_BLK_MQ_DEPTH (NVME_AQ_DEPTH - NVME_NR_AEN_COMMANDS) @@ -425,7 +427,7 @@ struct nvme_id_ns { }; struct nvme_id_iocs { - __le64 iocs[512]; + __le64 iocs[NVME_NUM_IOCS_COMBINATIONS]; }; enum { diff --git a/nvme-print.c b/nvme-print.c index fa651c0d..9cfb9bef 100755 --- a/nvme-print.c +++ b/nvme-print.c @@ -4611,14 +4611,67 @@ void nvme_show_id_uuid_list(const struct nvme_id_uuid_list *uuid_list, } } -void nvme_show_id_iocs(struct nvme_id_iocs *iocs) +static void nvme_show_iocs_vector(__u64 iocs_vec) +{ + __u64 rsvd3 = iocs_vec >> 3; + __u8 zns_cmd_set = (iocs_vec >> 2) & 0x1; + __u8 kv_cmd_set = (iocs_vec >> 1) & 0x1; + __u8 nvm_cmd_set = iocs_vec & 0x1; + + if (rsvd3) + printf(" [63:3] : %"PRIx64"\tReserved3\n", le64_to_cpu(rsvd3)); + printf(" [2:2] : %#x\tZNS Command Set %sSelected\n", + zns_cmd_set, zns_cmd_set ? "" : "not "); + printf(" [1:1] : %#x\tKV Command Set %sSelected\n", + kv_cmd_set, kv_cmd_set ? "" : "not "); + printf(" [0:0] : %#x\tNVM Command Set %sSelected\n", + nvm_cmd_set, nvm_cmd_set ? "" : "not "); + printf("\n"); +} + +static void json_id_iocs(struct nvme_id_iocs *iocs) +{ + struct json_object *root; + struct json_object *entries; + int i; + + root = json_create_object(); + entries = json_create_array(); + + for (i = 0; i < NVME_NUM_IOCS_COMBINATIONS; i++) { + if (iocs->iocs[i]) { + struct json_object *entry = json_create_object(); + json_object_add_value_uint(entry, "iocs", + le64_to_cpu(iocs->iocs[i])); + json_array_add_value_object(entries, entry); + } + } + + json_object_add_value_array(root, "iocs_list", entries); + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); + +} + +void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags) { - __u16 i; + if (flags & BINARY) + return d_raw((unsigned char *)iocs, sizeof(*iocs)); + else if (flags & JSON) + return json_id_iocs(iocs); + + bool human = flags & VERBOSE; + int i; - for (i = 0; i < 512; i++) - if (iocs->iocs[i]) - printf("I/O Command Set Combination[%u]:%"PRIx64"\n", i, + for (i = 0; i < NVME_NUM_IOCS_COMBINATIONS; i++) { + if (iocs->iocs[i]) { + printf("I/O Command Set Combination[%u]: %"PRIx64"\n", i, (uint64_t)le64_to_cpu(iocs->iocs[i])); + if (human) + nvme_show_iocs_vector(le64_to_cpu(iocs->iocs[i])); + } + } } static const char *nvme_trtype_to_string(__u8 trtype) diff --git a/nvme-print.h b/nvme-print.h index a988dd0f..46abc0ba 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -83,7 +83,7 @@ void nvme_show_id_ns_granularity_list(const struct nvme_id_ns_granularity_list * enum nvme_print_flags flags); void nvme_show_id_uuid_list(const struct nvme_id_uuid_list *uuid_list, enum nvme_print_flags flags); -void nvme_show_id_iocs(struct nvme_id_iocs *iocs); +void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags); void nvme_show_list_ctrl(struct nvme_controller_list *ctrl_list, enum nvme_print_flags flags); void nvme_show_list_ns(__u32 *ns_list, enum nvme_print_flags flags); diff --git a/nvme.c b/nvme.c index c18ac84e..969be9ef 100644 --- a/nvme.c +++ b/nvme.c @@ -2340,19 +2340,26 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl "given device, returns properties of the specified controller "\ "in either human-readable or binary format."; const char *controller_id = "identifier of desired controller"; + const char *human_readable = "show info in human readable format"; struct nvme_id_iocs iocs; + enum nvme_print_flags flags; int err, fd; struct config { __u16 cntid; + char *output_format; + int human_readable; }; struct config cfg = { .cntid = 0xffff, + .output_format = "normal", }; OPT_ARGS(opts) = { - OPT_SHRT("controller-id", 'c', &cfg.cntid, controller_id), + OPT_SHRT("controller-id", 'c', &cfg.cntid, controller_id), + OPT_FMT("output-format", 'o', &cfg.output_format, output_format), + OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable), OPT_END() }; @@ -2362,15 +2369,22 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl goto ret; } + err = flags = validate_output_format(cfg.output_format); + if (flags < 0) + goto close_fd; + if (cfg.human_readable) + flags |= VERBOSE; + err = nvme_identify_iocs(fd, cfg.cntid, &iocs); if (!err) { printf("NVMe Identify I/O Command Set:\n"); - nvme_show_id_iocs(&iocs); + nvme_show_id_iocs(&iocs, flags); } else if (err > 0) nvme_show_status(err); else perror("NVMe Identify I/O Command Set"); +close_fd: close(fd); ret: return nvme_status_to_errno(err, false);