From fe45bae8ada04fc2d88604aef2442fbd63640efb Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Mon, 10 Feb 2025 13:28:42 +0100 Subject: [PATCH 1/5] nvme-wrap: handle get log rotational media info correctly Return error for the missing get log rotational media function for non MI devices. Signed-off-by: Tokunori Ikegami --- nvme-wrap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nvme-wrap.c b/nvme-wrap.c index 59f6be3840..bcec2d1904 100644 --- a/nvme-wrap.c +++ b/nvme-wrap.c @@ -440,5 +440,8 @@ int nvme_cli_get_log_mgmt_addr_list(struct nvme_dev *dev, __u32 len, int nvme_cli_get_log_rotational_media_info(struct nvme_dev *dev, __u16 endgid, __u32 len, struct nvme_rotational_media_info_log *info) { - return do_admin_op(get_log_rotational_media_info, dev, endgid, len, info); + if (dev->type == NVME_DEV_DIRECT) + return nvme_get_log_rotational_media_info(dev->direct.fd, endgid, len, info); + + return -ENODEV; } From 25079c2e227f96f06b5880be649ea546d3bb91d2 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Mon, 27 Jan 2025 23:22:35 +0900 Subject: [PATCH 2/5] nvme: add NVMe 2.1 changed-alloc-ns-list-log command The command functions combined with the changed-ns-list-log command. The output almost same but different as lists attached or allocated NSs. Signed-off-by: Tokunori Ikegami --- nvme-builtin.h | 3 ++- nvme-print-binary.c | 3 +-- nvme-print-json.c | 8 +++++--- nvme-print-stdout.c | 3 +-- nvme-print.c | 7 +++---- nvme-print.h | 6 +++--- nvme-wrap.c | 6 ++++++ nvme-wrap.h | 2 ++ nvme.c | 37 +++++++++++++++++++++++++++++-------- 9 files changed, 52 insertions(+), 23 deletions(-) diff --git a/nvme-builtin.h b/nvme-builtin.h index 0134e602c6..486b1e5a80 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -36,7 +36,7 @@ COMMAND_LIST( ENTRY("get-log", "Generic NVMe get log, returns log in raw format", get_log) ENTRY("telemetry-log", "Retrieve FW Telemetry log write to file", get_telemetry_log) ENTRY("fw-log", "Retrieve FW Log, show it", get_fw_log) - ENTRY("changed-ns-list-log", "Retrieve Changed Namespace List, show it", get_changed_ns_list_log) + ENTRY("changed-ns-list-log", "Retrieve Changed Attached Namespace List, show it", get_changed_attach_ns_list_log) ENTRY("smart-log", "Retrieve SMART Log, show it", get_smart_log) ENTRY("ana-log", "Retrieve ANA Log, show it", get_ana_log) ENTRY("error-log", "Retrieve Error Log, show it", get_error_log) @@ -60,6 +60,7 @@ COMMAND_LIST( 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("changed-alloc-ns-list-log", "Retrieve Changed Allocated Namespace List, show it", get_changed_alloc_ns_list_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 5d29beab6b..2c5135a7b2 100644 --- a/nvme-print-binary.c +++ b/nvme-print-binary.c @@ -233,8 +233,7 @@ static void binary_fw_log(struct nvme_firmware_slot *fw_log, d_raw((unsigned char *)fw_log, sizeof(*fw_log)); } -static void binary_changed_ns_list_log(struct nvme_ns_list *log, - const char *devname) +static void binary_changed_ns_list_log(struct nvme_ns_list *log, const char *devname, bool alloc) { d_raw((unsigned char *)log, sizeof(*log)); } diff --git a/nvme-print-json.c b/nvme-print-json.c index 03833f7f43..ee4338aae2 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -583,8 +583,7 @@ void json_fw_log(struct nvme_firmware_slot *fw_log, const char *devname) json_print(r); } -void json_changed_ns_list_log(struct nvme_ns_list *log, - const char *devname) +void json_changed_ns_list_log(struct nvme_ns_list *log, const char *devname, bool alloc) { struct json_object *r = json_create_object(); struct json_object *nsi = json_create_object(); @@ -593,10 +592,13 @@ void json_changed_ns_list_log(struct nvme_ns_list *log, __u32 nsid; int i; + _cleanup_free_ char *k = NULL; + if (log->ns[0] == cpu_to_le32(0xffffffff)) return; - obj_add_str(r, "Changed Namespace List Log", devname); + if (asprintf(&k, "Changed %s Namespace List Log", alloc ? "Allocated" : "Attached") > 0) + obj_add_str(r, k, devname); for (i = 0; i < NVME_ID_NS_LIST_MAX; i++) { nsid = le32_to_cpu(log->ns[i]); diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c index 1b47921f69..cc4d1fcdae 100644 --- a/nvme-print-stdout.c +++ b/nvme-print-stdout.c @@ -4034,8 +4034,7 @@ static void stdout_fw_log(struct nvme_firmware_slot *fw_log, } } -static void stdout_changed_ns_list_log(struct nvme_ns_list *log, - const char *devname) +static void stdout_changed_ns_list_log(struct nvme_ns_list *log, const char *devname, bool alloc) { __u32 nsid; int i; diff --git a/nvme-print.c b/nvme-print.c index 98aaa56611..bb41543b40 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -740,11 +740,10 @@ void nvme_show_fw_log(struct nvme_firmware_slot *fw_log, nvme_print(fw_log, flags, fw_log, devname); } -void nvme_show_changed_ns_list_log(struct nvme_ns_list *log, - const char *devname, - nvme_print_flags_t flags) +void nvme_show_changed_ns_list_log(struct nvme_ns_list *log, const char *devname, + nvme_print_flags_t flags, bool alloc) { - nvme_print(ns_list_log, flags, log, devname); + nvme_print(ns_list_log, flags, log, devname, alloc); } void nvme_print_effects_log_pages(struct list_head *list, diff --git a/nvme-print.h b/nvme-print.h index 4aeba5fcd3..55616279a3 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -58,7 +58,7 @@ struct print_ops { void (*media_unit_stat_log)(struct nvme_media_unit_stat_log *mus); void (*mi_cmd_support_effects_log)(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log, const char *devname); void (*ns_list)(struct nvme_ns_list *ns_list); - void (*ns_list_log)(struct nvme_ns_list *log, const char *devname); + void (*ns_list_log)(struct nvme_ns_list *log, const char *devname, bool alloc); void (*nvm_id_ns)(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid, struct nvme_id_ns *ns, unsigned int lba_index, bool cap_only); void (*persistent_event_log)(void *pevent_log_info, __u8 action, __u32 size, const char *devname); void (*predictable_latency_event_agg_log)(struct nvme_aggregate_predictable_lat_event *pea_log, __u64 log_entries, __u32 size, const char *devname); @@ -174,8 +174,8 @@ void nvme_show_fw_log(struct nvme_firmware_slot *fw_log, const char *devname, nvme_print_flags_t flags); void nvme_print_effects_log_pages(struct list_head *list, nvme_print_flags_t flags); -void nvme_show_changed_ns_list_log(struct nvme_ns_list *log, - const char *devname, nvme_print_flags_t flags); +void nvme_show_changed_ns_list_log(struct nvme_ns_list *log, const char *devname, + nvme_print_flags_t flags, bool alloc); void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log, __u16 group_id, const char *devname, nvme_print_flags_t flags); void nvme_show_sanitize_log(struct nvme_sanitize_log_page *sanitize, diff --git a/nvme-wrap.c b/nvme-wrap.c index bcec2d1904..0b1039a682 100644 --- a/nvme-wrap.c +++ b/nvme-wrap.c @@ -214,6 +214,12 @@ int nvme_cli_get_log_changed_ns_list(struct nvme_dev *dev, bool rae, return do_admin_op(get_log_changed_ns_list, dev, rae, ns_log); } +int nvme_cli_get_log_changed_alloc_ns_list(struct nvme_dev *dev, bool rae, __u32 len, + struct nvme_ns_list *ns_log) +{ + return do_admin_op(get_log_changed_alloc_ns_list, dev, rae, len, ns_log); +} + int nvme_cli_get_log_cmd_effects(struct nvme_dev *dev, enum nvme_csi csi, struct nvme_cmd_effects_log *effects_log) { diff --git a/nvme-wrap.h b/nvme-wrap.h index 19a5e3598e..bde7d720ab 100644 --- a/nvme-wrap.h +++ b/nvme-wrap.h @@ -72,6 +72,8 @@ int nvme_cli_get_log_fw_slot(struct nvme_dev *dev, bool rae, struct nvme_firmware_slot *fw_log); int nvme_cli_get_log_changed_ns_list(struct nvme_dev *dev, bool rae, struct nvme_ns_list *ns_log); +int nvme_cli_get_log_changed_alloc_ns_list(struct nvme_dev *dev, bool rae, __u32 len, + struct nvme_ns_list *ns_log); int nvme_cli_get_log_cmd_effects(struct nvme_dev *dev, enum nvme_csi csi, struct nvme_cmd_effects_log *effects_log); int nvme_cli_get_log_device_self_test(struct nvme_dev *dev, diff --git a/nvme.c b/nvme.c index 44a44317ce..06deeaeb56 100644 --- a/nvme.c +++ b/nvme.c @@ -1354,10 +1354,9 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin return err; } -static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_changed_ns_list_log(int argc, char **argv, bool alloc) { - const char *desc = "Retrieve Changed Namespaces log for the given device " - "in either decoded format (default) or binary."; + _cleanup_free_ char *desc = NULL; _cleanup_free_ struct nvme_ns_list *changed_ns_list_log = NULL; _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; @@ -1375,6 +1374,11 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s NVME_ARGS(opts, OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_output)); + if (asprintf(&desc, "Retrieve Changed %s Namespaces log for the given device %s", + alloc ? "Allocated" : "Attached", + "in either decoded format (default) or binary.") < 0) + desc = NULL; + err = parse_and_open(&dev, argc, argv, desc, opts); if (err) return err; @@ -1392,19 +1396,36 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s if (!changed_ns_list_log) return -ENOMEM; - err = nvme_cli_get_log_changed_ns_list(dev, true, - changed_ns_list_log); + if (alloc) + err = nvme_cli_get_log_changed_alloc_ns_list(dev, true, + sizeof(*changed_ns_list_log), + changed_ns_list_log); + else + err = nvme_cli_get_log_changed_ns_list(dev, true, + changed_ns_list_log); if (!err) - nvme_show_changed_ns_list_log(changed_ns_list_log, - dev->name, flags); + nvme_show_changed_ns_list_log(changed_ns_list_log, dev->name, flags, alloc); else if (err > 0) nvme_show_status(err); else - nvme_show_error("changed ns list log: %s", nvme_strerror(errno)); + nvme_show_error("changed %s ns list log: %s", alloc ? "allocated" : "attached", + nvme_strerror(errno)); return err; } +static int get_changed_attach_ns_list_log(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + return get_changed_ns_list_log(argc, argv, false); +} + +static int get_changed_alloc_ns_list_log(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + return get_changed_ns_list_log(argc, argv, true); +} + static int get_pred_lat_per_nvmset_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) { From b8825a2b9ac2b03457532a33f1388f3069246805 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sun, 26 Jan 2025 09:59:16 +0900 Subject: [PATCH 3/5] doc: add changed-alloc-ns-list-log command Added the nvme-changed-alloc-ns-list-log.txt file. Signed-off-by: Tokunori Ikegami --- .../nvme-changed-alloc-ns-list-log.txt | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/nvme-changed-alloc-ns-list-log.txt diff --git a/Documentation/nvme-changed-alloc-ns-list-log.txt b/Documentation/nvme-changed-alloc-ns-list-log.txt new file mode 100644 index 0000000000..3a7f2e8a7f --- /dev/null +++ b/Documentation/nvme-changed-alloc-ns-list-log.txt @@ -0,0 +1,67 @@ +nvme-changed-alloc-ns-list-log(1) +================================= + +NAME +---- +nvme-changed-alloc-ns-list-log - Send NVMe Changed Allocated Namespace List +log page request, returns result and log. + +SYNOPSIS +-------- +[verse] +'nvme changed-alloc-ns-list-log' [--raw-binary | -b] + [--output-format= | -o ] [--verbose | -v] + [--timeout=] + +DESCRIPTION +----------- +Retrieves the NVMe Changed Allocated Namespace List log page from an NVMe +device and provides the returned structure. + +The parameter is mandatory and must be a NVMe character device +(ex: /dev/nvme0). + +On success, the returned Changed Allocated Namespace List log structure may +be returned in one of several ways depending on the option flags; the +structure may parsed by the program and printed in a readable format or +the raw buffer may be printed to stdout for another program to parse. + +OPTIONS +------- +-b:: +--raw-binary:: + Print the raw Changed Namespace List log buffer to stdout. + +-o :: +--output-format=:: + Set the reporting format to 'normal', 'json' or 'binary'. Only one + output format can be used at a time. + +-v:: +--verbose:: + Increase the information detail in the output. + +-t :: +--timeout=:: + Override default timeout value. In milliseconds. + +EXAMPLES +-------- +* Print the Changed Allocated Namespace List Log page in a human readable format: ++ +------------ +# nvme changed-alloc-ns-list-log /dev/nvme0 +------------ ++ + +* Print the raw Changed Allocated Namespace List log to a file: ++ +------------ +# nvme changed-alloc-ns-list-log /dev/nvme0 --raw-binary > log.raw +------------ ++ +It is probably a bad idea to not redirect stdout when using this mode. + +NVME +---- +Part of the nvme-user suite From fbb463ca88967ff425acd1bd0fe91c002e7c9d82 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sun, 26 Jan 2025 10:29:09 +0900 Subject: [PATCH 4/5] completions: fix mgmt-addr-list-log command Since missed to add the command into the command list. Signed-off-by: Tokunori Ikegami --- completions/_nvme | 1 + 1 file changed, 1 insertion(+) diff --git a/completions/_nvme b/completions/_nvme index c8c3c5e63d..0e44629e29 100644 --- a/completions/_nvme +++ b/completions/_nvme @@ -110,6 +110,7 @@ _nvme () { 'set-reg:write and show the defined NVMe controller register' 'io-mgmt-recv:send an I/O management receive command' 'io-mgmt-send:send an I/O management send command' + 'mgmt-addr-list-log:retrieve management address list log' 'version:show the program version' 'ocp:OCP cloud SSD extensions' 'solidigm:Solidigm plug-in extensions' From 1eda789eb00b248cae2384d189f14e554b384fcb Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sat, 8 Feb 2025 00:10:15 +0900 Subject: [PATCH 5/5] completions: add changed-alloc-ns-list-log command Both bash and zsh completions updated for the command. Signed-off-by: Tokunori Ikegami --- completions/_nvme | 16 ++++++++++++++-- completions/bash-nvme-completion.sh | 6 +++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/completions/_nvme b/completions/_nvme index 0e44629e29..4e682e9e0c 100644 --- a/completions/_nvme +++ b/completions/_nvme @@ -111,6 +111,7 @@ _nvme () { 'io-mgmt-recv:send an I/O management receive command' 'io-mgmt-send:send an I/O management send command' 'mgmt-addr-list-log:retrieve management address list log' + 'changed-ns-list-log:retrieve changed allocated namespaces log' 'version:show the program version' 'ocp:OCP cloud SSD extensions' 'solidigm:Solidigm plug-in extensions' @@ -2639,11 +2640,22 @@ _nvme () { -v':alias for --verbose' --output-format=':Output format: normal|json|binary' -o ':alias for --output-format' + _describe -t commands "nvme rotational-media-info-log" _rmi_log + (changed-alloc-ns-list-log) + local _changed_alloc_ns_list_log + _changed_alloc_ns_list_log=( + /dev/nvme':supply a device to use (required)' + --output-format=':Output format: normal|json|binary' + -o':alias for --output-format' + --raw-binary':dump infos in binary format' + -b':alias of --raw-binary' + --verbose':Increase the information detail in the output.' + -v':alias for --verbose' --timeout=':value for timeout' -t ':alias for --timeout' ) _arguments '*:: :->subcmds' - _describe -t commands "nvme rotational-media-info-log" _rmi_log + _describe -t commands "nvme changed-alloc-ns-list-log options" _changed_alloc_ns_list_log ;; (version) local _version @@ -2757,7 +2769,7 @@ _nvme () { subsystem-reset ns-rescan get-lba-status dsm discover connect-all connect dim disconnect disconnect-all gen-hostnqn show-hostnqn tls-key dir-receive dir-send virt-mgmt rpmb version ocp solidigm dapustor mgmt-addr-list-log - rotational-media-info-log + rotational-media-info-log changed-alloc-ns-list-log ) _arguments '*:: :->subcmds' _describe -t commands "help: infos on a specific nvme command, or provide no option to see a synopsis of all nvme commands" _h diff --git a/completions/bash-nvme-completion.sh b/completions/bash-nvme-completion.sh index de2efde45d..12b09ef53f 100644 --- a/completions/bash-nvme-completion.sh +++ b/completions/bash-nvme-completion.sh @@ -486,6 +486,10 @@ nvme_list_opts () { opts+=" --endg-id= -e --verbose -v --output-format= -o \ --timeout= -t" ;; + "changed-alloc-cns-list-log") + opts+=" --output-format= -o --raw-binary -b --verbose -v \ + --timeout= -t" + ;; "version") opts+=$NO_OPTS ;; @@ -1677,7 +1681,7 @@ _nvme_subcmds () { supported-log-pages lockdown media-unit-stat-log \ supported-cap-config-log dim show-topology list-endgrp \ nvme-mi-recv nvme-mi-send get-reg set-reg mgmt-addr-list-log \ - rotational-media-info-log" + rotational-media-info-log changed-alloc-ns-list-log" # Add plugins: for plugin in "${!_plugin_subcmds[@]}"; do