From 24949de019ce724a70724eba980e6e6743c85be4 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Sat, 6 Mar 2021 01:50:57 +0530 Subject: [PATCH] nvme: add reservation notifacation log page This is to add the support for the reservation notification log page with LID = 0x80. Signed-off-by: Gollu Appalanaidu Co-Authored-By: Karthik Balan --- Documentation/nvme-resv-notif-log.1 | 98 +++ Documentation/nvme-resv-notif-log.html | 829 +++++++++++++++++++++++++ Documentation/nvme-resv-notif-log.txt | 51 ++ completions/_nvme | 10 + completions/bash-nvme-completion.sh | 5 +- linux/nvme.h | 9 + nvme-builtin.h | 1 + nvme-ioctl.c | 6 + nvme-ioctl.h | 1 + nvme-print.c | 49 ++ nvme-print.h | 2 + nvme.c | 48 ++ 12 files changed, 1108 insertions(+), 1 deletion(-) create mode 100644 Documentation/nvme-resv-notif-log.1 create mode 100644 Documentation/nvme-resv-notif-log.html create mode 100644 Documentation/nvme-resv-notif-log.txt diff --git a/Documentation/nvme-resv-notif-log.1 b/Documentation/nvme-resv-notif-log.1 new file mode 100644 index 00000000..ec0aca24 --- /dev/null +++ b/Documentation/nvme-resv-notif-log.1 @@ -0,0 +1,98 @@ +'\" t +.\" Title: nvme-resv-notif-log +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.79.1 +.\" Date: 03/09/2021 +.\" Manual: NVMe Manual +.\" Source: NVMe +.\" Language: English +.\" +.TH "NVME\-RESV\-NOTIF\-L" "1" "03/09/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-resv-notif-log \- Send NVMe Reservation Notification log page request, return result and log +.SH "SYNOPSIS" +.sp +.nf +\fInvme resv\-notif\-log\fR [\-\-output\-format= | \-o ] +.fi +.SH "DESCRIPTION" +.sp +Retrieves NVMe Reservation Notification log page from an NVMe device and provides the returned 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)\&. +.sp +On success, the returned Reservation Notification 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\&. +.SH "OPTIONS" +.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 +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Get the Reservation Notification log and print it in a human readable format: +.sp +.if n \{\ +.RS 4 +.\} +.nf +# nvme resv\-notif\-log /dev/nvme0 +.fi +.if n \{\ +.RE +.\} +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Print the output in json format: +.sp +.if n \{\ +.RS 4 +.\} +.nf +# nvme resv\-notif\-log /dev/nvme0 \-o json +.fi +.if n \{\ +.RE +.\} +.RE +.SH "NVME" +.sp +Part of the nvme\-user suite diff --git a/Documentation/nvme-resv-notif-log.html b/Documentation/nvme-resv-notif-log.html new file mode 100644 index 00000000..ebac7e10 --- /dev/null +++ b/Documentation/nvme-resv-notif-log.html @@ -0,0 +1,829 @@ + + + + + + +nvme-resv-notif-log(1) + + + + + +
+
+

SYNOPSIS

+
+
+
nvme resv-notif-log <device> [--output-format=<fmt> | -o <fmt>]
+
+
+
+
+
+

DESCRIPTION

+
+

Retrieves NVMe Reservation Notification log page from an NVMe device and +provides the returned 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).

+

On success, the returned Reservation Notification 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

+
+
+
+-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

+
+
    +
  • +

    +Get the Reservation Notification log and print it in a human readable format: +

    +
    +
    +
    # nvme resv-notif-log /dev/nvme0
    +
    +
  • +
  • +

    +Print the output in json format: +

    +
    +
    +
    # nvme resv-notif-log /dev/nvme0 -o json
    +
    +
  • +
+
+
+
+

NVME

+
+

Part of the nvme-user suite

+
+
+
+

+ + + diff --git a/Documentation/nvme-resv-notif-log.txt b/Documentation/nvme-resv-notif-log.txt new file mode 100644 index 00000000..a9c5cdda --- /dev/null +++ b/Documentation/nvme-resv-notif-log.txt @@ -0,0 +1,51 @@ +nvme-resv-notif-log(1) +====================== + +NAME +---- +nvme-resv-notif-log - Send NVMe Reservation Notification log page request, + return result and log + +SYNOPSIS +-------- +[verse] +'nvme resv-notif-log' [--output-format= | -o ] + +DESCRIPTION +----------- +Retrieves NVMe Reservation Notification log page from an NVMe device and +provides the returned structure. + +The parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1). + +On success, the returned Reservation Notification 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 +------- +-o :: +--output-format=:: + Set the reporting format to 'normal', 'json', or + 'binary'. Only one output format can be used at a time. + +EXAMPLES +-------- +* Get the Reservation Notification log and print it in a human readable format: ++ +------------ +# nvme resv-notif-log /dev/nvme0 +------------ ++ + +* Print the output in json format: ++ +------------ +# nvme resv-notif-log /dev/nvme0 -o json +------------ + +NVME +---- +Part of the nvme-user suite diff --git a/completions/_nvme b/completions/_nvme index 71c12975..92675224 100644 --- a/completions/_nvme +++ b/completions/_nvme @@ -28,6 +28,7 @@ _nvme () { 'error-log:retrieve error log' 'endurance-event-agg-log:retrieve endurance group event aggregate log' 'lba-status-log:retrieve lba status log' + 'resv-notif-log: retrieve reservation notification log' 'get-feature:display a controller feature' 'set-feature:set a controller feature and show results' 'format:apply new block format to namespace' @@ -322,6 +323,14 @@ _nvme () { _arguments '*:: :->subcmds' _describe -t commands "nvme lba-status-log options" _lbastatuslog ;; + (resv-notif-log) + local _resvnotiflog + _resvnotiflog=( + /dev/nvme':supply a device to use (required)' + ) + _arguments '*:: :->subcmds' + _describe -t commands "nvme resv-notif-log options" _resvnotiflog + ;; (get-feature) local _getf _getf=( @@ -779,6 +788,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 ) _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 7ab4226a..c022b89c 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" + lba-status-log resv-notif-log" nvme_list_opts () { local opts="" @@ -108,6 +108,9 @@ nvme_list_opts () { "lba-status-log") opts+=" --rae -r --output-format= -o" ;; + "resv-notif-log") + opts+=" --output-format= -o" + ;; "get-feature") opts+=" --namespace-id= -n --feature-id= -f --sel= -s \ --data-len= -l --cdw11= --raw-binary -b \ diff --git a/linux/nvme.h b/linux/nvme.h index 355bcb04..6dde09df 100644 --- a/linux/nvme.h +++ b/linux/nvme.h @@ -934,6 +934,15 @@ struct nvme_lba_status_hdr { __le16 lsgc; }; +struct nvme_resv_notif_log { + __le64 log_page_count; + __u8 resv_notif_log_type; + __u8 num_logs; + __u8 rsvd10[2]; + __le32 nsid; + __u8 rsvd16[48]; +}; + enum { NVME_SMART_CRIT_SPARE = 1 << 0, NVME_SMART_CRIT_TEMPERATURE = 1 << 1, diff --git a/nvme-builtin.h b/nvme-builtin.h index 296afd65..2679a17a 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -39,6 +39,7 @@ COMMAND_LIST( ENTRY("persistent-event-log", "Retrieve Presistent Event Log, show it", get_persistent_event_log) ENTRY("endurance-event-agg-log", "Retrieve Endurance Group Event Aggregate Log, show it", get_endurance_event_agg_log) ENTRY("lba-status-log", "Retrieve LBA Status Information Log, show it", get_lba_status_log) + ENTRY("resv-notif-log", "Retrieve Reservation Notification Log, show it", get_resv_notif_log) ENTRY("get-feature", "Get feature and show the resulting value", get_feature) ENTRY("device-self-test", "Perform the necessary tests to observe the performance", device_self_test) ENTRY("self-test-log", "Retrieve the SELF-TEST Log, show it", self_test_log) diff --git a/nvme-ioctl.c b/nvme-ioctl.c index f407b47b..7183cabc 100644 --- a/nvme-ioctl.c +++ b/nvme-ioctl.c @@ -634,6 +634,12 @@ int nvme_lba_status_log(int fd, void *lba_status, bool rae, rae, NVME_NO_LOG_LSP, size, lba_status); } +int nvme_resv_notif_log(int fd, struct nvme_resv_notif_log *resv) +{ + return nvme_get_log(fd, 0, NVME_LOG_RESERVATION, false, + NVME_NO_LOG_LSP, sizeof(*resv), resv); +} + int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 data_len, void *data, __u32 *result) { diff --git a/nvme-ioctl.h b/nvme-ioctl.h index 6149d629..830a1c8e 100644 --- a/nvme-ioctl.h +++ b/nvme-ioctl.h @@ -116,6 +116,7 @@ int nvme_endurance_log(int fd, __u16 group_id, struct nvme_endurance_group_log *endurance_log); int nvme_lba_status_log(int fd, void *lba_status, bool rae, __u32 size); +int nvme_resv_notif_log(int fd, struct nvme_resv_notif_log *resv); int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 data_len, void *data, __u32 *result); diff --git a/nvme-print.c b/nvme-print.c index b2a55af6..46caa6d7 100755 --- a/nvme-print.c +++ b/nvme-print.c @@ -1733,6 +1733,55 @@ void nvme_show_lba_status_log(void *lba_status, __u32 size, } } +static const char *resv_notif_to_string(__u8 type) +{ + switch (type) { + case 0x1: return "Empty Log Page"; + case 0x2: return "Registration Preempted"; + case 0x3: return "Reservation Released"; + case 0x4: return "Reservation Preempted"; + default: return "Reserved"; + } +} + +static void json_resv_notif_log(struct nvme_resv_notif_log *resv) +{ + struct json_object *root; + + root = json_create_object(); + json_object_add_value_uint(root, "count", + le64_to_cpu(resv->log_page_count)); + json_object_add_value_uint(root, "rn_log_type", + resv->resv_notif_log_type); + json_object_add_value_uint(root, "num_logs", + resv->num_logs); + json_object_add_value_uint(root, "nsid", + le32_to_cpu(resv->nsid)); + + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); +} + +void nvme_show_resv_notif_log(struct nvme_resv_notif_log *resv, + const char *devname, enum nvme_print_flags flags) +{ + if (flags & BINARY) + return d_raw((unsigned char *)resv, sizeof(*resv)); + if (flags & JSON) + return json_resv_notif_log(resv); + + printf("Reservation Notif Log for device: %s\n", devname); + printf("Log Page Count : %"PRIx64"\n", + le64_to_cpu(resv->log_page_count)); + printf("Resv Notif Log Page Type : %u (%s)\n", + resv->resv_notif_log_type, + resv_notif_to_string(resv->resv_notif_log_type)); + printf("Num of Available Log Pages : %u\n", resv->num_logs); + printf("Namespace ID: : %"PRIx32"\n", + le32_to_cpu(resv->nsid)); +} + static void nvme_show_subsystem(struct nvme_subsystem *s) { int i; diff --git a/nvme-print.h b/nvme-print.h index d6e1e2ab..37945f31 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -64,6 +64,8 @@ void nvme_show_endurance_group_event_agg_log( void json_lba_status_log(void *lba_status); void nvme_show_lba_status_log(void *lba_status, __u32 size, const char *devname, enum nvme_print_flags flags); +void nvme_show_resv_notif_log(struct nvme_resv_notif_log *resv, + const char *devname, enum nvme_print_flags flags); void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags flags); void nvme_show_single_property(int offset, uint64_t prop, int human); void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flags); diff --git a/nvme.c b/nvme.c index 7ede2750..5ce6c8e4 100644 --- a/nvme.c +++ b/nvme.c @@ -1162,6 +1162,54 @@ ret: return nvme_status_to_errno(err, false); } +static int get_resv_notif_log(int argc, char **argv, + struct command *cmd, struct plugin *plugin) +{ + + const char *desc = "Retrieve Reservation Notification " \ + "log page and prints it, for the given " \ + "device in either decoded format(default), " \ + "json or binary."; + struct nvme_resv_notif_log resv; + enum nvme_print_flags flags; + int err, fd; + + struct config { + char *output_format; + }; + + struct config cfg = { + .output_format = "normal", + }; + + OPT_ARGS(opts) = { + OPT_FMT("output-format", 'o', &cfg.output_format, output_format), + OPT_END() + }; + + err = fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + goto ret; + + err = flags = validate_output_format(cfg.output_format); + if (flags < 0) + goto close_fd; + + err = nvme_resv_notif_log(fd, &resv); + if (!err) + nvme_show_resv_notif_log(&resv, devicename, flags); + else if (err > 0) + nvme_show_status(err); + else + perror("resv notifi log"); + +close_fd: + close(fd); +ret: + return nvme_status_to_errno(err, false); + +} + static int get_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Retrieve desired number of bytes "\ -- 2.50.1