]> www.infradead.org Git - users/hch/nvme-cli.git/commitdiff
Add additional smart log critical warn decoding
authorWen Xiong <wenxiong@linux.vnet.ibm.com>
Wed, 8 Jan 2020 20:24:41 +0000 (12:24 -0800)
committerKeith Busch <kbusch@kernel.org>
Wed, 8 Jan 2020 20:26:47 +0000 (12:26 -0800)
Provide a user option to request additional smart log page decoding,
and print out detailed critical warning when requested.

Signed-off-by: Wendy Xiong<wenxiong@linux.vnet.ibm.com>
[merge up, rename json keys]
Signed-off-by: Keith Busch <kbusch@kernel.org>
nvme-print.c
nvme.c

index 2ba1de119cb6e004ab2b677164a46b14e91147c8..46d522849e7e066824fead5721b21863071820a6 100644 (file)
@@ -585,10 +585,11 @@ static void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
        json_free_object(root);
 }
 
-static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid)
+static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
+       enum nvme_print_flags flags)
 {
+       int c, human = flags & VERBOSE;
        struct json_object *root;
-       int c;
        char key[21];
 
        unsigned int temperature = ((smart->temperature[1] << 8) |
@@ -607,8 +608,22 @@ static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid)
 
        root = json_create_object();
 
-       json_object_add_value_int(root, "critical_warning",
-               smart->critical_warning);
+       if (human) {
+               struct json_object *crt = json_create_object();
+
+               json_object_add_value_int(crt, "value", smart->critical_warning);
+               json_object_add_value_int(crt, "available_spare", smart->critical_warning & 0x01);
+               json_object_add_value_int(crt, "temp_threshold", (smart->critical_warning & 0x02) >> 1);
+               json_object_add_value_int(crt, "reliability_degraded", (smart->critical_warning & 0x04) >> 2);
+               json_object_add_value_int(crt, "ro", (smart->critical_warning & 0x08) >> 3);
+               json_object_add_value_int(crt, "vmbu_failed", (smart->critical_warning & 0x10) >> 4);
+               json_object_add_value_int(crt, "pmr_ro", (smart->critical_warning & 0x20) >> 5);
+
+               json_object_add_value_object(root, "critical_warning", crt);
+       } else
+               json_object_add_value_int(root, "critical_warning",
+                       smart->critical_warning);
+
        json_object_add_value_int(root, "temperature", temperature);
        json_object_add_value_int(root, "avail_spare", smart->avail_spare);
        json_object_add_value_int(root, "spare_thresh", smart->spare_thresh);
@@ -3400,16 +3415,26 @@ void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
        /* convert temperature from Kelvin to Celsius */
        int temperature = ((smart->temperature[1] << 8) |
                            smart->temperature[0]) - 273;
-       int i;
+       int i, human = flags & VERBOSE;
 
        if (flags & BINARY)
                return d_raw((unsigned char *)smart, sizeof(*smart));
        else if (flags & JSON)
-               return json_smart_log(smart, nsid);
+               return json_smart_log(smart, nsid, flags);
 
        printf("Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
        printf("critical_warning                        : %#x\n",
                smart->critical_warning);
+
+       if (human) {
+               printf("      Available Spare[0]             : %d\n", smart->critical_warning & 0x01);
+               printf("      Temp. Threshold[1]             : %d\n", (smart->critical_warning & 0x02) >> 1);
+               printf("      NVM subsystem Reliability[2]   : %d\n", (smart->critical_warning & 0x04) >> 2);
+               printf("      Read-only[3]                   : %d\n", (smart->critical_warning & 0x08) >> 3);
+               printf("      Volatile mem. backup failed[4] : %d\n", (smart->critical_warning & 0x10) >> 4);
+               printf("      Persistent Mem. RO[5]          : %d\n", (smart->critical_warning & 0x20) >> 5);
+       }
+
        printf("temperature                             : %d C\n",
                temperature);
        printf("available_spare                         : %u%%\n",
diff --git a/nvme.c b/nvme.c
index 3b386bcc3c75dd75cd4884722ee5ca4a11f0defc..dd3ab5870e62209d5674c4216b4d92818ecd2720 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -218,6 +218,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
                        "(default) or binary.";
        const char *namespace = "(optional) desired namespace";
        const char *raw = "output in binary format";
+       const char *human_readable = "show info in readable format";
        enum nvme_print_flags flags;
        int err, fd;
 
@@ -225,6 +226,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
                __u32 namespace_id;
                int   raw_binary;
                char *output_format;
+               int   human_readable;
        };
 
        struct config cfg = {
@@ -234,9 +236,10 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
 
 
        OPT_ARGS(opts) = {
-               OPT_UINT("namespace-id", 'n', &cfg.namespace_id,  namespace),
-               OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
-               OPT_FLAG("raw-binary",   'b', &cfg.raw_binary,    raw),
+               OPT_UINT("namespace-id",   'n', &cfg.namespace_id,   namespace),
+               OPT_FMT("output-format",   'o', &cfg.output_format,  output_format),
+               OPT_FLAG("raw-binary",     'b', &cfg.raw_binary,     raw),
+               OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
                OPT_END()
        };
 
@@ -249,6 +252,8 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
                goto close_fd;
        if (cfg.raw_binary)
                flags = BINARY;
+       if (cfg.human_readable)
+               flags |= VERBOSE;
 
        err = nvme_smart_log(fd, cfg.namespace_id, &smart_log);
        if (!err)