]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: add json, binary and human readable output format for id iocs
authorGollu Appalanaidu <anaidu.gollu@samsung.com>
Fri, 28 May 2021 18:11:33 +0000 (23:41 +0530)
committerKeith Busch <kbusch@kernel.org>
Fri, 11 Jun 2021 15:56:23 +0000 (09:56 -0600)
Signed-off-by: Gollu Appalanaidu <anaidu.gollu@samsung.com>
Documentation/nvme-id-iocs.1
Documentation/nvme-id-iocs.html
Documentation/nvme-id-iocs.txt
linux/nvme.h
nvme-print.c
nvme-print.h
nvme.c

index f79b4de2d6d14d8f94aebdbd96093d075da329aa..2320de32dabf86af5fb81f27f5962de5168fae39 100644 (file)
@@ -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 <http://docbook.sf.net/>
-.\"      Date: 10/20/2020
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      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 <device> [\-\-controller\-id=<cntid> | \-c <cntid>]
+                        [\-o <fmt> | \-\-output\-format=<fmt>]
 .fi
 .SH "DESCRIPTION"
 .sp
@@ -45,6 +46,19 @@ The <device> 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 <format>, \-\-output\-format=<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
index 6bc983f717b38526cdd425a724dfcca74545246f..159f3063cf8fe8f0345c985317fd224c2bfea296 100644 (file)
@@ -749,7 +749,8 @@ nvme-id-iocs(1) Manual Page
 <h2 id="_synopsis">SYNOPSIS</h2>\r
 <div class="sectionbody">\r
 <div class="verseblock">\r
-<pre class="content"><em>nvme id-iocs</em> &lt;device&gt; [--controller-id=&lt;cntid&gt; | -c &lt;cntid&gt;]</pre>\r
+<pre class="content"><em>nvme id-iocs</em> &lt;device&gt; [--controller-id=&lt;cntid&gt; | -c &lt;cntid&gt;]\r
+                        [-o &lt;fmt&gt; | --output-format=&lt;fmt&gt;]</pre>\r
 <div class="attribution">\r
 </div></div>\r
 </div>\r
@@ -779,6 +780,30 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></di
         cntid. If this value is not given, cntid will be 0xffff.\r
 </p>\r
 </dd>\r
+<dt class="hdlist1">\r
+-H\r
+</dt>\r
+<dt class="hdlist1">\r
+--human-readable\r
+</dt>\r
+<dd>\r
+<p>\r
+        This option will parse and format many of the bit fields\r
+        into human-readable formats.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+-o &lt;format&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+--output-format=&lt;format&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+              Set the reporting format to <em>normal</em>, <em>json</em>, or\r
+              <em>binary</em>. Only one output format can be used at a time.\r
+</p>\r
+</dd>\r
 </dl></div>\r
 </div>\r
 </div>\r
@@ -796,6 +821,15 @@ fields in a human readable format:
 <pre><code># nvme id-iocs /dev/nvme0</code></pre>\r
 </div></div>\r
 </li>\r
+<li>\r
+<p>\r
+show the fields in human readable format\r
+</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code># nvme id-iocs /dev/nvme0 -H</code></pre>\r
+</div></div>\r
+</li>\r
 </ul></div>\r
 </div>\r
 </div>\r
@@ -810,7 +844,7 @@ fields in a human readable format:
 <div id="footer">\r
 <div id="footer-text">\r
 Last updated\r
- 2020-05-06 10:39:59 CEST\r
+ 2021-05-28 23:15:06 IST\r
 </div>\r
 </div>\r
 </body>\r
index 9e53207a8b78956b28be4759fb1bb9189a51e492..a35217e15ffc9760e63bb6f80fcaf82307211fed 100644 (file)
@@ -9,6 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'nvme id-iocs' <device> [--controller-id=<cntid> | -c <cntid>]
+                        [-o <fmt> | --output-format=<fmt>]
 
 DESCRIPTION
 -----------
@@ -24,6 +25,15 @@ OPTIONS
 --controller-id=<cntid>::
        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 <format>::
+--output-format=<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
index f3cbe7348bb8cb746048eee24d975daf9a379810..5ec2cd37aea316b9b9d60693edec830514e463d5 100644 (file)
@@ -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 {
index fa651c0d7cd9c7dbb21318d84a632722b6fe64ca..9cfb9bef3a7517d78aab9294363bf30e0a874eb1 100755 (executable)
@@ -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)
index a988dd0fc2e988b3e23b50e51da627ffe9a24ed1..46abc0ba6ae7331204723a0b4c71bf1ad556038b 100644 (file)
@@ -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 c18ac84e3997b33634c11fbefe1eeb2c8f4d8554..969be9ef73296d2ef00c56410d1583ae7c94dc59 100644 (file)
--- 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);