Since added the NVMe 2.1 log page.
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
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)
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,
.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,
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,
.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,
&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,
.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,
{
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);
+}
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);
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 */
{
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);
+}
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 */
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;