]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: add reachability-associations-log command
authorTokunori Ikegami <ikegami.t@gmail.com>
Tue, 11 Feb 2025 15:15:37 +0000 (00:15 +0900)
committerDaniel Wagner <wagi@monom.org>
Thu, 13 Feb 2025 14:28:55 +0000 (15:28 +0100)
Since added the NVMe 2.1 log page.

Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
nvme-builtin.h
nvme-print-binary.c
nvme-print-json.c
nvme-print-stdout.c
nvme-print.c
nvme-print.h
nvme-wrap.c
nvme-wrap.h
nvme.c

index b97d2dded7c1892d8c37894910b70d6b96c5b4b0..6c71143d2cf3ad15ff949bc1a0fc041481c3a1f5 100644 (file)
@@ -63,6 +63,7 @@ COMMAND_LIST(
        ENTRY("changed-alloc-ns-list-log", "Retrieve Changed Allocated Namespace List, show it", get_changed_alloc_ns_list_log)
        ENTRY("dispersed-ns-participating-nss-log", "Retrieve Dispersed Namespace Participating NVM Subsystems Log, show it", get_dispersed_ns_participating_nss_log)
        ENTRY("reachability-groups-log", "Retrieve Reachability Groups Log, show it", get_reachability_groups_log)
+       ENTRY("reachability-associations-log", "Retrieve Reachability Associations Log, show it", get_reachability_associations_log)
        ENTRY("set-feature", "Set a feature and show the resulting value", set_feature)
        ENTRY("set-property", "Set a property and show the resulting value", set_property)
        ENTRY("get-property", "Get a property and show the resulting value", get_property)
index dcaaddc6df2723301585cbad640962e3fa274e17..a1e4885a6e382b44c71dc38288b6efa236f20214 100644 (file)
@@ -326,6 +326,11 @@ static void binary_reachability_groups_log(struct nvme_reachability_groups_log *
        d_raw((unsigned char *)log, sizeof(*log));
 }
 
+static void binary_reachability_associations_log(struct nvme_reachability_associations_log *log)
+{
+       d_raw((unsigned char *)log, sizeof(*log));
+}
+
 static struct print_ops binary_print_ops = {
        /* libnvme types.h print functions */
        .ana_log                        = binary_ana_log,
@@ -396,6 +401,7 @@ static struct print_ops binary_print_ops = {
        .rotational_media_info_log      = binary_rotational_media_info_log,
        .dispersed_ns_psub_log          = binary_dispersed_ns_psub_log,
        .reachability_groups_log        = binary_reachability_groups_log,
+       .reachability_associations_log  = binary_reachability_associations_log,
 
        /* libnvme tree print functions */
        .list_item                      = NULL,
index 5320f5736bc96ea6d9be08346ac50c4d3ab4d3cb..4f342eb51861980d808e1ff2f3b410f26d86f6cf 100644 (file)
@@ -4701,6 +4701,31 @@ static void json_reachability_groups_log(struct nvme_reachability_groups_log *lo
        json_print(r);
 }
 
+static void json_reachability_associations_log(struct nvme_reachability_associations_log *log)
+{
+       struct json_object *r = json_create_object();
+       __u16 i;
+       __u32 j;
+       char json_str[STR_LEN];
+       struct json_object *rad;
+
+       obj_add_uint64(r, "chngc", le64_to_cpu(log->chngc));
+       obj_add_uint(r, "nrad", le16_to_cpu(log->nrad));
+
+       for (i = 0; i < le16_to_cpu(log->nrad); i++) {
+               snprintf(json_str, sizeof(json_str), "rasid: %u", le32_to_cpu(log->rad[i].rasid));
+               rad = json_create_object();
+               obj_add_uint(rad, "nrid", le32_to_cpu(log->rad[i].nrid));
+               obj_add_uint64(rad, "chngc", le64_to_cpu(log->rad[i].chngc));
+               obj_add_uint(rad, "rac", log->rad[i].rac);
+               for (j = 0; j < le32_to_cpu(log->rad[i].nrid); j++)
+                       obj_add_uint(rad, "rgid", le32_to_cpu(log->rad[i].rgid[j]));
+               obj_add_obj(r, json_str, rad);
+       }
+
+       json_print(r);
+}
+
 static struct print_ops json_print_ops = {
        /* libnvme types.h print functions */
        .ana_log                        = json_ana_log,
@@ -4772,6 +4797,7 @@ static struct print_ops json_print_ops = {
        .rotational_media_info_log      = json_rotational_media_info_log,
        .dispersed_ns_psub_log          = json_dispersed_ns_psub_log,
        .reachability_groups_log        = json_reachability_groups_log,
+       .reachability_associations_log  = json_reachability_associations_log,
 
        /* libnvme tree print functions */
        .list_item                      = json_list_item,
index f9abf03f5161d114c94f7513085d69988693f7b9..b3f95bafa5e1d09e2bbadb866021e84f16c84440 100644 (file)
@@ -5655,6 +5655,24 @@ static void stdout_reachability_groups_log(struct nvme_reachability_groups_log *
        }
 }
 
+static void stdout_reachability_associations_log(struct nvme_reachability_associations_log *log)
+{
+       __u16 i;
+       __u32 j;
+
+       printf("chngc: %"PRIu64"\n", le64_to_cpu(log->chngc));
+       printf("nrad: %u\n", le16_to_cpu(log->nrad));
+
+       for (i = 0; i < le16_to_cpu(log->nrad); i++) {
+               printf("rasid: %u\n", le32_to_cpu(log->rad[i].rasid));
+               printf("nrid: %u\n", le32_to_cpu(log->rad[i].nrid));
+               printf("chngc: %"PRIu64"\n", le64_to_cpu(log->rad[i].chngc));
+               printf("rac: %u\n", log->rad[i].rac);
+               for (j = 0; j < le32_to_cpu(log->rad[i].nrid); j++)
+                       printf("rgid%u: %u\n", j, le32_to_cpu(log->rad[i].rgid[j]));
+       }
+}
+
 static struct print_ops stdout_print_ops = {
        /* libnvme types.h print functions */
        .ana_log                        = stdout_ana_log,
@@ -5726,6 +5744,7 @@ static struct print_ops stdout_print_ops = {
        .rotational_media_info_log      = stdout_rotational_media_info_log,
        .dispersed_ns_psub_log          = stdout_dispersed_ns_psub_log,
        .reachability_groups_log        = stdout_reachability_groups_log,
+       .reachability_associations_log  = stdout_reachability_associations_log,
 
        /* libnvme tree print functions */
        .list_item                      = stdout_list_item,
index f15a3b4dee15316b5499ecf2f0e21fc7f584f624..5c0f7ca52569edfdd8a4f15df3304c68b7ec843b 100644 (file)
@@ -1514,3 +1514,9 @@ void nvme_show_reachability_groups_log(struct nvme_reachability_groups_log *log,
 {
        nvme_print(reachability_groups_log, flags, log);
 }
+
+void nvme_show_reachability_associations_log(struct nvme_reachability_associations_log *log,
+                                            nvme_print_flags_t flags)
+{
+       nvme_print(reachability_associations_log, flags, log);
+}
index 5a3d939c44004aad5668157cd869a406d42fa36b..5e6663adcc695cdb937daa72fa85af7599bdc59e 100644 (file)
@@ -92,6 +92,7 @@ struct print_ops {
        void (*rotational_media_info_log)(struct nvme_rotational_media_info_log *info);
        void (*dispersed_ns_psub_log)(struct nvme_dispersed_ns_participating_nss_log *log);
        void (*reachability_groups_log)(struct nvme_reachability_groups_log *log);
+       void (*reachability_associations_log)(struct nvme_reachability_associations_log *log);
 
        /* libnvme tree print functions */
        void (*list_item)(nvme_ns_t n);
@@ -341,4 +342,6 @@ void nvme_show_dispersed_ns_psub_log(struct nvme_dispersed_ns_participating_nss_
                                     nvme_print_flags_t flags);
 void nvme_show_reachability_groups_log(struct nvme_reachability_groups_log *log,
                                       nvme_print_flags_t flags);
+void nvme_show_reachability_associations_log(struct nvme_reachability_associations_log *log,
+                                            nvme_print_flags_t flags);
 #endif /* NVME_PRINT_H */
index cd90ceea193abda1f82544235c5f76061867c99c..371a603d74b56fc900671c4ddee5637e5bcb15dc 100644 (file)
@@ -463,3 +463,9 @@ int nvme_cli_get_log_reachability_groups(struct nvme_dev *dev, bool rgo, bool ra
 {
        return do_admin_op(get_log_reachability_groups, dev, rgo, rae, len, log);
 }
+
+int nvme_cli_get_log_reachability_associations(struct nvme_dev *dev, bool rao, bool rae, __u32 len,
+                                              struct nvme_reachability_associations_log *log)
+{
+       return do_admin_op(get_log_reachability_associations, dev, len, rao, rae, log);
+}
index 9300e8b0b644dbfa624f580ff657dbf961b5a370..d0f91c1f6a1e2d970aa3a33723b7a467aa67f636 100644 (file)
@@ -159,4 +159,7 @@ int nvme_cli_get_log_dispersed_ns_participating_nss(struct nvme_dev *dev, __u32
 
 int nvme_cli_get_log_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, __u32 len,
                                         struct nvme_reachability_groups_log *log);
+
+int nvme_cli_get_log_reachability_associations(struct nvme_dev *dev, bool rgo, bool rae, __u32 len,
+                                              struct nvme_reachability_associations_log *log);
 #endif /* _NVME_WRAP_H */
diff --git a/nvme.c b/nvme.c
index 5a98920628917ee9b9ac4c245f4e5cdcf8f03b27..4f6cde852e0c557840381fb47149ff051bfbf0df 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -10334,6 +10334,118 @@ static int get_reachability_groups_log(int argc, char **argv, struct command *cm
        return err;
 }
 
+static int get_reachability_association_desc(struct nvme_dev *dev, struct nvme_get_log_args *args,
+                                            __u64 offset,
+                                            struct nvme_reachability_associations_log **logp)
+{
+       int err;
+       struct nvme_reachability_associations_log *log = *logp;
+       __u16 i;
+       __u32 len;
+
+       for (i = 0; i < le16_to_cpu(log->nrad); i++) {
+               len = sizeof(*log->rad);
+               err = get_log_offset(dev, args, &offset, len, (void **)&log);
+               if (err)
+                       goto err_free;
+               len = le32_to_cpu(log->rad[i].nrid) * sizeof(*log->rad[i].rgid);
+               err = get_log_offset(dev, args, &offset, len, (void **)&log);
+               if (err)
+                       goto err_free;
+       }
+
+       *logp = log;
+       return 0;
+
+err_free:
+       free(log);
+       *logp = NULL;
+       return err;
+}
+
+static int get_reachability_associations(struct nvme_dev *dev, bool rao, bool rae,
+                                        struct nvme_reachability_associations_log **logp)
+{
+       int err;
+       struct nvme_reachability_associations_log *log;
+       __u64 log_len = sizeof(*log);
+       struct nvme_get_log_args args = {
+               .args_size = sizeof(args),
+               .fd = dev_fd(dev),
+               .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+               .lid = NVME_LOG_LID_REACHABILITY_ASSOCIATIONS,
+               .nsid = NVME_NSID_ALL,
+               .lsp = rao,
+               .rae = rae,
+       };
+
+       log = nvme_alloc(log_len);
+       if (!log)
+               return -ENOMEM;
+
+       err = nvme_cli_get_log_reachability_associations(dev, rao, rae, log_len, log);
+       if (err)
+               goto err_free;
+
+       err = get_reachability_association_desc(dev, &args, log_len, &log);
+       if (err)
+               goto err_free;
+
+       *logp = log;
+       return 0;
+
+err_free:
+       free(log);
+       return err;
+}
+
+static int get_reachability_associations_log(int argc, char **argv, struct command *cmd,
+                                            struct plugin *plugin)
+{
+       const char *desc = "Retrieve Reachability Associations Log, show it";
+       const char *rao = "Return Associations Only";
+       nvme_print_flags_t flags;
+       int err;
+
+       _cleanup_free_ struct nvme_reachability_associations_log *log = NULL;
+
+       _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+
+       struct config {
+               bool rao;
+               bool rae;
+       };
+
+       struct config cfg = {
+               .rao = false,
+               .rae = false,
+       };
+
+       NVME_ARGS(opts,
+                 OPT_FLAG("associations-only", 'a', &cfg.rao, rao),
+                 OPT_FLAG("rae", 'r', &cfg.rae, rae));
+
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err)
+               return err;
+
+       err = validate_output_format(nvme_cfg.output_format, &flags);
+       if (err < 0) {
+               nvme_show_error("Invalid output format");
+               return err;
+       }
+
+       err = get_reachability_associations(dev, cfg.rao, cfg.rae, &log);
+       if (!err)
+               nvme_show_reachability_associations_log(log, flags);
+       else if (err > 0)
+               nvme_show_status(err);
+       else
+               nvme_show_perror("reachability associations log");
+
+       return err;
+}
+
 void register_extension(struct plugin *plugin)
 {
        plugin->parent = &nvme;