import CS nvme-cli-2.11-5.el9

This commit is contained in:
eabdullin 2025-03-11 07:52:05 +00:00
parent 79384b8760
commit 6dbdd0beeb
16 changed files with 891 additions and 766 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/nvme-cli-2.9.1.tar.gz
SOURCES/nvme-cli-2.11.tar.gz

View File

@ -1 +1 @@
33eaae0a2334451553952ac701f8568a52fd2a98 SOURCES/nvme-cli-2.9.1.tar.gz
e3a599bd67057c5bb9a8e7e621d439b9fbcaf7b6 SOURCES/nvme-cli-2.11.tar.gz

View File

@ -1,20 +0,0 @@
diff --git a/fabrics.c b/fabrics.c
index 871c20ede093..90c3e5d6c602 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -643,6 +643,7 @@ char *nvmf_hostid_from_hostnqn(const char *hostnqn)
void nvmf_check_hostid_and_hostnqn(const char *hostid, const char *hostnqn, unsigned int verbose)
{
+#if 0
_cleanup_free_ char *hostid_from_file = NULL;
_cleanup_free_ char *hostid_from_hostnqn = NULL;
@@ -665,6 +666,7 @@ void nvmf_check_hostid_and_hostnqn(const char *hostid, const char *hostnqn, unsi
fprintf(stderr,
"warning: use hostid which does not match uuid in hostnqn\n");
}
+#endif
}
int nvmf_discover(const char *desc, int argc, char **argv, bool connect)

View File

@ -0,0 +1,239 @@
From ab841e9a58688e64c5ce50e6159f34fc1a414c48 Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Mon, 11 Nov 2024 22:08:39 +0530
Subject: [PATCH] netapp-ontapdev: add verbose output
Add a vebose output option to display additional information of
ONTAP devices on the host.
Signed-off-by: Martin George <marting@netapp.com>
---
plugins/netapp/netapp-nvme.c | 141 +++++++++++++++++++++++++++++++----
1 file changed, 126 insertions(+), 15 deletions(-)
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index 9f05ffc5..cebd019e 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -119,6 +119,42 @@ static void netapp_get_ns_size(char *size, unsigned long long *lba,
sprintf(size, "%.2f%sB", nsze, s_suffix);
}
+static void netapp_get_ns_attrs(char *size, char *used, char *blk_size,
+ char *version, unsigned long long *lba,
+ struct nvme_id_ctrl *ctrl, struct nvme_id_ns *ns)
+{
+ __u8 lba_index;
+
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
+ *lba = 1ULL << ns->lbaf[lba_index].ds;
+
+ /* get the namespace size */
+ double nsze = le64_to_cpu(ns->nsze) * (*lba);
+ const char *s_suffix = suffix_si_get(&nsze);
+
+ sprintf(size, "%.2f%sB", nsze, s_suffix);
+
+ /* get the namespace utilization */
+ double nuse = le64_to_cpu(ns->nuse) * (*lba);
+ const char *u_suffix = suffix_si_get(&nuse);
+
+ sprintf(used, "%.2f%sB", nuse, u_suffix);
+
+ /* get the namespace block size */
+ long long addr = 1LL << ns->lbaf[lba_index].ds;
+ const char *l_suffix = suffix_binary_get(&addr);
+
+ sprintf(blk_size, "%u%sB", (unsigned int)addr, l_suffix);
+
+ /* get the ontap version */
+ int i, max = sizeof(ctrl->fr);
+
+ memcpy(version, ctrl->fr, sizeof(ctrl->fr));
+ /* strip trailing whitespaces */
+ for (i = max - 1; i >= 0 && version[i] == ' '; i--)
+ version[i] = '\0';
+}
+
static void ontap_labels_to_str(char *dst, char *src, int count)
{
int i;
@@ -235,7 +271,8 @@ static void netapp_smdevice_json(struct json_object *devices, char *devname,
static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
char *vsname, char *nspath, int nsid, char *uuid,
- char *size, long long lba, long long nsze)
+ unsigned long long lba, char *version,
+ unsigned long long nsze, unsigned long long nuse)
{
struct json_object *device_attrs;
@@ -245,9 +282,10 @@ static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
json_object_add_value_string(device_attrs, "Namespace_Path", nspath);
json_object_add_value_int(device_attrs, "NSID", nsid);
json_object_add_value_string(device_attrs, "UUID", uuid);
- json_object_add_value_string(device_attrs, "Size", size);
- json_object_add_value_int(device_attrs, "LBA_Data_Size", lba);
- json_object_add_value_int(device_attrs, "Namespace_Size", nsze);
+ json_object_add_value_uint64(device_attrs, "LBA_Data_Size", lba);
+ json_object_add_value_uint64(device_attrs, "Namespace_Size", nsze);
+ json_object_add_value_uint64(device_attrs, "UsedBytes", nuse);
+ json_object_add_value_string(device_attrs, "Version", version);
json_array_add_value_object(devices, device_attrs);
}
@@ -410,6 +448,66 @@ out:
json_free_object(root);
}
+static void netapp_ontapdevices_print_verbose(struct ontapdevice_info *devices,
+ int count, int format, const char *devname)
+{
+ char vsname[ONTAP_LABEL_LEN] = " ";
+ char nspath[ONTAP_NS_PATHLEN] = " ";
+ unsigned long long lba;
+ char size[128], used[128];
+ char blk_size[128], version[8];
+ char uuid_str[37] = " ";
+ int i;
+
+ char *formatstr = NULL;
+ char basestr[] =
+ "%s, Vserver %s, Path %s, NSID %d, UUID %s, %s, %s, %s, %s\n";
+ char columnstr[] = "%-16s %-25s %-50s %-4d %-38s %-9s %-9s %-9s %-9s\n";
+
+ if (format == NNORMAL)
+ formatstr = basestr;
+ else if (format == NCOLUMN) {
+ printf("%-16s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
+ "Device", "Vserver", "Namespace Path",
+ "NSID", "UUID", "Size", "Used",
+ "Format", "Version");
+ printf("%-16s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
+ "----------------", "-------------------------",
+ "--------------------------------------------------",
+ "----", "--------------------------------------",
+ "---------", "---------", "---------", "---------");
+ formatstr = columnstr;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (devname && !strcmp(devname, basename(devices[i].dev))) {
+ /* found the device, fetch and print for that alone */
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
+ nvme_uuid_to_string(devices[i].uuid, uuid_str);
+ netapp_get_ontap_labels(vsname, nspath,
+ devices[i].log_data);
+
+ printf(formatstr, devices[i].dev, vsname, nspath,
+ devices[i].nsid, uuid_str, size, used,
+ blk_size, version);
+ return;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ /* fetch info and print for all devices */
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
+ nvme_uuid_to_string(devices[i].uuid, uuid_str);
+ netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
+
+ printf(formatstr, devices[i].dev, vsname, nspath,
+ devices[i].nsid, uuid_str, size, used,
+ blk_size, version);
+ }
+}
+
static void netapp_ontapdevices_print_regular(struct ontapdevice_info *devices,
int count, int format, const char *devname)
{
@@ -472,7 +570,8 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
char vsname[ONTAP_LABEL_LEN] = " ";
char nspath[ONTAP_NS_PATHLEN] = " ";
unsigned long long lba;
- char size[128];
+ char size[128], used[128];
+ char blk_size[128], version[8];
char uuid_str[37] = " ";
int i;
@@ -483,28 +582,33 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
for (i = 0; i < count; i++) {
if (devname && !strcmp(devname, basename(devices[i].dev))) {
/* found the device, fetch info for that alone */
- netapp_get_ns_size(size, &lba, &devices[i].ns);
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
nvme_uuid_to_string(devices[i].uuid, uuid_str);
- netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
+ netapp_get_ontap_labels(vsname, nspath,
+ devices[i].log_data);
netapp_ontapdevice_json(json_devices, devices[i].dev,
vsname, nspath, devices[i].nsid,
- uuid_str, size, lba,
- le64_to_cpu(devices[i].ns.nsze));
+ uuid_str, lba, version,
+ le64_to_cpu(devices[i].ns.nsze),
+ le64_to_cpu(devices[i].ns.nuse));
goto out;
}
}
for (i = 0; i < count; i++) {
/* fetch info for all devices */
- netapp_get_ns_size(size, &lba, &devices[i].ns);
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
netapp_ontapdevice_json(json_devices, devices[i].dev,
vsname, nspath, devices[i].nsid,
- uuid_str, size, lba,
- le64_to_cpu(devices[i].ns.nsze));
+ uuid_str, lba, version,
+ le64_to_cpu(devices[i].ns.nsze),
+ le64_to_cpu(devices[i].ns.nuse));
}
out:
@@ -776,6 +880,7 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command,
int num_ontapdevices = 0;
struct config {
+ bool verbose;
char *output_format;
};
@@ -784,6 +889,7 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command,
};
OPT_ARGS(opts) = {
+ OPT_FLAG("verbose", 'v', &cfg.verbose, "Increase output verbosity"),
OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json|column"),
OPT_END()
};
@@ -839,9 +945,14 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command,
}
if (num_ontapdevices) {
- if (fmt == NNORMAL || fmt == NCOLUMN)
- netapp_ontapdevices_print_regular(ontapdevices,
- num_ontapdevices, fmt, devname);
+ if (fmt == NNORMAL || fmt == NCOLUMN) {
+ if (argconfig_parse_seen(opts, "verbose"))
+ netapp_ontapdevices_print_verbose(ontapdevices,
+ num_ontapdevices, fmt, devname);
+ else
+ netapp_ontapdevices_print_regular(ontapdevices,
+ num_ontapdevices, fmt, devname);
+ }
else if (fmt == NJSON)
netapp_ontapdevices_print_json(ontapdevices,
num_ontapdevices, devname);
--
2.43.5

View File

@ -0,0 +1,39 @@
From a8d1efcaba26dd992d89da2e60999642d7ae8eca Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Wed, 13 Nov 2024 00:14:07 +0530
Subject: [PATCH] netapp-ontapdev-doc: add verbose details
Add verbose option details to the ontapdevices documentation.
Signed-off-by: Martin George <marting@netapp.com>
---
Documentation/nvme-netapp-ontapdevices.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/nvme-netapp-ontapdevices.txt b/Documentation/nvme-netapp-ontapdevices.txt
index fc28947d..e56bae57 100644
--- a/Documentation/nvme-netapp-ontapdevices.txt
+++ b/Documentation/nvme-netapp-ontapdevices.txt
@@ -8,7 +8,7 @@ nvme-netapp-ontapdevices - Display information about ONTAP devices
SYNOPSIS
--------
[verse]
-'nvme netapp ontapdevices' [--output-format=<fmt> | -o <fmt>]
+'nvme netapp ontapdevices' [--output-format=<fmt> | -o <fmt>] [--verbose | -v]
DESCRIPTION
-----------
@@ -22,6 +22,10 @@ OPTIONS
Set the reporting format to 'normal' (default), 'column', or
'json'. Only one output format can be used at a time.
+-v::
+--verbose::
+ Display additional information of ONTAP devices on the host.
+
EXAMPLES
--------
* Display information, in a column-based format, for ONTAP devices.
--
2.43.5

View File

@ -1,76 +0,0 @@
From 42f788edccb954fe8b54c43809523e603c99f63c Mon Sep 17 00:00:00 2001
From: Maurizio Lombardi <mlombard@redhat.com>
Date: Wed, 22 May 2024 15:06:18 +0200
Subject: [PATCH] nvme: telemetry: report the correct error if the ioctl()
fails.
It's wrong to assume that if the ioctl() returns a non-zero number
then the errno variable is set.
The ioctl() might return an NVMe Status error to inform the caller
that the requested log page is not supported, in that case errno is left
untouched.
The original code didn't handle this case and returned "-errno" even when
the latter was zero. The caller interpreted this as a successful operation
and this might lead to improperly dereferencing the log page pointer.
$ nvme telemetry-log /dev/nvme0 --output-file=telemetry_log.bin
ERROR: get_telemetry_log: : write failed with error : Bad address
Fix this bug by returning the NVMe status if errno is zero:
$ nvme telemetry-log /dev/nvme0 --output-file=telemetry_log.bin
NVMe status: Invalid Log Page: The log page indicated is invalid(0x109)
Failed to acquire telemetry log 265!
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
---
nvme.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/nvme.c b/nvme.c
index d722b91e5ed8..226413bc0eda 100644
--- a/nvme.c
+++ b/nvme.c
@@ -717,7 +717,10 @@ static int get_log_telemetry_ctrl(struct nvme_dev *dev, bool rae, size_t size,
err = nvme_cli_get_log_telemetry_ctrl(dev, rae, 0, size, log);
if (err) {
free(log);
- return -errno;
+ if (errno)
+ return -errno;
+ else
+ return err;
}
*buf = log;
@@ -737,7 +740,10 @@ static int get_log_telemetry_host(struct nvme_dev *dev, size_t size,
err = nvme_cli_get_log_telemetry_host(dev, 0, size, log);
if (err) {
free(log);
- return -errno;
+ if (errno)
+ return -errno;
+ else
+ return err;
}
*buf = log;
@@ -757,8 +763,12 @@ static int __create_telemetry_log_host(struct nvme_dev *dev,
return -ENOMEM;
err = nvme_cli_get_log_create_telemetry_host(dev, log);
- if (err)
- return -errno;
+ if (err) {
+ if (errno)
+ return -errno;
+ else
+ return err;
+ }
err = parse_telemetry_da(dev, da, log, size);
if (err)
--
2.43.0

View File

@ -0,0 +1,52 @@
From 24961e9d228531f1cb60739239d7591aa70bdd53 Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Fri, 29 Nov 2024 11:04:34 +0530
Subject: [PATCH] netapp-ontapdev: fix fw version handling
The string used to capture the fw version was not handled
properly. Fix the same.
Signed-off-by: Martin George <marting@netapp.com>
---
plugins/netapp/netapp-nvme.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index cebd019e..76e8ddf1 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -146,10 +146,11 @@ static void netapp_get_ns_attrs(char *size, char *used, char *blk_size,
sprintf(blk_size, "%u%sB", (unsigned int)addr, l_suffix);
- /* get the ontap version */
+ /* get the firmware version */
int i, max = sizeof(ctrl->fr);
- memcpy(version, ctrl->fr, sizeof(ctrl->fr));
+ memcpy(version, ctrl->fr, max);
+ version[max] = '\0';
/* strip trailing whitespaces */
for (i = max - 1; i >= 0 && version[i] == ' '; i--)
version[i] = '\0';
@@ -455,7 +456,7 @@ static void netapp_ontapdevices_print_verbose(struct ontapdevice_info *devices,
char nspath[ONTAP_NS_PATHLEN] = " ";
unsigned long long lba;
char size[128], used[128];
- char blk_size[128], version[8];
+ char blk_size[128], version[9];
char uuid_str[37] = " ";
int i;
@@ -571,7 +572,7 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
char nspath[ONTAP_NS_PATHLEN] = " ";
unsigned long long lba;
char size[128], used[128];
- char blk_size[128], version[8];
+ char blk_size[128], version[9];
char uuid_str[37] = " ";
int i;
--
2.43.5

View File

@ -1,63 +0,0 @@
From fac45ce03315479b0d30e71316e669d9d4ffb31c Mon Sep 17 00:00:00 2001
From: Greg Joyce <gjoyce@linux.ibm.com>
Date: Fri, 10 May 2024 14:23:11 -0500
Subject: [PATCH] sed: only re-read partition table after unlock.
The partition table was being re-read after both lock and
unlock operations. The re-read would fail with an error
message after a lock since the partition was no longer readable.
Signed-off-by: Greg Joyce <gjoyce@linux.ibm.com>
---
plugins/sed/sedopal_cmd.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/plugins/sed/sedopal_cmd.c b/plugins/sed/sedopal_cmd.c
index 21ebd360c219..221f62b15186 100644
--- a/plugins/sed/sedopal_cmd.c
+++ b/plugins/sed/sedopal_cmd.c
@@ -251,8 +251,21 @@ int sedopal_cmd_lock(int fd)
*/
int sedopal_cmd_unlock(int fd)
{
+ int rc;
+
+ rc = sedopal_lock_unlock(fd, OPAL_RW);
+
+ /*
+ * If the unlock was successful, force a re-read of the
+ * partition table. Return rc of unlock operation.
+ */
+ if (rc == 0) {
+ if (ioctl(fd, BLKRRPART, 0) != 0)
+ fprintf(stderr,
+ "Warning: failed re-reading partition\n");
+ }
- return sedopal_lock_unlock(fd, OPAL_RW);
+ return rc;
}
/*
@@ -275,18 +288,6 @@ int sedopal_lock_unlock(int fd, int lock_state)
if (rc != 0)
fprintf(stderr,
"Error: failed locking or unlocking - %d\n", rc);
-
- /*
- * If the unlock was successful, force a re-read of the
- * partition table.
- */
- if (rc == 0) {
- rc = ioctl(fd, BLKRRPART, 0);
- if (rc != 0)
- fprintf(stderr,
- "Error: failed re-reading partition\n");
- }
-
return rc;
}
--
2.43.0

View File

@ -0,0 +1,42 @@
From b5208a987bf85ae3f4e264e6df55a7fb9acd9907 Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Fri, 29 Nov 2024 11:10:16 +0530
Subject: [PATCH] netapp-ontapdev: fix JSON output for nsze & nuse
The namespace size & utilization values printed in the JSON
output was incorrect. Fix the same.
Signed-off-by: Martin George <marting@netapp.com>
---
plugins/netapp/netapp-nvme.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index 76e8ddf1..6ff428d9 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -276,6 +276,8 @@ static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
unsigned long long nsze, unsigned long long nuse)
{
struct json_object *device_attrs;
+ unsigned long long ns_size = nsze * lba;
+ unsigned long long used_size = nuse * lba;
device_attrs = json_create_object();
json_object_add_value_string(device_attrs, "Device", devname);
@@ -283,9 +285,9 @@ static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
json_object_add_value_string(device_attrs, "Namespace_Path", nspath);
json_object_add_value_int(device_attrs, "NSID", nsid);
json_object_add_value_string(device_attrs, "UUID", uuid);
- json_object_add_value_uint64(device_attrs, "LBA_Data_Size", lba);
- json_object_add_value_uint64(device_attrs, "Namespace_Size", nsze);
- json_object_add_value_uint64(device_attrs, "UsedBytes", nuse);
+ json_object_add_value_uint64(device_attrs, "LBA_Size", lba);
+ json_object_add_value_uint64(device_attrs, "Namespace_Size", ns_size);
+ json_object_add_value_uint64(device_attrs, "UsedBytes", used_size);
json_object_add_value_string(device_attrs, "Version", version);
json_array_add_value_object(devices, device_attrs);
--
2.43.5

View File

@ -0,0 +1,53 @@
From 6f1f902af071fc46b78485ce851ffaaeb444c25f Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Fri, 29 Nov 2024 11:15:23 +0530
Subject: [PATCH] nvme-netapp: update err messages
Trivial fix to update a few error messages.
Signed-off-by: Martin George <marting@netapp.com>
---
plugins/netapp/netapp-nvme.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index 6ff428d9..aee65215 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -816,7 +816,7 @@ static int netapp_smdevices(int argc, char **argv, struct command *command,
num = scandir(dev_path, &devices, netapp_nvme_filter, alphasort);
if (num <= 0) {
- fprintf(stderr, "No NVMe devices detected.\n");
+ fprintf(stderr, "No NVMe devices detected\n");
return num;
}
@@ -834,7 +834,7 @@ static int netapp_smdevices(int argc, char **argv, struct command *command,
smdevices = calloc(num, sizeof(*smdevices));
if (!smdevices) {
- fprintf(stderr, "Unable to allocate memory for devices.\n");
+ fprintf(stderr, "Unable to allocate memory for devices\n");
return -ENOMEM;
}
@@ -921,13 +921,13 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command,
num = scandir(dev_path, &devices, netapp_nvme_filter, alphasort);
if (num <= 0) {
- fprintf(stderr, "No NVMe devices detected.\n");
+ fprintf(stderr, "No NVMe devices detected\n");
return num;
}
ontapdevices = calloc(num, sizeof(*ontapdevices));
if (!ontapdevices) {
- fprintf(stderr, "Unable to allocate memory for devices.\n");
+ fprintf(stderr, "Unable to allocate memory for devices\n");
return -ENOMEM;
}
--
2.43.5

View File

@ -0,0 +1,106 @@
From b8c9a3c1ee55c2477ce1ce0348014aa891dee58d Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Tue, 3 Dec 2024 13:16:17 +0530
Subject: [PATCH] netapp-smdev: remove redundant code
Remove redundant code in regular and JSON functions, which is
already invoked in a separate function.
Signed-off-by: Martin George <marting@netapp.com>
---
plugins/netapp/netapp-nvme.c | 44 +++++++-----------------------------
1 file changed, 8 insertions(+), 36 deletions(-)
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index aee65215..f839852d 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -300,7 +300,8 @@ static void netapp_smdevices_print_regular(struct smdevice_info *devices,
char array_label[ARRAY_LABEL_LEN / 2 + 1];
char volume_label[VOLUME_LABEL_LEN / 2 + 1];
char nguid_str[33];
- __u8 lba_index;
+ unsigned long long lba;
+ char size[128];
char *formatstr = NULL;
char basestr[] =
@@ -325,15 +326,7 @@ static void netapp_smdevices_print_regular(struct smdevice_info *devices,
for (i = 0; i < count; i++) {
if (devname && !strcmp(devname, basename(devices[i].dev))) {
/* found the device, fetch info for that alone */
- nvme_id_ns_flbas_to_lbaf_inuse(devices[i].ns.flbas,
- &lba_index);
- unsigned long long lba = 1ULL <<
- devices[i].ns.lbaf[lba_index].ds;
- double nsze = le64_to_cpu(devices[i].ns.nsze) * lba;
- const char *s_suffix = suffix_si_get(&nsze);
- char size[128];
-
- sprintf(size, "%.2f%sB", nsze, s_suffix);
+ netapp_get_ns_size(size, &lba, &devices[i].ns);
netapp_convert_string(array_label,
(char *)&devices[i].ctrl.vs[20],
ARRAY_LABEL_LEN / 2);
@@ -353,14 +346,7 @@ static void netapp_smdevices_print_regular(struct smdevice_info *devices,
for (i = 0; i < count; i++) {
/* fetch info for all devices */
- nvme_id_ns_flbas_to_lbaf_inuse(devices[i].ns.flbas, &lba_index);
- unsigned long long lba = 1ULL <<
- devices[i].ns.lbaf[lba_index].ds;
- double nsze = le64_to_cpu(devices[i].ns.nsze) * lba;
- const char *s_suffix = suffix_si_get(&nsze);
- char size[128];
-
- sprintf(size, "%.2f%sB", nsze, s_suffix);
+ netapp_get_ns_size(size, &lba, &devices[i].ns);
netapp_convert_string(array_label,
(char *)&devices[i].ctrl.vs[20],
ARRAY_LABEL_LEN / 2);
@@ -384,7 +370,8 @@ static void netapp_smdevices_print_json(struct smdevice_info *devices,
char array_label[ARRAY_LABEL_LEN / 2 + 1];
char volume_label[VOLUME_LABEL_LEN / 2 + 1];
char nguid_str[33];
- __u8 lba_index;
+ unsigned long long lba;
+ char size[128];
/* prepare for the json output */
root = json_create_object();
@@ -393,15 +380,7 @@ static void netapp_smdevices_print_json(struct smdevice_info *devices,
for (i = 0; i < count; i++) {
if (devname && !strcmp(devname, basename(devices[i].dev))) {
/* found the device, fetch info for that alone */
- nvme_id_ns_flbas_to_lbaf_inuse(devices[i].ns.flbas,
- &lba_index);
- unsigned long long lba = 1ULL <<
- devices[i].ns.lbaf[lba_index].ds;
- double nsze = le64_to_cpu(devices[i].ns.nsze) * lba;
- const char *s_suffix = suffix_si_get(&nsze);
- char size[128];
-
- sprintf(size, "%.2f%sB", nsze, s_suffix);
+ netapp_get_ns_size(size, &lba, &devices[i].ns);
netapp_convert_string(array_label,
(char *)&devices[i].ctrl.vs[20],
ARRAY_LABEL_LEN / 2);
@@ -421,14 +400,7 @@ static void netapp_smdevices_print_json(struct smdevice_info *devices,
for (i = 0; i < count; i++) {
/* fetch info for all devices */
- nvme_id_ns_flbas_to_lbaf_inuse(devices[i].ns.flbas, &lba_index);
- unsigned long long lba = 1ULL <<
- devices[i].ns.lbaf[lba_index].ds;
- double nsze = le64_to_cpu(devices[i].ns.nsze) * lba;
- const char *s_suffix = suffix_si_get(&nsze);
- char size[128];
-
- sprintf(size, "%.2f%sB", nsze, s_suffix);
+ netapp_get_ns_size(size, &lba, &devices[i].ns);
netapp_convert_string(array_label,
(char *)&devices[i].ctrl.vs[20],
ARRAY_LABEL_LEN / 2);
--
2.43.5

View File

@ -0,0 +1,230 @@
From 0943fc446609996dc6acf2fae7f31a6c20c28e06 Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Wed, 4 Dec 2024 00:24:48 +0530
Subject: [PATCH] netapp-smdev: add verbose output
Add a verbose option to display additional information of smdevices
on the host. And while at it, make a few corrections/modifications
to the JSON output as well.
Signed-off-by: Martin George <marting@netapp.com>
Tested-by: Clayton Skaggs <claytons@netapp.com>
---
plugins/netapp/netapp-nvme.c | 123 ++++++++++++++++++++++++++++++-----
1 file changed, 108 insertions(+), 15 deletions(-)
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index f839852d..d86e93e1 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -250,10 +250,11 @@ static void netapp_get_ontap_labels(char *vsname, char *nspath,
static void netapp_smdevice_json(struct json_object *devices, char *devname,
char *arrayname, char *volname, int nsid, char *nguid,
- char *ctrl, char *astate, char *size, long long lba,
- long long nsze)
+ char *ctrl, char *astate, char *version, unsigned long long lba,
+ unsigned long long nsze, unsigned long long nuse)
{
struct json_object *device_attrs;
+ unsigned long long ns_size = nsze * lba;
device_attrs = json_create_object();
json_object_add_value_string(device_attrs, "Device", devname);
@@ -263,9 +264,9 @@ static void netapp_smdevice_json(struct json_object *devices, char *devname,
json_object_add_value_string(device_attrs, "Volume_ID", nguid);
json_object_add_value_string(device_attrs, "Controller", ctrl);
json_object_add_value_string(device_attrs, "Access_State", astate);
- json_object_add_value_string(device_attrs, "Size", size);
- json_object_add_value_int(device_attrs, "LBA_Data_Size", lba);
- json_object_add_value_int(device_attrs, "Namespace_Size", nsze);
+ json_object_add_value_uint64(device_attrs, "LBA_Size", lba);
+ json_object_add_value_uint64(device_attrs, "Namespace_Size", ns_size);
+ json_object_add_value_string(device_attrs, "Version", version);
json_array_add_value_object(devices, device_attrs);
}
@@ -293,6 +294,84 @@ static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
json_array_add_value_object(devices, device_attrs);
}
+static void netapp_smdevices_print_verbose(struct smdevice_info *devices,
+ int count, int format, const char *devname)
+{
+ int i, slta;
+ char array_label[ARRAY_LABEL_LEN / 2 + 1];
+ char volume_label[VOLUME_LABEL_LEN / 2 + 1];
+ char nguid_str[33];
+ unsigned long long lba;
+ char size[128], used[128];
+ char blk_size[128], version[9];
+
+ char *formatstr = NULL;
+ char basestr[] =
+ "%s, Array %s, Vol %s, NSID %d, ID %s, Ctrl %c, %s, %s, %s, %s\n";
+ char columnstr[] =
+ "%-16s %-30s %-30s %4d %32s %c %-12s %-9s %-9s %-9s\n";
+
+ if (format == NNORMAL)
+ formatstr = basestr;
+ else if (format == NCOLUMN) {
+ /* print column headers and change the output string */
+ printf("%-16s %-30s %-30s %-4s %-32s %-4s %-12s %-9s %-9s %-9s\n",
+ "Device", "Array Name", "Volume Name", "NSID",
+ "Volume ID", "Ctrl", "Access State", " Size",
+ "Format", "Version");
+ printf("%-16s %-30s %-30s %-4s %-32s %-4s %-12s %-9s %-9s %-9s\n",
+ "----------------", "------------------------------",
+ "------------------------------", "----",
+ "--------------------------------", "----",
+ "------------", "---------",
+ "---------", "---------");
+ formatstr = columnstr;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (devname && !strcmp(devname, basename(devices[i].dev))) {
+ /* found the device, fetch info for that alone */
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
+ netapp_convert_string(array_label,
+ (char *)&devices[i].ctrl.vs[20],
+ ARRAY_LABEL_LEN / 2);
+ slta = devices[i].ctrl.vs[0] & 0x1;
+ netapp_convert_string(volume_label,
+ (char *)devices[i].ns.vs,
+ VOLUME_LABEL_LEN / 2);
+ netapp_nguid_to_str(nguid_str, devices[i].ns.nguid);
+
+ printf(formatstr, devices[i].dev, array_label,
+ volume_label, devices[i].nsid,
+ nguid_str,
+ slta ? 'A' : 'B', "unknown", size,
+ blk_size, version);
+ return;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ /* fetch info and print for all devices */
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
+ netapp_convert_string(array_label,
+ (char *)&devices[i].ctrl.vs[20],
+ ARRAY_LABEL_LEN / 2);
+ slta = devices[i].ctrl.vs[0] & 0x1;
+ netapp_convert_string(volume_label,
+ (char *)devices[i].ns.vs,
+ VOLUME_LABEL_LEN / 2);
+ netapp_nguid_to_str(nguid_str, devices[i].ns.nguid);
+
+ printf(formatstr, devices[i].dev, array_label,
+ volume_label, devices[i].nsid,
+ nguid_str,
+ slta ? 'A' : 'B', "unknown", size,
+ blk_size, version);
+ }
+}
+
static void netapp_smdevices_print_regular(struct smdevice_info *devices,
int count, int format, const char *devname)
{
@@ -311,7 +390,7 @@ static void netapp_smdevices_print_regular(struct smdevice_info *devices,
if (format == NNORMAL)
formatstr = basestr;
else if (format == NCOLUMN) {
- /* change output string and print column headers */
+ /* print column headers and change the output string */
printf("%-16s %-30s %-30s %-4s %-32s %-4s %-12s %-9s\n",
"Device", "Array Name", "Volume Name", "NSID",
"Volume ID", "Ctrl", "Access State", " Size");
@@ -371,7 +450,8 @@ static void netapp_smdevices_print_json(struct smdevice_info *devices,
char volume_label[VOLUME_LABEL_LEN / 2 + 1];
char nguid_str[33];
unsigned long long lba;
- char size[128];
+ char size[128], used[128];
+ char blk_size[128], version[9];
/* prepare for the json output */
root = json_create_object();
@@ -380,7 +460,8 @@ static void netapp_smdevices_print_json(struct smdevice_info *devices,
for (i = 0; i < count; i++) {
if (devname && !strcmp(devname, basename(devices[i].dev))) {
/* found the device, fetch info for that alone */
- netapp_get_ns_size(size, &lba, &devices[i].ns);
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
netapp_convert_string(array_label,
(char *)&devices[i].ctrl.vs[20],
ARRAY_LABEL_LEN / 2);
@@ -392,15 +473,18 @@ static void netapp_smdevices_print_json(struct smdevice_info *devices,
netapp_smdevice_json(json_devices, devices[i].dev,
array_label, volume_label,
devices[i].nsid, nguid_str,
- slta ? "A" : "B", "unknown", size, lba,
- le64_to_cpu(devices[i].ns.nsze));
+ slta ? "A" : "B", "unknown",
+ version, lba,
+ le64_to_cpu(devices[i].ns.nsze),
+ le64_to_cpu(devices[i].ns.nuse));
goto out;
}
}
for (i = 0; i < count; i++) {
/* fetch info for all devices */
- netapp_get_ns_size(size, &lba, &devices[i].ns);
+ netapp_get_ns_attrs(size, used, blk_size, version,
+ &lba, &devices[i].ctrl, &devices[i].ns);
netapp_convert_string(array_label,
(char *)&devices[i].ctrl.vs[20],
ARRAY_LABEL_LEN / 2);
@@ -412,7 +496,9 @@ static void netapp_smdevices_print_json(struct smdevice_info *devices,
netapp_smdevice_json(json_devices, devices[i].dev,
array_label, volume_label, devices[i].nsid,
nguid_str, slta ? "A" : "B", "unknown",
- size, lba, le64_to_cpu(devices[i].ns.nsze));
+ version, lba,
+ le64_to_cpu(devices[i].ns.nsze),
+ le64_to_cpu(devices[i].ns.nuse));
}
out:
@@ -764,6 +850,7 @@ static int netapp_smdevices(int argc, char **argv, struct command *command,
int num_smdevices = 0;
struct config {
+ bool verbose;
char *output_format;
};
@@ -772,6 +859,7 @@ static int netapp_smdevices(int argc, char **argv, struct command *command,
};
OPT_ARGS(opts) = {
+ OPT_FLAG("verbose", 'v', &cfg.verbose, "Increase output verbosity"),
OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json|column"),
OPT_END()
};
@@ -826,9 +914,14 @@ static int netapp_smdevices(int argc, char **argv, struct command *command,
}
if (num_smdevices) {
- if (fmt == NNORMAL || fmt == NCOLUMN)
- netapp_smdevices_print_regular(smdevices,
- num_smdevices, fmt, devname);
+ if (fmt == NNORMAL || fmt == NCOLUMN) {
+ if (argconfig_parse_seen(opts, "verbose"))
+ netapp_smdevices_print_verbose(smdevices,
+ num_smdevices, fmt, devname);
+ else
+ netapp_smdevices_print_regular(smdevices,
+ num_smdevices, fmt, devname);
+ }
else if (fmt == NJSON)
netapp_smdevices_print_json(smdevices,
num_smdevices, devname);
--
2.43.5

View File

@ -0,0 +1,40 @@
From cd69ccb4d51b4c0b1f772f9fef42fbf441e4a7f2 Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Tue, 3 Dec 2024 13:26:56 +0530
Subject: [PATCH] netapp-smdev-doc: add verbose details
Add verbose option details to the smdevices documentation.
Signed-off-by: Martin George <marting@netapp.com>
Tested-by: Clayton Skaggs <claytons@netapp.com>
---
Documentation/nvme-netapp-smdevices.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/nvme-netapp-smdevices.txt b/Documentation/nvme-netapp-smdevices.txt
index cb68acf7..c135ff0c 100644
--- a/Documentation/nvme-netapp-smdevices.txt
+++ b/Documentation/nvme-netapp-smdevices.txt
@@ -8,7 +8,7 @@ nvme-netapp-smdevices - Display information for each NVMe path to an E-Series vo
SYNOPSIS
--------
[verse]
-'nvme netapp smdevices' [--output-format=<fmt> | -o <fmt>]
+'nvme netapp smdevices' [--output-format=<fmt> | -o <fmt>] [--verbose | -v]
DESCRIPTION
-----------
@@ -23,6 +23,10 @@ OPTIONS
Set the reporting format to 'normal' (default), 'column', or
'json'. Only one output format can be used at a time.
+-v::
+--verbose::
+ Display additional information of E-Series devices on the host.
+
EXAMPLES
--------
* Display information, in a column-based format, for each path to an E-Series
--
2.43.5

View File

@ -0,0 +1,56 @@
From 7057e6c50639fb05d0997eaa6fac48ece3cb38bc Mon Sep 17 00:00:00 2001
From: Bryan Gurney <bgurney@redhat.com>
Date: Tue, 21 Jan 2025 12:20:34 -0500
Subject: [PATCH] nvme: set eds to true if controller supports 128 bit hostid
A controller that uses a 128-bit Host Identifier may result in the
"nvme resv-report" command failing with a "Host Identifier Inconsistent
Format" error that suggests the "simultaneous use of 64-bit and
128-bit Host Identifier values on different controllers".
This error can be avoided if the "--eds" option is used, to request
the extended data structure. However, the controller's ctratt
value indicates whether the Host Identifier is 64 bits or 128 bits.
Therefore, check the ctratt flag, and set eds to true if the
controller indicates a 128-bit Host Identifier.
Signed-off-by: Bryan Gurney <bgurney@redhat.com>
---
nvme.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/nvme.c b/nvme.c
index a65873b2..2ed4ee92 100644
--- a/nvme.c
+++ b/nvme.c
@@ -7740,6 +7740,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
const char *eds = "request extended data structure";
_cleanup_free_ struct nvme_resv_status *status = NULL;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
nvme_print_flags_t flags;
int err, size;
@@ -7792,6 +7793,19 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
size = (cfg.numd + 1) << 2;
+ ctrl = nvme_alloc(sizeof(*ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
+ err = nvme_cli_identify_ctrl(dev, ctrl);
+ if (err) {
+ nvme_show_error("identify-ctrl: %s", nvme_strerror(errno));
+ return -errno;
+ }
+
+ if (ctrl->ctratt & NVME_CTRL_CTRATT_128_ID)
+ cfg.eds = true;
+
status = nvme_alloc(size);
if (!status)
return -ENOMEM;
--
2.43.5

View File

@ -1,596 +0,0 @@
From ca58ecc64852fc413a04f41d953914720d05459f Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Wed, 24 Apr 2024 17:46:19 +0200
Subject: [PATCH 1/5] fabrics: Make some symbols public
Needed for nbft, useful to have public.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
fabrics.c | 24 ++++++++++++------------
fabrics.h | 6 ++++++
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/fabrics.c b/fabrics.c
index 0b70d290a9..a82a56c7b0 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -195,9 +195,9 @@ static nvme_ctrl_t __create_discover_ctrl(nvme_root_t r, nvme_host_t h,
return c;
}
-static nvme_ctrl_t create_discover_ctrl(nvme_root_t r, nvme_host_t h,
- struct nvme_fabrics_config *cfg,
- struct tr_config *trcfg)
+nvme_ctrl_t nvmf_create_discover_ctrl(nvme_root_t r, nvme_host_t h,
+ struct nvme_fabrics_config *cfg,
+ struct tr_config *trcfg)
{
_cleanup_free_ struct nvme_id_ctrl *id = NULL;
nvme_ctrl_t c;
@@ -378,8 +378,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg,
return 0;
}
-static char *get_default_trsvcid(const char *transport,
- bool discovery_ctrl)
+char *nvmf_get_default_trsvcid(const char *transport, bool discovery_ctrl)
{
if (!transport)
return NULL;
@@ -465,7 +464,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
goto next;
if (!trsvcid)
- trsvcid = get_default_trsvcid(transport, true);
+ trsvcid = nvmf_get_default_trsvcid(transport, true);
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
@@ -485,7 +484,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
}
}
- c = create_discover_ctrl(r, h, &cfg, &trcfg);
+ c = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg);
if (!c)
goto next;
@@ -549,7 +548,8 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
trsvcid = nvme_ctrl_get_trsvcid(c);
if (!trsvcid || !strcmp(trsvcid, ""))
- trsvcid = get_default_trsvcid(transport, true);
+ trsvcid = nvmf_get_default_trsvcid(transport,
+ true);
if (force)
subsysnqn = nvme_ctrl_get_subsysnqn(c);
@@ -579,7 +579,7 @@ static int discover_from_json_config_file(nvme_root_t r, nvme_host_t h,
}
}
- cn = create_discover_ctrl(r, h, &cfg, &trcfg);
+ cn = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg);
if (!cn)
continue;
@@ -806,7 +806,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
}
if (!trsvcid)
- trsvcid = get_default_trsvcid(transport, true);
+ trsvcid = nvmf_get_default_trsvcid(transport, true);
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
@@ -876,7 +876,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
}
if (!c) {
/* No device or non-matching device, create a new controller */
- c = create_discover_ctrl(r, h, &cfg, &trcfg);
+ c = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg);
if (!c) {
if (errno != ENVME_CONNECT_IGNORED)
fprintf(stderr,
@@ -1005,7 +1005,7 @@ int nvmf_connect(const char *desc, int argc, char **argv)
if (hostkey)
nvme_host_set_dhchap_key(h, hostkey);
if (!trsvcid)
- trsvcid = get_default_trsvcid(transport, false);
+ trsvcid = nvmf_get_default_trsvcid(transport, false);
struct tr_config trcfg = {
.subsysnqn = subsysnqn,
diff --git a/fabrics.h b/fabrics.h
index c16df60472..aec305dc31 100644
--- a/fabrics.h
+++ b/fabrics.h
@@ -18,5 +18,11 @@ extern int nvmf_disconnect(const char *desc, int argc, char **argv);
extern int nvmf_disconnect_all(const char *desc, int argc, char **argv);
extern int nvmf_config(const char *desc, int argc, char **argv);
extern int nvmf_dim(const char *desc, int argc, char **argv);
+extern nvme_ctrl_t nvmf_create_discover_ctrl(nvme_root_t r, nvme_host_t h,
+ struct nvme_fabrics_config *cfg,
+ struct tr_config *trcfg);
+extern char *nvmf_get_default_trsvcid(const char *transport,
+ bool discovery_ctrl);
+
#endif
From 996fd5554157949ed77154eecd0f8236590cc716 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Wed, 24 Apr 2024 17:47:02 +0200
Subject: [PATCH 2/5] util/cleanup: Add cleanup for struct nvme_fabrics_uri
libnvme cleanup definitions are not part of public API.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
util/cleanup.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff -up nvme-cli-2.9.1/util/cleanup.h.bak nvme-cli-2.9.1/util/cleanup.h
--- nvme-cli-2.9.1/util/cleanup.h.bak 2024-06-21 15:53:35.839852234 +0200
+++ nvme-cli-2.9.1/util/cleanup.h 2024-05-03 16:03:42.000000000 +0200
@@ -34,4 +34,12 @@ static inline void close_file(int *f)
}
#define _cleanup_file_ __cleanup__(close_file)
+static inline void free_uri(struct nvme_fabrics_uri **uri)
+{
+ if (*uri)
+ nvme_free_uri(*uri);
+}
+
+#define _cleanup_uri_ __cleanup__(free_uri)
+
#endif
From 2f79015b83faff4947d29fb172d6f92d81f078e2 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Wed, 24 Apr 2024 17:52:46 +0200
Subject: [PATCH 3/5] nbft: Perform actual discovery
This adds actual discovery support for Discovery Descriptor records.
SSNS records are connected first. Discovery Descriptor records
are checked for any existing (back-)reference from SSNS records
and are skipped if so. It is assumed in such case that the pre-OS
driver has succeeded in discovery and filled SSNS records
accordingly.
In case no SSNS record references the particular Discovery
record, an actual discovery is performed.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
nbft.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
nbft.h | 2 +-
2 files changed, 223 insertions(+), 11 deletions(-)
diff --git a/nbft.c b/nbft.c
index 7ff8765a80..995b31ca54 100644
--- a/nbft.c
+++ b/nbft.c
@@ -7,6 +7,7 @@
#include <libnvme.h>
+#include "common.h"
#include "nvme.h"
#include "nbft.h"
#include "fabrics.h"
@@ -77,12 +78,38 @@ void free_nbfts(struct list_head *nbft_list)
}
}
+static bool validate_uri(struct nbft_info_discovery *dd,
+ struct nvme_fabrics_uri *uri)
+{
+ if (!uri) {
+ fprintf(stderr,
+ "Discovery Descriptor %d: failed to parse URI %s\n",
+ dd->index, dd->uri);
+ return false;
+ }
+ if (strcmp(uri->scheme, "nvme") != 0) {
+ fprintf(stderr,
+ "Discovery Descriptor %d: unsupported scheme '%s'\n",
+ dd->index, uri->scheme);
+ return false;
+ }
+ if (!uri->protocol || strcmp(uri->protocol, "tcp") != 0) {
+ fprintf(stderr,
+ "Discovery Descriptor %d: unsupported transport '%s'\n",
+ dd->index, uri->protocol);
+ return false;
+ }
+
+ return true;
+}
+
/* returns 0 for success or negative errno otherwise */
static int do_connect(nvme_root_t r,
nvme_host_t h,
+ struct nvmf_disc_log_entry *e,
struct nbft_info_subsystem_ns *ss,
struct tr_config *trcfg,
- const struct nvme_fabrics_config *cfg,
+ struct nvme_fabrics_config *cfg,
enum nvme_print_flags flags,
unsigned int verbose)
{
@@ -111,6 +138,12 @@ static int do_connect(nvme_root_t r,
nvme_init_logging(r, -1, false, false);
}
+ if (e) {
+ if (e->trtype == NVMF_TRTYPE_TCP &&
+ e->tsas.tcp.sectype != NVMF_TCP_SECTYPE_NONE)
+ cfg->tls = true;
+ }
+
errno = 0;
ret = nvmf_add_ctrl(h, c, cfg);
@@ -145,10 +178,114 @@ static int do_connect(nvme_root_t r,
return 0;
}
+static int do_discover(struct nbft_info_discovery *dd,
+ nvme_root_t r,
+ nvme_host_t h,
+ nvme_ctrl_t c,
+ struct nvme_fabrics_config *defcfg,
+ struct tr_config *deftrcfg,
+ enum nvme_print_flags flags,
+ unsigned int verbose)
+{
+ struct nvmf_discovery_log *log = NULL;
+ int i;
+ int ret;
+
+ struct nvme_get_discovery_args args = {
+ .c = c,
+ .args_size = sizeof(args),
+ .max_retries = 10 /* MAX_DISC_RETRIES */,
+ .result = 0,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .lsp = 0,
+ };
+
+ log = nvmf_get_discovery_wargs(&args);
+ if (!log) {
+ fprintf(stderr,
+ "Discovery Descriptor %d: failed to get discovery log: %s\n",
+ dd->index, nvme_strerror(errno));
+ return -errno;
+ }
+
+ for (i = 0; i < le64_to_cpu(log->numrec); i++) {
+ struct nvmf_disc_log_entry *e = &log->entries[i];
+ nvme_ctrl_t cl;
+ int tmo = defcfg->keep_alive_tmo;
+
+ struct tr_config trcfg = {
+ .subsysnqn = e->subnqn,
+ .transport = nvmf_trtype_str(e->trtype),
+ .traddr = e->traddr,
+ .host_traddr = deftrcfg->host_traddr,
+ .host_iface = deftrcfg->host_iface,
+ .trsvcid = e->trsvcid,
+ };
+
+ if (e->subtype == NVME_NQN_CURR)
+ continue;
+
+ /* Already connected ? */
+ cl = lookup_ctrl(h, &trcfg);
+ if (cl && nvme_ctrl_get_name(cl))
+ continue;
+
+ /* Skip connect if the transport types don't match */
+ if (strcmp(nvme_ctrl_get_transport(c),
+ nvmf_trtype_str(e->trtype)))
+ continue;
+
+ if (e->subtype == NVME_NQN_DISC) {
+ nvme_ctrl_t child;
+
+ child = nvmf_connect_disc_entry(h, e, defcfg, NULL);
+ do_discover(dd, r, h, child, defcfg, &trcfg,
+ flags, verbose);
+ nvme_disconnect_ctrl(child);
+ nvme_free_ctrl(child);
+ } else {
+ ret = do_connect(r, h, e, NULL, &trcfg,
+ defcfg, flags, verbose);
+
+ /*
+ * With TCP/DHCP, it can happen that the OS
+ * obtains a different local IP address than the
+ * firmware had. Retry without host_traddr.
+ */
+ if (ret == -ENVME_CONNECT_ADDRNOTAVAIL &&
+ !strcmp(trcfg.transport, "tcp") &&
+ strlen(dd->hfi->tcp_info.dhcp_server_ipaddr) > 0) {
+ const char *htradr = trcfg.host_traddr;
+
+ trcfg.host_traddr = NULL;
+ ret = do_connect(r, h, e, NULL, &trcfg,
+ defcfg, flags, verbose);
+
+ if (ret == 0 && verbose >= 1)
+ fprintf(stderr,
+ "Discovery Descriptor %d: connect with host_traddr=\"%s\" failed, success after omitting host_traddr\n",
+ dd->index,
+ htradr);
+ }
+
+ if (ret)
+ fprintf(stderr, "Discovery Descriptor %d: no controller found\n",
+ dd->index);
+ if (ret == -ENOMEM)
+ break;
+ }
+
+ defcfg->keep_alive_tmo = tmo;
+ }
+
+ free(log);
+ return 0;
+}
+
int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
char *hostnqn_sys, char *hostid_sys,
const char *desc, bool connect,
- const struct nvme_fabrics_config *cfg, char *nbft_path,
+ struct nvme_fabrics_config *cfg, char *nbft_path,
enum nvme_print_flags flags, unsigned int verbose)
{
char *hostnqn = NULL, *hostid = NULL, *host_traddr = NULL;
@@ -158,6 +295,7 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
struct nbft_file_entry *entry = NULL;
struct nbft_info_subsystem_ns **ss;
struct nbft_info_hfi *hfi;
+ struct nbft_info_discovery **dd;
if (!connect)
/* to do: print discovery-type info from NBFT tables */
@@ -192,15 +330,15 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
if (!h)
goto out_free;
+ /* Subsystem Namespace Descriptor List */
for (ss = entry->nbft->subsystem_ns_list; ss && *ss; ss++)
for (i = 0; i < (*ss)->num_hfis; i++) {
hfi = (*ss)->hfis[i];
- if (!cfg->host_traddr) {
- host_traddr = NULL;
- if (!strncmp((*ss)->transport, "tcp", 3))
- host_traddr = hfi->tcp_info.ipaddr;
- }
+ host_traddr = NULL;
+ if (!cfg->host_traddr &&
+ !strncmp((*ss)->transport, "tcp", 3))
+ host_traddr = hfi->tcp_info.ipaddr;
struct tr_config trcfg = {
.subsysnqn = (*ss)->subsys_nqn,
@@ -211,7 +349,7 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
.trsvcid = (*ss)->trsvcid,
};
- ret = do_connect(r, h, *ss, &trcfg,
+ ret = do_connect(r, h, NULL, *ss, &trcfg,
cfg, flags, verbose);
/*
@@ -220,11 +358,11 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
* firmware had. Retry without host_traddr.
*/
if (ret == -ENVME_CONNECT_ADDRNOTAVAIL &&
- !strcmp((*ss)->transport, "tcp") &&
+ !strcmp(trcfg.transport, "tcp") &&
strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) {
trcfg.host_traddr = NULL;
- ret = do_connect(r, h, *ss, &trcfg,
+ ret = do_connect(r, h, NULL, *ss, &trcfg,
cfg, flags, verbose);
if (ret == 0 && verbose >= 1)
@@ -241,6 +379,80 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
if (ret == -ENOMEM)
goto out_free;
}
+
+ /* Discovery Descriptor List */
+ for (dd = entry->nbft->discovery_list; dd && *dd; dd++) {
+ nvme_ctrl_t c;
+ bool linked = false;
+ _cleanup_uri_ struct nvme_fabrics_uri *uri = NULL;
+ _cleanup_free_ char *trsvcid = NULL;
+
+ /* only perform discovery when no SSNS record references it */
+ for (ss = entry->nbft->subsystem_ns_list; ss && *ss; ss++)
+ if ((*ss)->discovery &&
+ (*ss)->discovery->index == (*dd)->index &&
+ /* unavailable boot attempts are not discovered
+ * and may get transferred along with a well-known
+ * discovery NQN into an SSNS record.
+ */
+ strcmp((*ss)->subsys_nqn, NVME_DISC_SUBSYS_NAME) != 0) {
+ linked = true;
+ break;
+ }
+ if (linked)
+ continue;
+
+ hfi = (*dd)->hfi;
+ uri = nvme_parse_uri((*dd)->uri);
+ if (!validate_uri(*dd, uri))
+ continue;
+
+ host_traddr = NULL;
+ if (!cfg->host_traddr &&
+ !strncmp(uri->protocol, "tcp", 3))
+ host_traddr = hfi->tcp_info.ipaddr;
+ if (uri->port > 0) {
+ if (asprintf(&trsvcid, "%d", uri->port) < 0) {
+ errno = ENOMEM;
+ goto out_free;
+ }
+ } else
+ trsvcid = strdup(nvmf_get_default_trsvcid(uri->protocol, true));
+
+ struct tr_config trcfg = {
+ .subsysnqn = NVME_DISC_SUBSYS_NAME,
+ .transport = uri->protocol,
+ .traddr = uri->host,
+ .host_traddr = host_traddr,
+ .host_iface = NULL,
+ .trsvcid = trsvcid,
+ };
+
+ c = nvmf_create_discover_ctrl(r, h, cfg, &trcfg);
+ if (!c && errno == ENVME_CONNECT_ADDRNOTAVAIL &&
+ !strcmp(trcfg.transport, "tcp") &&
+ strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) {
+ trcfg.host_traddr = NULL;
+ c = nvmf_create_discover_ctrl(r, h, cfg, &trcfg);
+ }
+
+ if (!c) {
+ fprintf(stderr,
+ "Discovery Descriptor %d: failed to add discovery controller: %s\n",
+ (*dd)->index,
+ nvme_strerror(errno));
+ if (errno == ENOMEM)
+ goto out_free;
+ continue;
+ }
+
+ ret = do_discover(*dd, r, h, c, cfg, &trcfg,
+ flags, verbose);
+ nvme_disconnect_ctrl(c);
+ nvme_free_ctrl(c);
+ if (ret == -ENOMEM)
+ goto out_free;
+ }
}
out_free:
free_nbfts(&nbft_list);
diff --git a/nbft.h b/nbft.h
index 0f7e33cee5..5dfb8704fd 100644
--- a/nbft.h
+++ b/nbft.h
@@ -15,5 +15,5 @@ void free_nbfts(struct list_head *nbft_list);
extern int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
char *hostnqn_sys, char *hostid_sys,
const char *desc, bool connect,
- const struct nvme_fabrics_config *cfg, char *nbft_path,
+ struct nvme_fabrics_config *cfg, char *nbft_path,
enum nvme_print_flags flags, unsigned int verbose);
From 1074da1dbbbef229bf7e42a3cb644ab5b9745267 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Thu, 25 Apr 2024 15:54:53 +0200
Subject: [PATCH 4/5] nbft: Skip SSNS records pointing to well-known discovery
NQN
Depending on a pre-OS implementation, boot attempts pointing
to the well-known discovery NQN may get transformed in
an SSNS record (and marked as 'unavailable') in case
the discovery cannot be performed. Otherwise the NBFT
table should be populated by discovered records instead.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
nbft.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/nbft.c b/nbft.c
index 995b31ca54..9d1834d0db 100644
--- a/nbft.c
+++ b/nbft.c
@@ -335,6 +335,15 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
for (i = 0; i < (*ss)->num_hfis; i++) {
hfi = (*ss)->hfis[i];
+ /* Skip discovery NQN records */
+ if (strcmp((*ss)->subsys_nqn, NVME_DISC_SUBSYS_NAME) == 0) {
+ if (verbose >= 1)
+ fprintf(stderr,
+ "SSNS %d points to well-known discovery NQN, skipping\n",
+ (*ss)->index);
+ continue;
+ }
+
host_traddr = NULL;
if (!cfg->host_traddr &&
!strncmp((*ss)->transport, "tcp", 3))
From 8b4c30014ed17fa226a34a3dd92167f122ccec42 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Mon, 20 May 2024 17:43:01 +0200
Subject: [PATCH 5/5] nbft: Reuse existing discovery controller
Attempt to look up and use existing (persistent) discovery
controller.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
nbft.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/nbft.c b/nbft.c
index 9d1834d0db..8c03a1f53b 100644
--- a/nbft.c
+++ b/nbft.c
@@ -393,6 +393,7 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
for (dd = entry->nbft->discovery_list; dd && *dd; dd++) {
nvme_ctrl_t c;
bool linked = false;
+ bool persistent = false;
_cleanup_uri_ struct nvme_fabrics_uri *uri = NULL;
_cleanup_free_ char *trsvcid = NULL;
@@ -437,12 +438,19 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
.trsvcid = trsvcid,
};
- c = nvmf_create_discover_ctrl(r, h, cfg, &trcfg);
- if (!c && errno == ENVME_CONNECT_ADDRNOTAVAIL &&
- !strcmp(trcfg.transport, "tcp") &&
- strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) {
- trcfg.host_traddr = NULL;
+ /* Lookup existing discovery controller */
+ c = lookup_ctrl(h, &trcfg);
+ if (c && nvme_ctrl_get_name(c))
+ persistent = true;
+
+ if (!c) {
c = nvmf_create_discover_ctrl(r, h, cfg, &trcfg);
+ if (!c && errno == ENVME_CONNECT_ADDRNOTAVAIL &&
+ !strcmp(trcfg.transport, "tcp") &&
+ strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) {
+ trcfg.host_traddr = NULL;
+ c = nvmf_create_discover_ctrl(r, h, cfg, &trcfg);
+ }
}
if (!c) {
@@ -457,7 +465,8 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
ret = do_discover(*dd, r, h, c, cfg, &trcfg,
flags, verbose);
- nvme_disconnect_ctrl(c);
+ if (!persistent)
+ nvme_disconnect_ctrl(c);
nvme_free_ctrl(c);
if (ret == -ENOMEM)
goto out_free;

View File

@ -4,8 +4,8 @@
%global nmlibdir %{_prefix}/lib/NetworkManager
Name: nvme-cli
Version: 2.9.1
Release: 6%{?dist}
Version: 2.11
Release: 5%{?dist}
Summary: NVMe management command line interface
License: GPL-2.0-only
@ -13,12 +13,15 @@ URL: https://github.com/linux-nvme/nvme-cli
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
Source1: 99-nvme-nbft-connect.sh
Source2: 99-nvme-nbft-no-ignore-carrier.conf
Patch0: 0001-Revert-fabrics-Use-corresponding-hostid-when-hostnqn.patch
Patch1: 0002-nvme-telemetry-report-the-correct-error-if-the-ioctl.patch
# https://issues.redhat.com/browse/RHEL-37601
Patch2: nvme-cli-2.10-nbft-discovery.patch
Patch3: 0003-sed-only-re-read-partition-table-after-unlock.patch
Patch0: 0001-netapp-ontapdev-add-verbose-output.patch
Patch1: 0002-netapp-ontapdev-doc-add-verbose-details.patch
Patch2: 0003-netapp-ontapdev-fix-fw-version-handling.patch
Patch3: 0004-netapp-ontapdev-fix-JSON-output-for-nsze-nuse.patch
Patch4: 0005-nvme-netapp-update-err-messages.patch
Patch5: 0006-netapp-smdev-remove-redundant-code.patch
Patch6: 0007-netapp-smdev-add-verbose-output.patch
Patch7: 0008-netapp-smdev-doc-add-verbose-details.patch
Patch8: 0009-nvme-set-eds-to-true-if-controller-supports-128-bit-.patch
BuildRequires: meson >= 0.50.0
BuildRequires: gcc gcc-c++
@ -26,10 +29,11 @@ BuildRequires: libuuid-devel
BuildRequires: systemd-devel
BuildRequires: systemd-rpm-macros
BuildRequires: zlib-devel
BuildRequires: libnvme-devel >= 1.9-2
BuildRequires: libnvme-devel >= 1.11-1
BuildRequires: json-c-devel >= 0.14
BuildRequires: asciidoc
BuildRequires: xmlto
BuildRequires: kernel-headers >= 5.14.0-542
Requires: util-linux
@ -75,6 +79,7 @@ rm -rf %{buildroot}%{_pkgdocdir}/nvme
%{_unitdir}/nvmf-connect@.service
%{_udevrulesdir}/65-persistent-net-nbft.rules
%{_udevrulesdir}/70-nvmf-autoconnect.rules
%{_udevrulesdir}/70-nvmf-keys.rules
%{_udevrulesdir}/71-nvmf-netapp.rules
# Do not install the dracut rule yet. See rhbz 1742764
# Is this still true? Now that we support nvme-of boot, do we want to install this file?
@ -101,6 +106,24 @@ if [ $1 -eq 1 ] || [ $1 -eq 2 ]; then
fi
%changelog
* Thu Feb 13 2025 Maurizio Lombardi <mlombard@redhat.com> - 2.11-5
- Fix for RHEL-10433
* Fri Jan 24 2025 Maurizio Lombardi <mlombard@redhat.com> - 2.11-4
- Add kernel-headers to BuildRequires (RHEL-70856)
* Thu Jan 16 2025 Maurizio Lombardi <mlombard@redhat.com> - 2.11-3
- NetApp fixes for RHEL-71521
* Fri Nov 15 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.11-2
- Rebuild for RHEL-67144
* Tue Nov 12 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.11-1
- Update to version v2.11 RHEL-67144
* Mon Oct 07 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.10.2-1
- Update to version 2.10.2 RHEL-60536
* Thu Aug 22 2024 Tomas Bzatek <tbzatek@redhat.com> - 2.9.1-6
- Install NetworkManager override for nbft interfaces
- Rename reconnect NetworkManager hook to 99-nvme-nbft-connect.sh