From: Gollu Appalanaidu Date: Mon, 19 Jul 2021 13:57:47 +0000 (+0530) Subject: Add Identify CNS 0x18 Domain List Support X-Git-Tag: v1.15~10 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=ee201cea74b32f78bdf7155b7e388996126a29d0;p=users%2Fsagi%2Fnvme-cli.git Add Identify CNS 0x18 Domain List Support Signed-off-by: Gollu Appalanaidu --- diff --git a/Documentation/nvme-id-domain.1 b/Documentation/nvme-id-domain.1 new file mode 100644 index 00000000..ddd9c3f2 --- /dev/null +++ b/Documentation/nvme-id-domain.1 @@ -0,0 +1,62 @@ +'\" t +.\" Title: nvme-id-domain +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Date: 07/20/2021 +.\" Manual: NVMe Manual +.\" Source: NVMe +.\" Language: English +.\" +.TH "NVME\-ID\-DOMAIN" "1" "07/20/2021" "NVMe" "NVMe Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nvme-id-domain \- Send NVMe Identify Domain List, return result and structure +.SH "SYNOPSIS" +.sp +.nf +\fInvme id\-domain\fR [\-\-dom\-id= | \-d ] + [\-o | \-\-output\-format=] +.fi +.SH "DESCRIPTION" +.sp +For the NVMe device given, send an identify command and return the domian list data structure\&. +.sp +The parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1)\&. +.SH "OPTIONS" +.PP +\-d , \-\-dom\-id= +.RS 4 +Retrieve the identify domain list data structure for the given domain id\&. If this value is not given, domain id will be 0xffff\&. +.RE +.PP +\-o , \-\-output\-format= +.RS 4 +Set the reporting format to +\fInormal\fR, +\fIjson\fR, or +\fIbinary\fR\&. Only one output format can be used at a time\&. +.RE +.SH "EXAMPLES" +.sp +No examples yet\&. +.SH "NVME" +.sp +Part of the nvme\-user suite diff --git a/Documentation/nvme-id-domain.html b/Documentation/nvme-id-domain.html new file mode 100644 index 00000000..067cef0b --- /dev/null +++ b/Documentation/nvme-id-domain.html @@ -0,0 +1,819 @@ + + + + + + +nvme-id-domain(1) + + + + + +
+
+

SYNOPSIS

+
+
+
nvme id-domain <device> [--dom-id=<domian_id> | -d <domian_id>]
+                        [-o <fmt> | --output-format=<fmt>]
+
+
+
+
+
+

DESCRIPTION

+
+

For the NVMe device given, send an identify command and return the domian list +data structure.

+

The <device> parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).

+
+
+
+

OPTIONS

+
+
+
+-d <domian_id> +
+
+--dom-id=<domian_id> +
+
+

+ Retrieve the identify domain list data structure for the given + domain id. If this value is not given, domain id will be 0xffff. +

+
+
+-o <format> +
+
+--output-format=<format> +
+
+

+ Set the reporting format to normal, json, or + binary. Only one output format can be used at a time. +

+
+
+
+
+
+

EXAMPLES

+
+

No examples yet.

+
+
+
+

NVME

+
+

Part of the nvme-user suite

+
+
+
+

+ + + diff --git a/Documentation/nvme-id-domain.txt b/Documentation/nvme-id-domain.txt new file mode 100644 index 00000000..be7b81ab --- /dev/null +++ b/Documentation/nvme-id-domain.txt @@ -0,0 +1,40 @@ +nvme-id-domain(1) +================= + +NAME +---- +nvme-id-domain - Send NVMe Identify Domain List, return result and structure + +SYNOPSIS +-------- +[verse] +'nvme id-domain' [--dom-id= | -d ] + [-o | --output-format=] + +DESCRIPTION +----------- +For the NVMe device given, send an identify command and return the domian list +data structure. + +The parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1). + +OPTIONS +------- +-d :: +--dom-id=:: + Retrieve the identify domain list data structure for the given + domain id. If this value is not given, domain id will be 0xffff. + +-o :: +--output-format=:: + Set the reporting format to 'normal', 'json', or + 'binary'. Only one output format can be used at a time. + +EXAMPLES +-------- +No examples yet. + +NVME +---- +Part of the nvme-user suite diff --git a/completions/_nvme b/completions/_nvme index f864dd40..b8070d62 100644 --- a/completions/_nvme +++ b/completions/_nvme @@ -11,6 +11,7 @@ _nvme () { 'id-ns:display information about the namespace' 'list-ns:identify all namespace(s) attached' 'id-iocs:display information about I/O command sets' + 'id-domain:display information about domain list' 'create-ns:create a new namespace before attachment' 'delete-ns:delete a detached namespace' 'attach-ns:attach namespace to controller' @@ -114,6 +115,16 @@ _nvme () { _arguments '*:: :->subcmds' _describe -t commands "nvme id-iocs options" _idiocs ;; + (id-domain) + local _iddomain + _iddomain=( + /dev/nvme':supply a device to use (required)' + --dom-id=':show infos for domain id ' + -d':alias of --dom-id' + ) + _arguments '*:: :->subcmds' + _describe -t commands "nvme id-domain options" _iddomain + ;; nvm-id-ctrl) local _nvmidctrl _nvmidctrl=( @@ -809,7 +820,7 @@ _nvme () { security-send security-recv resv-acquire resv-register resv-release resv-report flush compare read write copy show-regs persistent-event-log pred-lat-event-agg-log nvm-id-ctrl endurance-event-agg-log lba-status-log - resv-notif-log capacity-mgmt + resv-notif-log capacity-mgmt id-domain ) _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 9f89da1c..563c8487 100644 --- a/completions/bash-nvme-completion.sh +++ b/completions/bash-nvme-completion.sh @@ -12,7 +12,7 @@ _cmds="list id-ctrl id-ns list-ns id-iocs nvm-id-ctrl create-ns delete-ns \ write-uncor copy reset subsystem-reset show-regs discover \ connect-all connect disconnect version help \ intel lnvm memblaze list-subsys endurance-event-agg-log \ - lba-status-log resv-notif-log capacity-mgmt" + lba-status-log resv-notif-log id-domain" nvme_list_opts () { local opts="" @@ -50,6 +50,9 @@ nvme_list_opts () { "id-iocs") opts+=" --controller-id= -c" ;; + "id-domain") + opts+=" --dom-id= -d --output-format= -o" + ;; "nvm-id-ctrl") opts+=" --output-format= -o" ;; diff --git a/linux/nvme.h b/linux/nvme.h index a63b3455..c5224a6f 100644 --- a/linux/nvme.h +++ b/linux/nvme.h @@ -455,6 +455,7 @@ enum { NVME_ID_CNS_SCNDRY_CTRL_LIST = 0x15, NVME_ID_CNS_NS_GRANULARITY = 0x16, NVME_ID_CNS_UUID_LIST = 0x17, + NVME_ID_CNS_DOMAIN_LIST = 0x18, NVME_ID_CNS_CSI_NS_PRESENT_LIST = 0x1a, NVME_ID_CNS_CSI_NS_PRESENT = 0x1b, NVME_ID_CNS_CSI = 0x1c, @@ -1895,4 +1896,20 @@ enum nvme_zns_report_options { NVME_ZNS_ZRAS_REPORT_READ_ONLY = 0x6, NVME_ZNS_ZRAS_REPORT_OFFLINE = 0x7, }; + +struct nvme_id_domain_attr_entry { + __le16 dom_id; + __u8 rsvd2[14]; + __u8 dom_cap[16]; + __u8 unalloc_dom_cap[16]; + __u8 max_egrp_dom_cap[16]; + __u8 rsvd64[64]; +}; + +struct nvme_id_domain_list { + __u8 num_entries; + __u8 rsvd1[127]; + struct nvme_id_domain_attr_entry domain_attr[]; +}; + #endif /* _LINUX_NVME_H */ diff --git a/nvme-builtin.h b/nvme-builtin.h index 42ae5a27..80839410 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -21,6 +21,7 @@ COMMAND_LIST( ENTRY("id-nvmset", "Send NVMe Identify NVM Set List, display structure", id_nvmset) ENTRY("id-uuid", "Send NVMe Identify UUID List, display structure", id_uuid) ENTRY("id-iocs", "Send NVMe Identify I/O Command Set, display structure", id_iocs) + ENTRY("id-domain", "Send NVMe Identify Domain List, display structure", id_domain) ENTRY("create-ns", "Creates a namespace with the provided parameters", create_ns) ENTRY("delete-ns", "Deletes a namespace from the controller", delete_ns) ENTRY("attach-ns", "Attaches a namespace to requested controller(s)", attach_ns) diff --git a/nvme-ioctl.c b/nvme-ioctl.c index 40ac16f9..e7092c5b 100644 --- a/nvme-ioctl.c +++ b/nvme-ioctl.c @@ -466,6 +466,11 @@ int nvme_identify_iocs(int fd, __u16 cntid, void *data) return nvme_identify(fd, 0, (cntid << 16) | NVME_ID_CNS_CSI, data); } +int nvme_identify_domain_list(int fd, __u16 dom_id, void *data) +{ + return nvme_identify13(fd, 0, NVME_ID_CNS_DOMAIN_LIST, dom_id, data); +} + int nvme_get_log14(int fd, __u32 nsid, __u8 log_id, __u8 lsp, __u64 lpo, __u16 lsi, bool rae, __u8 uuid_ix, __u8 csi, bool ot, __u32 data_len, void *data) diff --git a/nvme-ioctl.h b/nvme-ioctl.h index acb79e1b..7be1ffdd 100644 --- a/nvme-ioctl.h +++ b/nvme-ioctl.h @@ -87,6 +87,7 @@ int nvme_identify_ctrl_nvm(int fd, void *data); int nvme_zns_identify_ctrl(int fd, void *data); int nvme_zns_identify_ns(int fd, __u32 nsid, void *data); int nvme_identify_iocs(int fd, __u16 cntid, void *data); +int nvme_identify_domain_list(int fd, __u16 dom_id, void *data); int nvme_get_log(int fd, __u32 nsid, __u8 log_id, bool rae, __u8 lsp, __u32 data_len, void *data); int nvme_get_log14(int fd, __u32 nsid, __u8 log_id, __u8 lsp, __u64 lpo, diff --git a/nvme-print.c b/nvme-print.c index dc400aff..6c6b1583 100755 --- a/nvme-print.c +++ b/nvme-print.c @@ -4764,6 +4764,61 @@ void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags) } } +static void json_id_domain_list(struct nvme_id_domain_list *id_dom) +{ + struct json_object *root; + struct json_object *entries; + struct json_object *entry; + int i; + long double dom_cap, unalloc_dom_cap, max_egrp_dom_cap; + + root = json_create_object(); + entries = json_create_array(); + + json_object_add_value_uint(root, "num_dom_entries", id_dom->num_entries); + + for (i = 0; i < id_dom->num_entries; i++) { + entry = json_create_object(); + dom_cap = int128_to_double(id_dom->domain_attr[i].dom_cap); + unalloc_dom_cap = int128_to_double(id_dom->domain_attr[i].unalloc_dom_cap); + max_egrp_dom_cap = int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap); + + json_object_add_value_uint(entry, "dom_id", le16_to_cpu(id_dom->domain_attr[i].dom_id)); + json_object_add_value_float(entry, "dom_cap", dom_cap); + json_object_add_value_float(entry, "unalloc_dom_cap", unalloc_dom_cap); + json_object_add_value_float(entry, "max_egrp_dom_cap", max_egrp_dom_cap); + + json_array_add_value_object(entries, entry); + } + + json_object_add_value_array(root, "domain_list", entries); + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); +} + +void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom, + enum nvme_print_flags flags) +{ + int i; + if (flags & BINARY) + return d_raw((unsigned char *)id_dom, sizeof(*id_dom)); + else if (flags & JSON) + return json_id_domain_list(id_dom); + + printf("Number of Domain Entires: %u\n", id_dom->num_entries); + for (i = 0; i < id_dom->num_entries; i++) { + printf("Domain Id for Attr Entry[%u]: %u\n", i, + le16_to_cpu(id_dom->domain_attr[i].dom_id)); + printf("Domain Capacity for Attr Entry[%u]: %.0Lf\\n", i, + int128_to_double(id_dom->domain_attr[i].dom_cap)); + printf("Unallocated Domain Capacity for Attr Entry[%u]: %.0Lf\n", i, + int128_to_double(id_dom->domain_attr[i].unalloc_dom_cap)); + printf("Max Endurange Group Domain Capacity for Attr Entry[%u]: %.0Lf\n", i, + int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap)); + } +} + static const char *nvme_trtype_to_string(__u8 trtype) { switch (trtype) { diff --git a/nvme-print.h b/nvme-print.h index 46abc0ba..08be8f23 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -87,6 +87,8 @@ void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags); void nvme_show_list_ctrl(struct nvme_controller_list *ctrl_list, enum nvme_print_flags flags); void nvme_show_list_ns(__u32 *ns_list, enum nvme_print_flags flags); +void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom, + enum nvme_print_flags flags); void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned char *buf); void nvme_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result, diff --git a/nvme.c b/nvme.c index 7f08e8bb..dde7a13e 100644 --- a/nvme.c +++ b/nvme.c @@ -2434,6 +2434,57 @@ ret: return nvme_status_to_errno(err, false); } +static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *plugin) { + const char *desc = "Send an Identify Domain List command to the "\ + "given device, returns properties of the specified domain "\ + "in either normal|json|binary format."; + const char *domain_id = "identifier of desired domain"; + struct nvme_id_domain_list id_domain; + enum nvme_print_flags flags; + int err, fd; + + struct config { + __u16 dom_id; + char *output_format; + }; + + struct config cfg = { + .dom_id = 0xffff, + .output_format = "normal", + }; + + OPT_ARGS(opts) = { + OPT_SHRT("dom-id", 'd', &cfg.dom_id, domain_id), + OPT_FMT("output-format", 'o', &cfg.output_format, output_format), + OPT_END() + }; + + fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) { + err = fd; + goto ret; + } + + err = flags = validate_output_format(cfg.output_format); + if (flags < 0) + goto close_fd; + + err = nvme_identify_domain_list(fd, cfg.dom_id, &id_domain); + if (!err) { + printf("NVMe Identify command for Domain List is successful:\n"); + printf("NVMe Identify Domain List:\n"); + nvme_show_id_domain_list(&id_domain, flags); + } else if (err > 0) + nvme_show_status(err); + else + perror("NVMe Identify Domain List"); + +close_fd: + close(fd); +ret: + return nvme_status_to_errno(err, false); +} + static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin *plugin) { int err = 0, nsid, fd;