From 2247a5dc4376736e0936dfc2296a2cb78097e5f6 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sun, 26 Jan 2025 23:36:58 +0900 Subject: [PATCH] nvme: add rotational-media-info-log command Since added the NVMe 2.1 log page. Signed-off-by: Tokunori Ikegami --- nvme-builtin.h | 1 + nvme-print-binary.c | 6 ++++++ nvme-print-json.c | 16 +++++++++++++++ nvme-print-stdout.c | 12 +++++++++++ nvme-print.c | 6 ++++++ nvme-print.h | 3 +++ nvme-wrap.c | 9 +++++++++ nvme-wrap.h | 3 +++ nvme.c | 49 ++++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 104 insertions(+), 1 deletion(-) diff --git a/nvme-builtin.h b/nvme-builtin.h index 5b1af693..0134e602 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -59,6 +59,7 @@ COMMAND_LIST( ENTRY("media-unit-stat-log", "Retrieve the configuration and wear of media units, show it", get_media_unit_stat_log) ENTRY("supported-cap-config-log", "Retrieve the list of Supported Capacity Configuration Descriptors", get_supp_cap_config_log) ENTRY("mgmt-addr-list-log", "Retrieve Management Address List Log, show it", get_mgmt_addr_list_log) + ENTRY("rotational-media-info-log", "Retrieve Rotational Media Information Log, show it", get_rotational_media_info_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) diff --git a/nvme-print-binary.c b/nvme-print-binary.c index caefd951..5d29beab 100644 --- a/nvme-print-binary.c +++ b/nvme-print-binary.c @@ -312,6 +312,11 @@ static void binary_mgmt_addr_list_log(struct nvme_mgmt_addr_list_log *ma_list) d_raw((unsigned char *)ma_list, sizeof(*ma_list)); } +static void binary_rotational_media_info_log(struct nvme_rotational_media_info_log *info) +{ + d_raw((unsigned char *)info, sizeof(*info)); +} + static struct print_ops binary_print_ops = { /* libnvme types.h print functions */ .ana_log = binary_ana_log, @@ -379,6 +384,7 @@ static struct print_ops binary_print_ops = { .show_init = NULL, .show_finish = NULL, .mgmt_addr_list_log = binary_mgmt_addr_list_log, + .rotational_media_info_log = binary_rotational_media_info_log, /* libnvme tree print functions */ .list_item = NULL, diff --git a/nvme-print-json.c b/nvme-print-json.c index b2501aba..069ba336 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -4638,6 +4638,21 @@ out: json_print(r); } +static void json_rotational_media_info_log(struct nvme_rotational_media_info_log *info) +{ + struct json_object *r = json_create_object(); + + obj_add_uint(r, "endgid", le16_to_cpu(info->endgid)); + obj_add_uint(r, "numa", le16_to_cpu(info->numa)); + obj_add_uint(r, "nrs", le16_to_cpu(info->nrs)); + obj_add_uint(r, "spinc", le32_to_cpu(info->spinc)); + obj_add_uint(r, "fspinc", le32_to_cpu(info->fspinc)); + obj_add_uint(r, "ldc", le32_to_cpu(info->ldc)); + obj_add_uint(r, "fldc", le32_to_cpu(info->fldc)); + + json_print(r); +} + static struct print_ops json_print_ops = { /* libnvme types.h print functions */ .ana_log = json_ana_log, @@ -4706,6 +4721,7 @@ static struct print_ops json_print_ops = { .show_init = json_show_init, .show_finish = json_show_finish, .mgmt_addr_list_log = json_mgmt_addr_list_log, + .rotational_media_info_log = json_rotational_media_info_log, /* libnvme tree print functions */ .list_item = json_list_item, diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c index b6776b73..8d713eb5 100644 --- a/nvme-print-stdout.c +++ b/nvme-print-stdout.c @@ -5566,6 +5566,17 @@ out: printf("All management address descriptors reserved\n"); } +static void stdout_rotational_media_info_log(struct nvme_rotational_media_info_log *info) +{ + printf("endgid: %u\n", le16_to_cpu(info->endgid)); + printf("numa: %u\n", le16_to_cpu(info->numa)); + printf("nrs: %u\n", le16_to_cpu(info->nrs)); + printf("spinc: %u\n", le32_to_cpu(info->spinc)); + printf("fspinc: %u\n", le32_to_cpu(info->fspinc)); + printf("ldc: %u\n", le32_to_cpu(info->ldc)); + printf("fldc: %u\n", le32_to_cpu(info->fldc)); +} + static struct print_ops stdout_print_ops = { /* libnvme types.h print functions */ .ana_log = stdout_ana_log, @@ -5634,6 +5645,7 @@ static struct print_ops stdout_print_ops = { .show_init = NULL, .show_finish = NULL, .mgmt_addr_list_log = stdout_mgmt_addr_list_log, + .rotational_media_info_log = stdout_rotational_media_info_log, /* libnvme tree print functions */ .list_item = stdout_list_item, diff --git a/nvme-print.c b/nvme-print.c index e95d21e0..98aaa566 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -1497,3 +1497,9 @@ void nvme_show_mgmt_addr_list_log(struct nvme_mgmt_addr_list_log *ma_list, nvme_ { nvme_print(mgmt_addr_list_log, flags, ma_list); } + +void nvme_show_rotational_media_info_log(struct nvme_rotational_media_info_log *info, + nvme_print_flags_t flags) +{ + nvme_print(rotational_media_info_log, flags, info); +} diff --git a/nvme-print.h b/nvme-print.h index 6fedd584..4aeba5fc 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -89,6 +89,7 @@ struct print_ops { void (*show_init)(void); void (*show_finish)(void); 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); /* libnvme tree print functions */ void (*list_item)(nvme_ns_t n); @@ -332,4 +333,6 @@ void json_print(struct json_object *r); struct json_object *obj_create_array_obj(struct json_object *o, const char *k); void nvme_show_mgmt_addr_list_log(struct nvme_mgmt_addr_list_log *ma_list, nvme_print_flags_t flags); +void nvme_show_rotational_media_info_log(struct nvme_rotational_media_info_log *info, + nvme_print_flags_t flags); #endif /* NVME_PRINT_H */ diff --git a/nvme-wrap.c b/nvme-wrap.c index 9b4aecd4..bcec2d19 100644 --- a/nvme-wrap.c +++ b/nvme-wrap.c @@ -436,3 +436,12 @@ int nvme_cli_get_log_mgmt_addr_list(struct nvme_dev *dev, __u32 len, { return do_admin_op(get_log_mgmt_addr_list, dev, len, ma_list); } + +int nvme_cli_get_log_rotational_media_info(struct nvme_dev *dev, __u16 endgid, __u32 len, + struct nvme_rotational_media_info_log *info) +{ + if (dev->type == NVME_DEV_DIRECT) + return nvme_get_log_rotational_media_info(dev->direct.fd, endgid, len, info); + + return -ENODEV; +} diff --git a/nvme-wrap.h b/nvme-wrap.h index c9d861b6..19a5e359 100644 --- a/nvme-wrap.h +++ b/nvme-wrap.h @@ -149,4 +149,7 @@ int nvme_cli_security_receive(struct nvme_dev *dev, int nvme_cli_get_log_mgmt_addr_list(struct nvme_dev *dev, __u32 len, struct nvme_mgmt_addr_list_log *ma_list); +int nvme_cli_get_log_rotational_media_info(struct nvme_dev *dev, __u16 endgid, __u32 len, + struct nvme_rotational_media_info_log *info); + #endif /* _NVME_WRAP_H */ diff --git a/nvme.c b/nvme.c index 2ed4ee92..0591fc72 100644 --- a/nvme.c +++ b/nvme.c @@ -204,6 +204,7 @@ static const char *doper = "directive operation"; static const char *dry = "show command instead of sending"; static const char *dspec_w_dtype = "directive specification associated with directive type"; static const char *dtype = "directive type"; +static const char *endgid = "Endurance Group Identifier (ENDGID)"; static const char *force_unit_access = "force device to commit data before command completes"; static const char *human_readable_directive = "show directive in readable format"; static const char *human_readable_identify = "show identify in readable format"; @@ -3096,7 +3097,6 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * const char *nmic = "multipath and sharing capabilities (NMIC)"; const char *anagrpid = "ANA Group Identifier (ANAGRPID)"; const char *nvmsetid = "NVM Set Identifier (NVMSETID)"; - const char *endgid = "Endurance Group Identifier (ENDGID)"; const char *csi = "command set identifier (CSI)"; const char *lbstm = "logical block storage tag mask (LBSTM)"; const char *nphndls = "Number of Placement Handles (NPHNDLS)"; @@ -10091,6 +10091,53 @@ static int get_mgmt_addr_list_log(int argc, char **argv, struct command *cmd, st return err; } +static int get_rotational_media_info_log(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + const char *desc = "Retrieve Rotational Media Information Log, show it"; + nvme_print_flags_t flags; + int err = -1; + + _cleanup_free_ struct nvme_rotational_media_info_log *info = NULL; + + _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + + struct config { + __u16 endgid; + }; + + struct config cfg = { + .endgid = 0, + }; + + NVME_ARGS(opts, + OPT_UINT("endg-id", 'e', &cfg.endgid, endgid)); + + 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; + } + + info = nvme_alloc(sizeof(*info)); + if (!info) + return -ENOMEM; + + err = nvme_cli_get_log_rotational_media_info(dev, cfg.endgid, sizeof(*info), info); + if (!err) + nvme_show_rotational_media_info_log(info, 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; -- 2.50.1