Since added the NVMe 2.1 log page.
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
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("host-discovery-log", "Retrieve Host Discovery Log, show it", get_host_discovery_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, len);
}
+static void binary_host_discovery_log(struct nvme_host_discover_log *log)
+{
+ d_raw((unsigned char *)log, le32_to_cpu(log->thdlpl));
+}
+
static struct print_ops binary_print_ops = {
/* libnvme types.h print functions */
.ana_log = binary_ana_log,
.dispersed_ns_psub_log = binary_dispersed_ns_psub_log,
.reachability_groups_log = binary_reachability_groups_log,
.reachability_associations_log = binary_reachability_associations_log,
+ .host_discovery_log = binary_host_discovery_log,
/* libnvme tree print functions */
.list_item = NULL,
json_print(r);
}
+static void json_host_discovery_log(struct nvme_host_discover_log *log)
+{
+ struct json_object *r = json_create_object();
+ __u32 i;
+ __u16 j;
+ struct nvme_host_ext_discover_log *hedlpe;
+ struct nvmf_ext_attr *exat;
+ __u32 thdlpl = le32_to_cpu(log->thdlpl);
+ __u32 tel;
+ __u16 numexat;
+ char json_str[STR_LEN];
+ struct json_object *hedlpe_o;
+ struct json_object *tsas_o;
+ struct json_object *exat_o;
+ int n = 0;
+
+ obj_add_uint64(r, "genctr", le64_to_cpu(log->genctr));
+ obj_add_uint64(r, "numrec", le64_to_cpu(log->numrec));
+ obj_add_uint(r, "recfmt", le16_to_cpu(log->recfmt));
+ obj_add_uint_02x(r, "hdlpf", log->hdlpf);
+ obj_add_uint(r, "thdlpl", thdlpl);
+
+ for (i = sizeof(*log); i < le32_to_cpu(log->thdlpl); i += tel) {
+ hedlpe_o = json_create_object();
+ hedlpe = (void *)log + i;
+ tel = le32_to_cpu(hedlpe->tel);
+ numexat = le16_to_cpu(hedlpe->numexat);
+ obj_add_str(hedlpe_o, "trtype", nvmf_trtype_str(hedlpe->trtype));
+ obj_add_str(hedlpe_o, "adrfam",
+ strlen(hedlpe->traddr) ? nvmf_adrfam_str(hedlpe->adrfam) : "");
+ obj_add_str(hedlpe_o, "eflags", nvmf_eflags_str(le16_to_cpu(hedlpe->eflags)));
+ obj_add_str(hedlpe_o, "hostnqn", hedlpe->hostnqn);
+ obj_add_str(hedlpe_o, "traddr", hedlpe->traddr);
+ tsas_o = json_create_object();
+ switch (hedlpe->trtype) {
+ case NVMF_TRTYPE_RDMA:
+ obj_add_str(tsas_o, "prtype", nvmf_prtype_str(hedlpe->tsas.rdma.prtype));
+ obj_add_str(tsas_o, "qptype", nvmf_qptype_str(hedlpe->tsas.rdma.qptype));
+ obj_add_str(tsas_o, "cms", nvmf_cms_str(hedlpe->tsas.rdma.cms));
+ obj_add_uint_0nx(tsas_o, "pkey", le16_to_cpu(hedlpe->tsas.rdma.pkey), 4);
+ break;
+ case NVMF_TRTYPE_TCP:
+ obj_add_str(tsas_o, "sectype", nvmf_sectype_str(hedlpe->tsas.tcp.sectype));
+ break;
+ default:
+ obj_d(tsas_o, "common", (unsigned char *)hedlpe->tsas.common,
+ sizeof(hedlpe->tsas.common), 16, 1);
+ break;
+ }
+ obj_add_obj(hedlpe_o, "tsas", tsas_o);
+ obj_add_uint(hedlpe_o, "tel", tel);
+ obj_add_uint(hedlpe_o, "numexat", numexat);
+
+ exat = hedlpe->exat;
+ for (j = 0; j < numexat; j++) {
+ exat_o = json_create_object();
+ snprintf(json_str, sizeof(json_str), "exat: %d", j);
+ obj_add_uint(exat_o, "exattype", le16_to_cpu(exat->exattype));
+ obj_add_uint(exat_o, "exatlen", le16_to_cpu(exat->exatlen));
+ printf(":\n");
+ obj_d(exat_o, "exatval", (unsigned char *)exat->exatval,
+ le16_to_cpu(exat->exatlen), 16, 1);
+ obj_add_obj(hedlpe_o, json_str, exat_o);
+ exat = nvmf_exat_ptr_next(exat);
+ }
+ snprintf(json_str, sizeof(json_str), "hedlpe: %d", n++);
+ obj_add_obj(r, json_str, hedlpe_o);
+ }
+}
+
static struct print_ops json_print_ops = {
/* libnvme types.h print functions */
.ana_log = json_ana_log,
.dispersed_ns_psub_log = json_dispersed_ns_psub_log,
.reachability_groups_log = json_reachability_groups_log,
.reachability_associations_log = json_reachability_associations_log,
+ .host_discovery_log = json_host_discovery_log,
/* libnvme tree print functions */
.list_item = json_list_item,
}
}
+static void stdout_host_discovery_log(struct nvme_host_discover_log *log)
+{
+ __u32 i;
+ __u16 j;
+ struct nvme_host_ext_discover_log *hedlpe;
+ struct nvmf_ext_attr *exat;
+ __u32 thdlpl = le32_to_cpu(log->thdlpl);
+ __u32 tel;
+ __u16 numexat;
+ int n = 0;
+
+ printf("genctr: %"PRIu64"\n", le64_to_cpu(log->genctr));
+ printf("numrec: %"PRIu64"\n", le64_to_cpu(log->numrec));
+ printf("recfmt: %u\n", le16_to_cpu(log->recfmt));
+ printf("hdlpf: %02x\n", log->hdlpf);
+ printf("thdlpl: %u\n", thdlpl);
+
+ for (i = sizeof(*log); i < le32_to_cpu(log->thdlpl); i += tel) {
+ printf("hedlpe: %d\n", n++);
+ hedlpe = (void *)log + i;
+ tel = le32_to_cpu(hedlpe->tel);
+ numexat = le16_to_cpu(hedlpe->numexat);
+ printf("trtype: %s\n", nvmf_trtype_str(hedlpe->trtype));
+ printf("adrfam: %s\n",
+ strlen(hedlpe->traddr) ? nvmf_adrfam_str(hedlpe->adrfam) : "");
+ printf("eflags: %s\n", nvmf_eflags_str(le16_to_cpu(hedlpe->eflags)));
+ printf("hostnqn: %s\n", hedlpe->hostnqn);
+ printf("traddr: %s\n", hedlpe->traddr);
+ printf("tsas: ");
+ switch (hedlpe->trtype) {
+ case NVMF_TRTYPE_RDMA:
+ printf("prtype: %s, qptype: %s, cms: %s, pkey: 0x%04x\n",
+ nvmf_prtype_str(hedlpe->tsas.rdma.prtype),
+ nvmf_qptype_str(hedlpe->tsas.rdma.qptype),
+ nvmf_cms_str(hedlpe->tsas.rdma.cms),
+ le16_to_cpu(hedlpe->tsas.rdma.pkey));
+ break;
+ case NVMF_TRTYPE_TCP:
+ printf("sectype: %s\n", nvmf_sectype_str(hedlpe->tsas.tcp.sectype));
+ break;
+ default:
+ printf("common:\n");
+ d((unsigned char *)hedlpe->tsas.common, sizeof(hedlpe->tsas.common), 16, 1);
+ break;
+ }
+ printf("tel: %u\n", tel);
+ printf("numexat: %u\n", numexat);
+
+ exat = hedlpe->exat;
+ for (j = 0; j < numexat; j++) {
+ printf("exat: %d\n", j);
+ printf("exattype: %u\n", le16_to_cpu(exat->exattype));
+ printf("exatlen: %u\n", le16_to_cpu(exat->exatlen));
+ printf("exatval:\n");
+ d((unsigned char *)exat->exatval, le16_to_cpu(exat->exatlen), 16, 1);
+ exat = nvmf_exat_ptr_next(exat);
+ }
+ }
+}
+
static struct print_ops stdout_print_ops = {
/* libnvme types.h print functions */
.ana_log = stdout_ana_log,
.dispersed_ns_psub_log = stdout_dispersed_ns_psub_log,
.reachability_groups_log = stdout_reachability_groups_log,
.reachability_associations_log = stdout_reachability_associations_log,
+ .host_discovery_log = stdout_host_discovery_log,
/* libnvme tree print functions */
.list_item = stdout_list_item,
{
nvme_print(reachability_associations_log, flags, log, len);
}
+
+void nvme_show_host_discovery_log(struct nvme_host_discover_log *log, nvme_print_flags_t flags)
+{
+ nvme_print(host_discovery_log, flags, log);
+}
void (*reachability_groups_log)(struct nvme_reachability_groups_log *log, __u64 len);
void (*reachability_associations_log)(struct nvme_reachability_associations_log *log,
__u64 len);
+ void (*host_discovery_log)(struct nvme_host_discover_log *log);
/* libnvme tree print functions */
void (*list_item)(nvme_ns_t n);
__u64 len, nvme_print_flags_t flags);
void nvme_show_reachability_associations_log(struct nvme_reachability_associations_log *log,
__u64 len, nvme_print_flags_t flags);
+void nvme_show_host_discovery_log(struct nvme_host_discover_log *log, nvme_print_flags_t flags);
#endif /* NVME_PRINT_H */
{
return do_admin_op(get_log_reachability_associations, dev, rao, rae, len, log);
}
+
+int nvme_cli_get_log_host_discovery(struct nvme_dev *dev, bool allhoste, bool rae, __u32 len,
+ struct nvme_host_discover_log *log)
+{
+ return do_admin_op(get_log_host_discover, dev, allhoste, rae, len, log);
+}
int nvme_cli_get_log_reachability_associations(struct nvme_dev *dev, bool rgo, bool rae, __u32 len,
struct nvme_reachability_associations_log *log);
+
+int nvme_cli_get_log_host_discovery(struct nvme_dev *dev, bool allhoste, bool rae, __u32 len,
+ struct nvme_host_discover_log *log);
#endif /* _NVME_WRAP_H */
return err;
}
+static int get_host_discovery(struct nvme_dev *dev, bool allhoste, bool rae,
+ struct nvme_host_discover_log **logp)
+{
+ int err;
+ struct nvme_host_discover_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_HOST_DISCOVER,
+ .nsid = NVME_NSID_ALL,
+ .lsp = allhoste,
+ .rae = rae,
+ };
+
+ log = nvme_alloc(log_len);
+ if (!log)
+ return -ENOMEM;
+
+ err = nvme_cli_get_log_host_discovery(dev, allhoste, rae, log_len, log);
+ if (err)
+ goto err_free;
+
+ log_len = le32_to_cpu(log->thdlpl);
+ err = get_log_offset(dev, &args, &log_len, le32_to_cpu(log->thdlpl) - log_len,
+ (void **)&log);
+ if (err)
+ goto err_free;
+
+ *logp = log;
+ return 0;
+
+err_free:
+ free(log);
+ return err;
+}
+
+static int get_host_discovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Retrieve Host Discovery Log, show it";
+ const char *allhoste = "All Host Entries";
+ nvme_print_flags_t flags;
+ int err;
+
+ _cleanup_free_ struct nvme_host_discover_log *log = NULL;
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+
+ struct config {
+ bool allhoste;
+ bool rae;
+ };
+
+ struct config cfg = {
+ .allhoste = false,
+ .rae = false,
+ };
+
+ NVME_ARGS(opts,
+ OPT_FLAG("all-host-entries", 'a', &cfg.allhoste, allhoste),
+ 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_host_discovery(dev, cfg.allhoste, cfg.rae, &log);
+ if (!err)
+ nvme_show_host_discovery_log(log, flags);
+ else if (err > 0)
+ nvme_show_status(err);
+ else
+ nvme_show_perror("host discovery log");
+
+ return err;
+}
+
void register_extension(struct plugin *plugin)
{
plugin->parent = &nvme;