]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: add reachability-groups-log command
authorTokunori Ikegami <ikegami.t@gmail.com>
Mon, 10 Feb 2025 14:56:07 +0000 (23:56 +0900)
committerDaniel Wagner <wagi@monom.org>
Mon, 10 Feb 2025 15:23:20 +0000 (16:23 +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 caa60721eae804f810b58cd127d511e3bfe22471..b97d2dded7c1892d8c37894910b70d6b96c5b4b0 100644 (file)
@@ -62,6 +62,7 @@ COMMAND_LIST(
        ENTRY("rotational-media-info-log", "Retrieve Rotational Media Information Log, show it", get_rotational_media_info_log)
        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("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 e9aa5688b045cbd3bc7cc8da75c1e1cb35c79002..dcaaddc6df2723301585cbad640962e3fa274e17 100644 (file)
@@ -321,6 +321,11 @@ static void binary_dispersed_ns_psub_log(struct nvme_dispersed_ns_participating_
        d_raw((unsigned char *)log, sizeof(*log));
 }
 
+static void binary_reachability_groups_log(struct nvme_reachability_groups_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,
@@ -390,6 +395,7 @@ static struct print_ops binary_print_ops = {
        .mgmt_addr_list_log             = binary_mgmt_addr_list_log,
        .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,
 
        /* libnvme tree print functions */
        .list_item                      = NULL,
index 57110c1539ad11a313b6c1b14650f73cc226b145..5320f5736bc96ea6d9be08346ac50c4d3ab4d3cb 100644 (file)
@@ -4677,6 +4677,30 @@ static void json_dispersed_ns_psub_log(struct nvme_dispersed_ns_participating_ns
        json_print(r);
 }
 
+static void json_reachability_groups_log(struct nvme_reachability_groups_log *log)
+{
+       struct json_object *r = json_create_object();
+       __u16 i;
+       __u32 j;
+       char json_str[STR_LEN];
+       struct json_object *rgd;
+
+       obj_add_uint64(r, "chngc", le64_to_cpu(log->chngc));
+       obj_add_uint(r, "nrgd", le16_to_cpu(log->nrgd));
+
+       for (i = 0; i < le16_to_cpu(log->nrgd); i++) {
+               snprintf(json_str, sizeof(json_str), "rgid: %u", le32_to_cpu(log->rgd[i].rgid));
+               rgd = json_create_object();
+               obj_add_uint(rgd, "nnid", le32_to_cpu(log->rgd[i].nnid));
+               obj_add_uint64(rgd, "chngc", le64_to_cpu(log->rgd[i].chngc));
+               for (j = 0; j < le32_to_cpu(log->rgd[i].nnid); j++)
+                       obj_add_uint(rgd, "nnid", le32_to_cpu(log->rgd[i].nsid[j]));
+               obj_add_obj(r, json_str, rgd);
+       }
+
+       json_print(r);
+}
+
 static struct print_ops json_print_ops = {
        /* libnvme types.h print functions */
        .ana_log                        = json_ana_log,
@@ -4747,6 +4771,7 @@ static struct print_ops json_print_ops = {
        .mgmt_addr_list_log             = json_mgmt_addr_list_log,
        .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,
 
        /* libnvme tree print functions */
        .list_item                      = json_list_item,
index c8e2ea653ec69c4babcd28381f6c71d45763804c..f9abf03f5161d114c94f7513085d69988693f7b9 100644 (file)
@@ -5638,6 +5638,23 @@ static void stdout_dispersed_ns_psub_log(struct nvme_dispersed_ns_participating_
                       &log->participating_nss[i * NVME_NQN_LENGTH]);
 }
 
+static void stdout_reachability_groups_log(struct nvme_reachability_groups_log *log)
+{
+       __u16 i;
+       __u32 j;
+
+       printf("chngc: %"PRIu64"\n", le64_to_cpu(log->chngc));
+       printf("nrgd: %u\n", le16_to_cpu(log->nrgd));
+
+       for (i = 0; i < le16_to_cpu(log->nrgd); i++) {
+               printf("rgid: %u\n", le32_to_cpu(log->rgd[i].rgid));
+               printf("nnid: %u\n", le32_to_cpu(log->rgd[i].nnid));
+               printf("chngc: %"PRIu64"\n", le64_to_cpu(log->rgd[i].chngc));
+               for (j = 0; j < le32_to_cpu(log->rgd[i].nnid); j++)
+                       printf("nsid%u: %u\n", j, le32_to_cpu(log->rgd[i].nsid[j]));
+       }
+}
+
 static struct print_ops stdout_print_ops = {
        /* libnvme types.h print functions */
        .ana_log                        = stdout_ana_log,
@@ -5708,6 +5725,7 @@ static struct print_ops stdout_print_ops = {
        .mgmt_addr_list_log             = stdout_mgmt_addr_list_log,
        .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,
 
        /* libnvme tree print functions */
        .list_item                      = stdout_list_item,
index 77f4b17ed59ec625df758b529b5435d6351c8525..f15a3b4dee15316b5499ecf2f0e21fc7f584f624 100644 (file)
@@ -1508,3 +1508,9 @@ void nvme_show_dispersed_ns_psub_log(struct nvme_dispersed_ns_participating_nss_
 {
        nvme_print(dispersed_ns_psub_log, flags, log);
 }
+
+void nvme_show_reachability_groups_log(struct nvme_reachability_groups_log *log,
+                                      nvme_print_flags_t flags)
+{
+       nvme_print(reachability_groups_log, flags, log);
+}
index e446c07ea6ab95c48aa5d5a02b58ad3d4a1df5b3..5a3d939c44004aad5668157cd869a406d42fa36b 100644 (file)
@@ -91,6 +91,7 @@ struct print_ops {
        void (*mgmt_addr_list_log)(struct nvme_mgmt_addr_list_log *ma_log);
        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);
 
        /* libnvme tree print functions */
        void (*list_item)(nvme_ns_t n);
@@ -338,4 +339,6 @@ void nvme_show_rotational_media_info_log(struct nvme_rotational_media_info_log *
                                         nvme_print_flags_t flags);
 void nvme_show_dispersed_ns_psub_log(struct nvme_dispersed_ns_participating_nss_log *log,
                                     nvme_print_flags_t flags);
+void nvme_show_reachability_groups_log(struct nvme_reachability_groups_log *log,
+                                      nvme_print_flags_t flags);
 #endif /* NVME_PRINT_H */
index 2cc5204f9327e787b3a31b19e76ce5626d6e5c68..3ef5bbe3f1d4b98a1d42ca5692a3375a91e4ee6a 100644 (file)
@@ -457,3 +457,9 @@ int nvme_cli_get_log_dispersed_ns_participating_nss(struct nvme_dev *dev, __u32
 {
        return do_admin_op(get_log_dispersed_ns_participating_nss, dev, nsid, len, log);
 }
+
+int nvme_cli_get_log_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, __u32 len,
+                                        struct nvme_reachability_groups_log *log)
+{
+       return do_admin_op(get_log_reachability_groups, dev, len, rgo, rae, log);
+}
index b675f4f0daff2e6700e5a64e960ec7ef34f22f74..9300e8b0b644dbfa624f580ff657dbf961b5a370 100644 (file)
@@ -157,4 +157,6 @@ int nvme_cli_get_log_rotational_media_info(struct nvme_dev *dev, __u16 endgid, _
 int nvme_cli_get_log_dispersed_ns_participating_nss(struct nvme_dev *dev, __u32 nsid, __u32 len,
        struct nvme_dispersed_ns_participating_nss_log *log);
 
+int nvme_cli_get_log_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, __u32 len,
+                                        struct nvme_reachability_groups_log *log);
 #endif /* _NVME_WRAP_H */
diff --git a/nvme.c b/nvme.c
index 39e68d265ac802afa81ad71554a1edf9e1ef608e..233b2dc563515dc98bb7ebae022637262d1942bd 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -10256,6 +10256,130 @@ static int get_dispersed_ns_participating_nss_log(int argc, char **argv, struct
        return err;
 }
 
+static int get_log_offset(struct nvme_dev *dev, struct nvme_get_log_args *args, __u64 *offset,
+                         __u32 len, void **log)
+{
+       args->lpo = *offset,
+       args->log = *log + *offset,
+       args->len = len;
+       *offset += args->len;
+       *log = nvme_realloc(*log, *offset);
+       if (!*log)
+               return -ENOMEM;
+       return nvme_cli_get_log_page(dev, NVME_LOG_PAGE_PDU_SIZE, args);
+}
+
+static int get_reachability_group_desc(struct nvme_dev *dev, struct nvme_get_log_args *args,
+                                      __u64 offset, struct nvme_reachability_groups_log **logp)
+{
+       int err;
+       struct nvme_reachability_groups_log *log = *logp;
+       __u16 i;
+       __u32 len;
+
+       for (i = 0; i < le16_to_cpu(log->nrgd); i++) {
+               len = sizeof(*log->rgd);
+               err = get_log_offset(dev, args, &offset, len, (void **)&log);
+               if (err)
+                       goto err_free;
+               len = le32_to_cpu(log->rgd[i].nnid) * sizeof(*log->rgd[i].nsid);
+               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_groups(struct nvme_dev *dev, bool rgo, bool rae,
+                                  struct nvme_reachability_groups_log **logp)
+{
+       int err;
+       struct nvme_reachability_groups_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_GROUPS,
+               .nsid = NVME_NSID_ALL,
+               .lsp = rgo,
+               .rae = rae,
+       };
+
+       log = nvme_alloc(log_len);
+       if (!log)
+               return -ENOMEM;
+
+       err = nvme_cli_get_log_reachability_groups(dev, rgo, rae, log_len, log);
+       if (err)
+               goto err_free;
+
+       err = get_reachability_group_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_groups_log(int argc, char **argv, struct command *cmd,
+                                      struct plugin *plugin)
+{
+       const char *desc = "Retrieve Reachability Groups Log, show it";
+       const char *rgo = "Return Groups Only";
+       nvme_print_flags_t flags;
+       int err;
+
+       _cleanup_free_ struct nvme_reachability_groups_log *log = NULL;
+
+       _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+
+       struct config {
+               bool rgo;
+               bool rae;
+       };
+
+       struct config cfg = {
+               .rgo = false,
+               .rae = false,
+       };
+
+       NVME_ARGS(opts,
+                 OPT_FLAG("groups-only", 'g', &cfg.rgo, rgo),
+                 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_groups(dev, cfg.rgo, cfg.rae, &log);
+       if (!err)
+               nvme_show_reachability_groups_log(log, flags);
+       else if (err > 0)
+               nvme_show_status(err);
+       else
+               nvme_show_perror("rotational media info log");
+
+       return err;
+}
+
 void register_extension(struct plugin *plugin)
 {
        plugin->parent = &nvme;