import CS nvme-cli-2.9.1-6.el9

This commit is contained in:
eabdullin 2024-09-30 16:12:05 +00:00
parent c339663693
commit 79384b8760
13 changed files with 820 additions and 216 deletions

2
.gitignore vendored
View File

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

View File

@ -1 +1 @@
01d2a5755d0d251eafeeefad27e739353f9e0f12 SOURCES/nvme-cli-2.6.tar.gz
33eaae0a2334451553952ac701f8568a52fd2a98 SOURCES/nvme-cli-2.9.1.tar.gz

View File

@ -0,0 +1,20 @@
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

@ -1,29 +0,0 @@
From 0782167f3a6709df232b746cdfa2a036c6207f7f Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Tue, 3 Oct 2023 16:05:23 +0530
Subject: [PATCH] udev-rules: set ctrl_loss_tmo to -1 for ONTAP NVMe/TCP
Setting ctrl_loss_tmo to -1 for ONTAP NVMe/TCP controllers would enable
indefinite reconnect attempts during a path loss and help avoid purging
the path on the host, which otherwise may lead to mounted fs read-only
behavior. So add a rule towards enabling the same.
Signed-off-by: Martin George <marting@netapp.com>
---
nvmf-autoconnect/udev-rules/71-nvmf-iopolicy-netapp.rules.in | 3 +++
1 file changed, 3 insertions(+)
diff --git a/nvmf-autoconnect/udev-rules/71-nvmf-iopolicy-netapp.rules.in b/nvmf-autoconnect/udev-rules/71-nvmf-iopolicy-netapp.rules.in
index 299fe2251418..99b6a8ba0bf8 100644
--- a/nvmf-autoconnect/udev-rules/71-nvmf-iopolicy-netapp.rules.in
+++ b/nvmf-autoconnect/udev-rules/71-nvmf-iopolicy-netapp.rules.in
@@ -1,3 +1,6 @@
# Enable round-robin for NetApp ONTAP and NetApp E-Series
ACTION=="add", SUBSYSTEM=="nvme-subsystem", ATTR{subsystype}=="nvm", ATTR{model}=="NetApp ONTAP Controller", ATTR{iopolicy}="round-robin"
ACTION=="add", SUBSYSTEM=="nvme-subsystem", ATTR{subsystype}=="nvm", ATTR{model}=="NetApp E-Series", ATTR{iopolicy}="round-robin"
+
+# Set ctrl_loss_tmo to -1 for NetApp ONTAP NVMe/TCP
+ACTION!="remove", SUBSYSTEM=="nvme", KERNEL=="nvme*", ATTR{transport}=="tcp", ATTR{model}=="NetApp ONTAP Controller", ATTR{ctrl_loss_tmo}="-1"
--
2.39.3

View File

@ -0,0 +1,76 @@
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

@ -1,50 +0,0 @@
From 748a9ac050fb443b1204d06ce3b5b129b6a8afe2 Mon Sep 17 00:00:00 2001
From: Martin George <marting@netapp.com>
Date: Thu, 5 Oct 2023 12:12:46 +0530
Subject: [PATCH] udev-rules: rename netapp udev rule
Rename 71-nvmf-iopolicy-netapp.rules.in to 71-nvmf-netapp.rules.in
so as to make the name generic, since this not only sets the
iopolicy here but also modifies the ctrl_loss_tmo.
Signed-off-by: Martin George <marting@netapp.com>
---
meson.build | 2 +-
nvme.spec.in | 2 +-
...71-nvmf-iopolicy-netapp.rules.in => 71-nvmf-netapp.rules.in} | 0
3 files changed, 2 insertions(+), 2 deletions(-)
rename nvmf-autoconnect/udev-rules/{71-nvmf-iopolicy-netapp.rules.in => 71-nvmf-netapp.rules.in} (100%)
diff --git a/meson.build b/meson.build
index 3d3fb08541ff..310ba1f83400 100644
--- a/meson.build
+++ b/meson.build
@@ -236,7 +236,7 @@ endforeach
udev_files = [
'70-nvmf-autoconnect.rules',
- '71-nvmf-iopolicy-netapp.rules',
+ '71-nvmf-netapp.rules',
]
foreach file : udev_files
diff --git a/nvme.spec.in b/nvme.spec.in
index fe4675a7bb0b..3eab9ff030ff 100644
--- a/nvme.spec.in
+++ b/nvme.spec.in
@@ -31,7 +31,7 @@ touch %{buildroot}@SYSCONFDIR@/nvme/hostid
@SYSCONFDIR@/nvme/discovery.conf
%ghost @SYSCONFDIR@/nvme/config.json
@UDEVRULESDIR@/70-nvmf-autoconnect.rules
-@UDEVRULESDIR@/71-nvmf-iopolicy-netapp.rules
+@UDEVRULESDIR@/71-nvmf-netapp.rules
@DRACUTRILESDIR@/70-nvmf-autoconnect.conf
@SYSTEMDDIR@/nvmf-connect@.service
@SYSTEMDDIR@/nvmefc-boot-connections.service
diff --git a/nvmf-autoconnect/udev-rules/71-nvmf-iopolicy-netapp.rules.in b/nvmf-autoconnect/udev-rules/71-nvmf-netapp.rules.in
similarity index 100%
rename from nvmf-autoconnect/udev-rules/71-nvmf-iopolicy-netapp.rules.in
rename to nvmf-autoconnect/udev-rules/71-nvmf-netapp.rules.in
--
2.39.3

View File

@ -1,92 +0,0 @@
From 5f872e9c1689078bf2c4e33108c1514da1a91497 Mon Sep 17 00:00:00 2001
From: Maurizio Lombardi <mlombard@redhat.com>
Date: Mon, 13 Nov 2023 10:49:35 +0100
Subject: [PATCH] Revert "fabrics: Use corresponding hostid when hostnqn is
generated"
This reverts commit 7d1c18f581e489e0cedfd9991bc97a2f8239cf82.
---
fabrics.c | 47 ++---------------------------------------------
1 file changed, 2 insertions(+), 45 deletions(-)
diff --git a/fabrics.c b/fabrics.c
index 57ca927fce9a..f4fb63f0c555 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -616,43 +616,6 @@ static int nvme_read_volatile_config(nvme_root_t r)
return ret;
}
-char *nvmf_hostid_from_hostnqn(const char *hostnqn)
-{
- const char *uuid;
-
- if (!hostnqn)
- return NULL;
-
- uuid = strstr(hostnqn, "uuid:");
- if (!uuid)
- return NULL;
-
- return strdup(uuid + strlen("uuid:"));
-}
-
-void nvmf_check_hostid_and_hostnqn(const char *hostid, const char *hostnqn)
-{
- char *hostid_from_file, *hostid_from_hostnqn;
-
- if (!hostid)
- return;
-
- hostid_from_file = nvmf_hostid_from_file();
- if (hostid_from_file && strcmp(hostid_from_file, hostid)) {
- fprintf(stderr, "warning: use generated hostid instead of hostid file\n");
- free(hostid_from_file);
- }
-
- if (!hostnqn)
- return;
-
- hostid_from_hostnqn = nvmf_hostid_from_hostnqn(hostnqn);
- if (hostid_from_hostnqn && strcmp(hostid_from_hostnqn, hostid)) {
- fprintf(stderr, "warning: use hostid which does not match uuid in hostnqn\n");
- free(hostid_from_hostnqn);
- }
-}
-
int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
{
char *subsysnqn = NVME_DISC_SUBSYS_NAME;
@@ -729,13 +692,10 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
hostid_arg = hostid;
if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_from_file();
- if (!hostnqn) {
+ if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_generate();
- hostid = hid = nvmf_hostid_from_hostnqn(hostnqn);
- }
if (!hostid)
hostid = hid = nvmf_hostid_from_file();
- nvmf_check_hostid_and_hostnqn(hostid, hostnqn);
h = nvme_lookup_host(r, hostnqn, hostid);
if (!h) {
ret = ENOMEM;
@@ -946,13 +906,10 @@ int nvmf_connect(const char *desc, int argc, char **argv)
if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_from_file();
- if (!hostnqn) {
+ if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_generate();
- hostid = hid = nvmf_hostid_from_hostnqn(hostnqn);
- }
if (!hostid)
hostid = hid = nvmf_hostid_from_file();
- nvmf_check_hostid_and_hostnqn(hostid, hostnqn);
h = nvme_lookup_host(r, hostnqn, hostid);
if (!h) {
errno = ENOMEM;
--
2.39.3

View File

@ -0,0 +1,63 @@
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

@ -1,29 +0,0 @@
From 2f30d87d5c258fd97f78b0705bb92519d8a2498d Mon Sep 17 00:00:00 2001
From: "da Cunha, Leonardo" <leonardo.da.cunha@solidigm.com>
Date: Wed, 11 Oct 2023 09:01:44 -0700
Subject: [PATCH] nvme: Fixed segmentation fault when getting host initiated
telemetry
Signed-off-by: leonardo.da.cunha <leonardo.da.cunha@solidigm.com>
---
nvme.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/nvme.c b/nvme.c
index b9e56a48f0a5..73d74afdfd73 100644
--- a/nvme.c
+++ b/nvme.c
@@ -851,6 +851,10 @@ static int __get_telemetry_log_host(struct nvme_dev *dev,
_cleanup_free_ struct nvme_telemetry_log *log = NULL;
int err;
+ log = nvme_alloc(sizeof(*log));
+ if (!log)
+ return -errno;
+
err = nvme_cli_get_log_telemetry_host(dev, 0,
NVME_LOG_TELEM_BLOCK_SIZE,
log);
--
2.39.3

View File

@ -0,0 +1,5 @@
#!/bin/bash
if [[ "$1" == nbft* ]] && [[ "$2" == "up" ]]; then
systemctl start nvmf-connect-nbft.service
fi

View File

@ -0,0 +1,15 @@
# Boot from NVMe over TCP (NBFT)
#
# For NVMe/TCP connections that provide namespaces containing rootfs
# it is crucial to react on carrier events and reconnect any missing
# NVMe/TCP connections as defined in the ACPI NBFT table. A custom
# /usr/lib/NetworkManager/dispatcher.d/99-nvme-nbft-connect.sh hook
# will respawn nvmf-connect-nbft.service on such occasion.
[device-nbft-no-ignore-carrier]
# only affects nbft0, nbft1, ... interfaces
match-device=interface-name:nbft*
# react on link up/down events
ignore-carrier=no

View File

@ -0,0 +1,596 @@
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

@ -1,19 +1,24 @@
#%%global commit0 bdbb4da0979fbdc079cf98410cdb31cf799e83b3
#%%global shortcommit0 %%(c=%%{commit0}; echo ${c:0:7})
%global nmlibdir %{_prefix}/lib/NetworkManager
Name: nvme-cli
Version: 2.6
Release: 5%{?dist}
Version: 2.9.1
Release: 6%{?dist}
Summary: NVMe management command line interface
License: GPL-2.0-only
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-udev-rules-set-ctrl_loss_tmo-to-1-for-ONTAP-NVMe-TCP.patch
Patch1: 0002-udev-rules-rename-netapp-udev-rule.patch
Patch2: 0003-Revert-fabrics-Use-corresponding-hostid-when-hostnqn.patch
Patch3: 0004-nvme-Fixed-segmentation-fault-when-getting-host-init.patch
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
BuildRequires: meson >= 0.50.0
BuildRequires: gcc gcc-c++
@ -21,7 +26,7 @@ BuildRequires: libuuid-devel
BuildRequires: systemd-devel
BuildRequires: systemd-rpm-macros
BuildRequires: zlib-devel
BuildRequires: libnvme-devel >= 1.6-1
BuildRequires: libnvme-devel >= 1.9-2
BuildRequires: json-c-devel >= 0.14
BuildRequires: asciidoc
BuildRequires: xmlto
@ -32,13 +37,7 @@ Requires: util-linux
nvme-cli provides NVM-Express user space tooling for Linux.
%prep
#%%setup -qn %%{name}-%%{commit0}
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%autosetup -p1 -n %{name}-%{version}
%build
%meson -Dudevrulesdir=%{_udevrulesdir} -Dsystemddir=%{_unitdir} -Ddocs=all -Ddocs-build=true -Dhtmldir=%{_pkgdocdir}
@ -46,6 +45,10 @@ nvme-cli provides NVM-Express user space tooling for Linux.
%install
%meson_install
mkdir -p $RPM_BUILD_ROOT%{nmlibdir}/dispatcher.d
mkdir -p $RPM_BUILD_ROOT%{nmlibdir}/conf.d
%{__install} -pm 755 %{SOURCE1} $RPM_BUILD_ROOT%{nmlibdir}/dispatcher.d/
%{__install} -pm 644 %{SOURCE2} $RPM_BUILD_ROOT%{nmlibdir}/conf.d/
# Do not install the dracut rule yet. See rhbz 1742764
# Do we want to keep this here? Now that we have boot support for nvme/fc + tcp?
@ -67,13 +70,17 @@ rm -rf %{buildroot}%{_pkgdocdir}/nvme
%config(noreplace) %{_sysconfdir}/nvme/discovery.conf
%{_unitdir}/nvmefc-boot-connections.service
%{_unitdir}/nvmf-autoconnect.service
%{_unitdir}/nvmf-connect-nbft.service
%{_unitdir}/nvmf-connect.target
%{_unitdir}/nvmf-connect@.service
%{_udevrulesdir}/65-persistent-net-nbft.rules
%{_udevrulesdir}/70-nvmf-autoconnect.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?
# /usr/lib/dracut/dracut.conf.d/70-nvmf-autoconnect.conf
%{nmlibdir}/dispatcher.d/99-nvme-nbft-connect.sh
%{nmlibdir}/conf.d/99-nvme-nbft-no-ignore-carrier.conf
%post
if [ $1 -eq 1 ] || [ $1 -eq 2 ]; then
@ -94,6 +101,28 @@ if [ $1 -eq 1 ] || [ $1 -eq 2 ]; then
fi
%changelog
* 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
* Tue Aug 06 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.9.1-5
- Fix RHEL-38372
* Wed Jul 24 2024 Tomas Bzatek <tbzatek@redhat.com> - 2.9.1-4
- Backport NBFT discovery support (RHEL-37601)
* Wed June 19 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.9.1-3
- Fix RHEL-36139
* Tue May 07 2024 Tomas Bzatek <tbzatek@redhat.com> - 2.9.1-2
- Install custom nvmf-connect-nbft.sh NetworkManager hook (RHEL-18912)
* Tue May 07 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.9.1-1
- Update to version 2.9.1
* Wed Apr 03 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.8-1
- Update to version 2.8
* Thu Feb 22 2024 Maurizio Lombardi <mlombard@redhat.com> - 2.6-5
- Fix for RHEL-13107