import CS libnvme-1.4-7.el9

This commit is contained in:
eabdullin 2023-09-21 19:10:39 +00:00
parent c9468c5411
commit 12f0921500
13 changed files with 2864 additions and 43 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/libnvme-1.2.tar.gz SOURCES/libnvme-1.4.tar.gz

View File

@ -1 +1 @@
32d5f81b7af835e5596cb390f7dd2ac889414e1d SOURCES/libnvme-1.2.tar.gz 1708e8659912cb695c3ac618a28518027f5833db SOURCES/libnvme-1.4.tar.gz

View File

@ -0,0 +1,399 @@
From d123131f2e542e5a4c046cb65a68fc1fb97ea384 Mon Sep 17 00:00:00 2001
From: Daniel Wagner <dwagner@suse.de>
Date: Wed, 12 Apr 2023 11:59:45 +0200
Subject: [PATCH] fabrics: Do not pass unsupported options to kernel
The kernel API might not support all options libnvme is supporting.
Filter out all options which the kernel doesn't support.
Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
src/nvme/fabrics.c | 216 ++++++++++++++++++++++++++++++++++++++-------
src/nvme/private.h | 33 +++++++
src/nvme/tree.c | 1 +
3 files changed, 220 insertions(+), 30 deletions(-)
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index 3c32e27..f9c26fe 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -30,6 +30,7 @@
#include <ccan/endian/endian.h>
#include <ccan/list/list.h>
#include <ccan/array_size/array_size.h>
+#include <ccan/str/str.h>
#include "fabrics.h"
#include "linux.h"
@@ -261,7 +262,7 @@ void nvmf_update_config(nvme_ctrl_t c, const struct nvme_fabrics_config *cfg)
UPDATE_CFG_OPTION(ctrl_cfg, cfg, tls, false);
}
-static int add_bool_argument(char **argstr, char *tok, bool arg)
+static int __add_bool_argument(char **argstr, char *tok, bool arg)
{
char *nstr;
@@ -277,7 +278,7 @@ static int add_bool_argument(char **argstr, char *tok, bool arg)
return 0;
}
-static int add_int_argument(char **argstr, char *tok, int arg, bool allow_zero)
+static int __add_int_argument(char **argstr, char *tok, int arg, bool allow_zero)
{
char *nstr;
@@ -293,7 +294,7 @@ static int add_int_argument(char **argstr, char *tok, int arg, bool allow_zero)
return 0;
}
-static int add_int_or_minus_one_argument(char **argstr, char *tok, int arg)
+static int __add_int_or_minus_one_argument(char **argstr, char *tok, int arg)
{
char *nstr;
@@ -309,7 +310,7 @@ static int add_int_or_minus_one_argument(char **argstr, char *tok, int arg)
return 0;
}
-static int add_argument(char **argstr, const char *tok, const char *arg)
+static int __add_argument(char **argstr, const char *tok, const char *arg)
{
char *nstr;
@@ -325,6 +326,71 @@ static int add_argument(char **argstr, const char *tok, const char *arg)
return 0;
}
+#define add_bool_argument(o, argstr, tok, arg) \
+({ \
+ int ret; \
+ if (r->options->tok) { \
+ ret = __add_bool_argument(argstr, \
+ stringify(tok), \
+ arg); \
+ } else { \
+ nvme_msg(r, LOG_DEBUG, \
+ "option \"%s\" ignored\n", \
+ stringify(tok)); \
+ ret = 0; \
+ } \
+ ret; \
+})
+
+#define add_int_argument(o, argstr, tok, arg, allow_zero) \
+({ \
+ int ret; \
+ if (r->options->tok) { \
+ ret = __add_int_argument(argstr, \
+ stringify(tok), \
+ arg, \
+ allow_zero); \
+ } else { \
+ nvme_msg(r, LOG_DEBUG, \
+ "option \"%s\" ignored\n", \
+ stringify(tok)); \
+ ret = 0; \
+ } \
+ ret; \
+})
+
+#define add_int_or_minus_one_argument(o, argstr, tok, arg) \
+({ \
+ int ret; \
+ if (r->options->tok) { \
+ ret = __add_int_or_minus_one_argument(argstr, \
+ stringify(tok), \
+ arg); \
+ } else { \
+ nvme_msg(r, LOG_DEBUG, \
+ "option \"%s\" ignored\n", \
+ stringify(tok)); \
+ ret = 0; \
+ } \
+ ret; \
+})
+
+#define add_argument(r, argstr, tok, arg) \
+({ \
+ int ret; \
+ if (r->options->tok) { \
+ ret = __add_argument(argstr, \
+ stringify(tok), \
+ arg); \
+ } else { \
+ nvme_msg(r, LOG_NOTICE, \
+ "option \"%s\" ignored\n", \
+ stringify(tok)); \
+ ret = 0; \
+ } \
+ ret; \
+})
+
static int inet4_pton(const char *src, uint16_t port,
struct sockaddr_storage *addr)
{
@@ -453,6 +519,7 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr)
const char *transport = nvme_ctrl_get_transport(c);
const char *hostnqn, *hostid, *hostkey, *ctrlkey;
bool discover = false, discovery_nqn = false;
+ nvme_root_t r = h->r;
if (!transport) {
nvme_msg(h->r, LOG_ERR, "need a transport (-t) argument\n");
@@ -487,60 +554,60 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr)
if (!hostkey)
hostkey = nvme_ctrl_get_dhchap_host_key(c);
ctrlkey = nvme_ctrl_get_dhchap_key(c);
- if (add_argument(argstr, "transport", transport) ||
- add_argument(argstr, "traddr",
+ if (add_argument(r, argstr, transport, transport) ||
+ add_argument(r, argstr, traddr,
nvme_ctrl_get_traddr(c)) ||
- add_argument(argstr, "host_traddr",
+ add_argument(r, argstr, host_traddr,
cfg->host_traddr) ||
- add_argument(argstr, "host_iface",
+ add_argument(r, argstr, host_iface,
cfg->host_iface) ||
- add_argument(argstr, "trsvcid",
+ add_argument(r, argstr, trsvcid,
nvme_ctrl_get_trsvcid(c)) ||
- (hostnqn && add_argument(argstr, "hostnqn", hostnqn)) ||
- (hostid && add_argument(argstr, "hostid", hostid)) ||
+ (hostnqn && add_argument(r, argstr, hostnqn, hostnqn)) ||
+ (hostid && add_argument(r, argstr, hostid, hostid)) ||
(discover && !discovery_nqn &&
- add_bool_argument(argstr, "discovery", true)) ||
+ add_bool_argument(r, argstr, discovery, true)) ||
(!discover && hostkey &&
- add_argument(argstr, "dhchap_secret", hostkey)) ||
+ add_argument(r, argstr, dhchap_secret, hostkey)) ||
(!discover && ctrlkey &&
- add_argument(argstr, "dhchap_ctrl_secret", ctrlkey)) ||
+ add_argument(r, argstr, dhchap_ctrl_secret, ctrlkey)) ||
(!discover &&
- add_int_argument(argstr, "nr_io_queues",
+ add_int_argument(r, argstr, nr_io_queues,
cfg->nr_io_queues, false)) ||
(!discover &&
- add_int_argument(argstr, "nr_write_queues",
+ add_int_argument(r, argstr, nr_write_queues,
cfg->nr_write_queues, false)) ||
(!discover &&
- add_int_argument(argstr, "nr_poll_queues",
+ add_int_argument(r, argstr, nr_poll_queues,
cfg->nr_poll_queues, false)) ||
(!discover &&
- add_int_argument(argstr, "queue_size",
+ add_int_argument(r, argstr, queue_size,
cfg->queue_size, false)) ||
- add_int_argument(argstr, "keep_alive_tmo",
+ add_int_argument(r, argstr, keep_alive_tmo,
cfg->keep_alive_tmo, false) ||
- add_int_argument(argstr, "reconnect_delay",
+ add_int_argument(r, argstr, reconnect_delay,
cfg->reconnect_delay, false) ||
(strcmp(transport, "loop") &&
- add_int_or_minus_one_argument(argstr, "ctrl_loss_tmo",
+ add_int_or_minus_one_argument(r, argstr, ctrl_loss_tmo,
cfg->ctrl_loss_tmo)) ||
(strcmp(transport, "loop") &&
- add_int_argument(argstr, "fast_io_fail_tmo",
+ add_int_argument(r, argstr, fast_io_fail_tmo,
cfg->fast_io_fail_tmo, false)) ||
(strcmp(transport, "loop") &&
- add_int_argument(argstr, "tos", cfg->tos, true)) ||
- add_int_argument(argstr, "keyring", cfg->keyring, false) ||
+ add_int_argument(r, argstr, tos, cfg->tos, true)) ||
+ add_int_argument(r, argstr, keyring, cfg->keyring, false) ||
(!strcmp(transport, "tcp") &&
- add_int_argument(argstr, "tls_key", cfg->tls_key, false)) ||
- add_bool_argument(argstr, "duplicate_connect",
+ add_int_argument(r, argstr, tls_key, cfg->tls_key, false)) ||
+ add_bool_argument(r, argstr, duplicate_connect,
cfg->duplicate_connect) ||
- add_bool_argument(argstr, "disable_sqflow",
+ add_bool_argument(r, argstr, disable_sqflow,
cfg->disable_sqflow) ||
(!strcmp(transport, "tcp") &&
- add_bool_argument(argstr, "hdr_digest", cfg->hdr_digest)) ||
+ add_bool_argument(r, argstr, hdr_digest, cfg->hdr_digest)) ||
(!strcmp(transport, "tcp") &&
- add_bool_argument(argstr, "data_digest", cfg->data_digest)) ||
+ add_bool_argument(r, argstr, data_digest, cfg->data_digest)) ||
(!strcmp(transport, "tcp") &&
- add_bool_argument(argstr, "tls", cfg->tls))) {
+ add_bool_argument(r, argstr, tls, cfg->tls))) {
free(*argstr);
return -1;
}
@@ -548,6 +615,92 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr)
return 0;
}
+#define parse_option(r, v, name) \
+ if (!strcmp(v, stringify(name))) { \
+ r->options->name = true; \
+ continue; \
+ }
+
+static int __nvmf_supported_options(nvme_root_t r)
+{
+ char buf[0x1000], *options, *p, *v;
+ int fd, ret;
+ size_t len;
+
+ if (r->options)
+ return 0;
+
+ r->options = calloc(1, sizeof(*r->options));
+ if (!r->options)
+ return -ENOMEM;
+
+ fd = open(nvmf_dev, O_RDONLY);
+ if (fd < 0) {
+ nvme_msg(r, LOG_ERR, "Failed to open %s: %s\n",
+ nvmf_dev, strerror(errno));
+ return -ENVME_CONNECT_OPEN;
+ }
+
+ memset(buf, 0x0, sizeof(buf));
+ len = read(fd, buf, sizeof(buf) - 1);
+ if (len < 0) {
+ nvme_msg(r, LOG_ERR, "Failed to read from %s: %s\n",
+ nvmf_dev, strerror(errno));
+ ret = -ENVME_CONNECT_READ;
+ goto out_close;
+ }
+
+ buf[len] = '\0';
+ options = buf;
+
+ nvme_msg(r, LOG_DEBUG, "kernel supports: ");
+
+ while ((p = strsep(&options, ",\n")) != NULL) {
+ if (!*p)
+ continue;
+ v = strsep(&p, "= ");
+ if (!v)
+ continue;
+ nvme_msg(r, LOG_DEBUG, "%s ", v);
+
+ parse_option(r, v, cntlid);
+ parse_option(r, v, ctrl_loss_tmo);
+ parse_option(r, v, data_digest);
+ parse_option(r, v, dhchap_ctrl_secret);
+ parse_option(r, v, dhchap_secret);
+ parse_option(r, v, disable_sqflow);
+ parse_option(r, v, discovery);
+ parse_option(r, v, duplicate_connect);
+ parse_option(r, v, fast_io_fail_tmo);
+ parse_option(r, v, hdr_digest);
+ parse_option(r, v, host_iface);
+ parse_option(r, v, host_traddr);
+ parse_option(r, v, hostid);
+ parse_option(r, v, hostnqn);
+ parse_option(r, v, instance);
+ parse_option(r, v, keep_alive_tmo);
+ parse_option(r, v, keyring);
+ parse_option(r, v, nqn);
+ parse_option(r, v, nr_io_queues);
+ parse_option(r, v, nr_poll_queues);
+ parse_option(r, v, nr_write_queues);
+ parse_option(r, v, queue_size);
+ parse_option(r, v, reconnect_delay);
+ parse_option(r, v, tls);
+ parse_option(r, v, tls_key);
+ parse_option(r, v, tos);
+ parse_option(r, v, traddr);
+ parse_option(r, v, transport);
+ parse_option(r, v, trsvcid);
+ }
+ nvme_msg(r, LOG_DEBUG, "\n");
+ ret = 0;
+
+out_close:
+ close(fd);
+ return ret;
+}
+
static int __nvmf_add_ctrl(nvme_root_t r, const char *argstr)
{
int ret, fd, len = strlen(argstr);
@@ -671,6 +824,9 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c,
free(traddr);
}
+ ret = __nvmf_supported_options(h->r);
+ if (ret)
+ return ret;
ret = build_options(h, c, &argstr);
if (ret)
return ret;
diff --git a/src/nvme/private.h b/src/nvme/private.h
index a6ded21..47ce7ca 100644
--- a/src/nvme/private.h
+++ b/src/nvme/private.h
@@ -120,6 +120,38 @@ struct nvme_host {
* value */
};
+struct nvme_fabric_options {
+ bool cntlid;
+ bool ctrl_loss_tmo;
+ bool data_digest;
+ bool dhchap_ctrl_secret;
+ bool dhchap_secret;
+ bool disable_sqflow;
+ bool discovery;
+ bool duplicate_connect;
+ bool fast_io_fail_tmo;
+ bool hdr_digest;
+ bool host_iface;
+ bool host_traddr;
+ bool hostid;
+ bool hostnqn;
+ bool instance;
+ bool keep_alive_tmo;
+ bool keyring;
+ bool nqn;
+ bool nr_io_queues;
+ bool nr_poll_queues;
+ bool nr_write_queues;
+ bool queue_size;
+ bool reconnect_delay;
+ bool tls;
+ bool tls_key;
+ bool tos;
+ bool traddr;
+ bool transport;
+ bool trsvcid;
+};
+
struct nvme_root {
char *config_file;
struct list_head hosts;
@@ -130,6 +162,7 @@ struct nvme_root {
bool log_timestamp;
bool modified;
bool mi_probe_enabled;
+ struct nvme_fabric_options *options;
};
int nvme_set_attr(const char *dir, const char *attr, const char *value);
diff --git a/src/nvme/tree.c b/src/nvme/tree.c
index 6b58483..c649408 100644
--- a/src/nvme/tree.c
+++ b/src/nvme/tree.c
@@ -288,6 +288,7 @@ void nvme_free_tree(nvme_root_t r)
{
struct nvme_host *h, *_h;
+ free(r->options);
nvme_for_each_host_safe(r, h, _h)
__nvme_free_host(h);
if (r->config_file)
--
2.31.1

View File

@ -1,33 +0,0 @@
From 78ce3528d00bb433c661fd24672a1b5c6795b59f Mon Sep 17 00:00:00 2001
From: Martin Belanger <martin.belanger@dell.com>
Date: Fri, 18 Nov 2022 10:41:32 -0500
Subject: [PATCH] fabrics: Fix bad UUID size introduced in recent UUID changes
Content-type: text/plain
71c25d1cf741 ("util: Add simple UUID type") introduced a regression in
nvmf_get_tel(). nvmf_get_tel() returns the lenght of the binary
representation. Hence use NVME_UUID_LEN instead.
Signed-off-by: Martin Belanger <martin.belanger@dell.com>
[dwagner: massaged commit message]
Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
src/nvme/fabrics.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index f943090..36bdc2d 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -1127,7 +1127,7 @@ static __u32 nvmf_get_tel(const char *hostsymname)
__u16 len;
/* Host ID is mandatory */
- tel += nvmf_exat_size(NVME_UUID_LEN_STRING);
+ tel += nvmf_exat_size(NVME_UUID_LEN);
/* Symbolic name is optional */
len = hostsymname ? strlen(hostsymname) : 0;
--
2.31.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
From 670ec98ebc986e62267145abb059b66ac5e51380 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Thu, 13 Apr 2023 15:39:28 +0200
Subject: [PATCH] nbft: Move added symbols to LIBNVME_1_5
---
src/libnvme.map | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/libnvme.map b/src/libnvme.map
index 6aa9fd0..28de595 100644
--- a/src/libnvme.map
+++ b/src/libnvme.map
@@ -1,5 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
+LIBNVME_1_5 {
+ global:
+ nvme_nbft_read;
+ nvme_nbft_free;
+};
+
LIBNVME_1_4 {
global:
nvme_lookup_keyring;
@@ -7,8 +13,6 @@ LIBNVME_1_4 {
nvme_lookup_key;
nvme_set_keyring;
nvme_insert_tls_key;
- nvme_nbft_read;
- nvme_nbft_free;
};
LIBNVME_1_3 {
--
2.39.1

View File

@ -0,0 +1,36 @@
From 26e4343c2ba2db7a3c5696bbf61bb87942ac02bb Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Thu, 13 Apr 2023 17:28:42 +0200
Subject: [PATCH] nbft: Fix nbft_ssns_flags endianness test
Missing flags endianness conversion leading to ssns_ext_info
not being parsed on s390x and armhf.
---
src/nvme/nbft.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/nvme/nbft.c b/src/nvme/nbft.c
index f91d21b..940dd8e 100644
--- a/src/nvme/nbft.c
+++ b/src/nvme/nbft.c
@@ -169,7 +169,7 @@ static int read_ssns_exended_info(struct nbft_info *nbft,
"invalid ID in SSNS extended info descriptor");
verify(raw_ssns_ei->version == 1,
"invalid version in SSNS extended info descriptor");
- verify(le16_to_cpu(raw_ssns_ei->ssns_index) == le16_to_cpu(ssns->index),
+ verify(le16_to_cpu(raw_ssns_ei->ssns_index) == ssns->index,
"SSNS index doesn't match extended info descriptor index");
if (!(le32_to_cpu(raw_ssns_ei->flags) & NBFT_SSNS_EXT_INFO_VALID))
@@ -292,7 +292,7 @@ static int read_ssns(struct nbft_info *nbft,
goto fail;
/* SSNS extended info */
- if (raw_ssns->flags & NBFT_SSNS_EXTENDED_INFO_IN_USE) {
+ if (le16_to_cpu(raw_ssns->flags) & NBFT_SSNS_EXTENDED_INFO_IN_USE) {
struct nbft_ssns_ext_info *ssns_extended_info;
if (!get_heap_obj(raw_ssns, ssns_extended_info_desc_obj, 0,
--
2.39.1

View File

@ -0,0 +1,25 @@
From 1617d1a3f42a25a2e99073811174609abcffc34d Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Thu, 13 Apr 2023 18:27:39 +0200
Subject: [PATCH] nbft: Parse the {HOSTID,HOSTNQN}_CONFIGURED flags
---
src/nvme/nbft.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/nvme/nbft.c b/src/nvme/nbft.c
index 940dd8e..c0af2b3 100644
--- a/src/nvme/nbft.c
+++ b/src/nvme/nbft.c
@@ -560,6 +560,8 @@ static int parse_raw_nbft(struct nbft_info *nbft)
nbft->host.id = (unsigned char *) &(host->host_id);
if (get_heap_obj(host, host_nqn_obj, 1, &nbft->host.nqn) != 0)
return -EINVAL;
+ nbft->host.host_id_configured = host->flags & NBFT_HOST_HOSTID_CONFIGURED;
+ nbft->host.host_nqn_configured = host->flags & NBFT_HOST_HOSTNQN_CONFIGURED;
/*
* HFI
--
2.39.1

View File

@ -0,0 +1,26 @@
From 00b48dd3c217a9271c1888e8dbeb4aa9d307e5bf Mon Sep 17 00:00:00 2001
From: Martin Belanger <martin.belanger@dell.com>
Date: Thu, 13 Apr 2023 09:27:04 -0400
Subject: [PATCH] nbft: Doc typo - Use nvme_nbft_free() instead of nbft_free()
Signed-off-by: Martin Belanger <martin.belanger@dell.com>
---
src/nvme/nbft.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nvme/nbft.c b/src/nvme/nbft.c
index c0af2b3..a085768 100644
--- a/src/nvme/nbft.c
+++ b/src/nvme/nbft.c
@@ -663,7 +663,7 @@ void nvme_nbft_free(struct nbft_info *nbft)
* @filename: Filename of the raw NBFT table to read.
*
* Read and parse the specified NBFT file into a struct nbft_info.
- * Free with nbft_free().
+ * Free with nvme_nbft_free().
*
* Return: 0 on success, errno otherwise.
*/
--
2.39.1

View File

@ -0,0 +1,64 @@
From 961606f0d0547c3eebd47b79c363ab28c95a94ea Mon Sep 17 00:00:00 2001
From: Martin Belanger <martin.belanger@dell.com>
Date: Fri, 14 Apr 2023 11:19:23 -0400
Subject: [PATCH] NBFT: Remove documentation from nbft.c since it's also in
nbft.h
Also, replace nbft_free() by nvme_nbft_free() in documentation
found in nbft.h.
Signed-off-by: Martin Belanger <martin.belanger@dell.com>
---
src/nvme/nbft.c | 15 ---------------
src/nvme/nbft.h | 2 +-
2 files changed, 1 insertion(+), 16 deletions(-)
diff --git a/src/nvme/nbft.c b/src/nvme/nbft.c
index a085768..a1e17cd 100644
--- a/src/nvme/nbft.c
+++ b/src/nvme/nbft.c
@@ -626,10 +626,6 @@ static int parse_raw_nbft(struct nbft_info *nbft)
return 0;
}
-/**
- * nvme_nbft_free() - Free the struct nbft_info and its contents
- * @nbft: Parsed NBFT table data.
- */
void nvme_nbft_free(struct nbft_info *nbft)
{
struct nbft_info_hfi **hfi;
@@ -656,17 +652,6 @@ void nvme_nbft_free(struct nbft_info *nbft)
free(nbft);
}
-/**
- * nvme_nbft_read() - Read and parse contents of an ACPI NBFT table
- *
- * @nbft: Parsed NBFT table data.
- * @filename: Filename of the raw NBFT table to read.
- *
- * Read and parse the specified NBFT file into a struct nbft_info.
- * Free with nvme_nbft_free().
- *
- * Return: 0 on success, errno otherwise.
- */
int nvme_nbft_read(struct nbft_info **nbft, const char *filename)
{
__u8 *raw_nbft = NULL;
diff --git a/src/nvme/nbft.h b/src/nvme/nbft.h
index c3caa85..6012e16 100644
--- a/src/nvme/nbft.h
+++ b/src/nvme/nbft.h
@@ -1223,7 +1223,7 @@ struct nbft_info {
* @filename: Filename of the raw NBFT table to read.
*
* Read and parse the specified NBFT file into a struct nbft_info.
- * Free with nbft_free().
+ * Free with nvme_nbft_free().
*
* Return: 0 on success, errno otherwise.
*/
--
2.39.1

View File

@ -0,0 +1,105 @@
From 4204cb3c79219926f750ede2d7e8b23a3852e72d Mon Sep 17 00:00:00 2001
From: Caleb Sander <csander@purestorage.com>
Date: Fri, 12 May 2023 10:49:46 -0600
Subject: [PATCH] fabrics: check genctr after getting discovery entries
Content-type: text/plain
From the NVMe base spec (version 2.0c, section 5.16.1.23):
If the host reads the Discovery Log Page using multiple Get Log Page
commands the host should ensure that there has not been a change in the
contents of the data. The host should read the Discovery Log Page
contents in order (i.e., with increasing Log Page Offset values) and
then re-read the Generation Counter after the entire log page is
transferred. If the Generation Counter does not match the original value
read, the host should discard the log page read as the entries may be
inconsistent.
nvme_get_log_page() will issue multiple Get Log Page commands
to fetch the discovery log page if it exceeds 4 KB.
Since GENCTR is at the start of the log page, this ordering is possible:
- GENCTR is read by a Get Log Page command for the first 4 KB
- The log page is modified, changing GENCTR
- Other Get Log Page commands read the remainder of the log page
So the check that GENCTR hasn't changed will incorrectly pass,
despite the log page having been modified.
This can lead to inconsistent, missing, or duplicate log page entries.
Ensure a GENCTR update is not missed
by fetching log page header again after all entries.
Also use NVME_LOG_PAGE_PDU_SIZE to match other nvme_get_log_page() calls
instead of hard-coding the 4 KB max transfer length.
And ensure LPO is correctly reset if the log page is read again.
Signed-off-by: Caleb Sander <csander@purestorage.com>
---
src/nvme/fabrics.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index 1762898..eaee29b 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -1036,9 +1036,10 @@ static struct nvmf_discovery_log *nvme_discovery_log(nvme_ctrl_t c,
nvme_msg(r, LOG_DEBUG, "%s: get header (try %d/%d)\n",
name, retries, max_retries);
args->rae = true;
+ args->lpo = 0;
args->len = size;
args->log = log;
- ret = nvme_get_log_page(fd, 4096, args);
+ ret = nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, args);
if (ret) {
nvme_msg(r, LOG_INFO,
"%s: discover try %d/%d failed, error %d\n",
@@ -1065,15 +1066,33 @@ static struct nvmf_discovery_log *nvme_discovery_log(nvme_ctrl_t c,
}
nvme_msg(r, LOG_DEBUG,
- "%s: get header and %" PRIu64
+ "%s: get %" PRIu64
" records (length %d genctr %" PRIu64 ")\n",
name, numrec, size, genctr);
+ args->rae = true;
+ args->lpo = sizeof(struct nvmf_discovery_log);
+ args->len = size - sizeof(struct nvmf_discovery_log);
+ args->log = log->entries;
+ ret = nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, args);
+ if (ret) {
+ nvme_msg(r, LOG_INFO,
+ "%s: discover try %d/%d failed, error %d\n",
+ name, retries, max_retries, errno);
+ goto out_free_log;
+ }
+
+ /*
+ * If the log page was read with multiple Get Log Page commands,
+ * genctr must be checked afterwards to ensure atomicity
+ */
+ nvme_msg(r, LOG_DEBUG, "%s: get header again\n", name);
+
args->rae = false;
- args->len = size;
+ args->lpo = 0;
+ args->len = sizeof(struct nvmf_discovery_log);
args->log = log;
- ret = nvme_get_log_page(fd, 4096, args);
-
+ ret = nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, args);
if (ret) {
nvme_msg(r, LOG_INFO,
"%s: discover try %d/%d failed, error %d\n",
@@ -1088,7 +1107,8 @@ static struct nvmf_discovery_log *nvme_discovery_log(nvme_ctrl_t c,
errno = EAGAIN;
} else if (numrec != le64_to_cpu(log->numrec)) {
nvme_msg(r, LOG_INFO,
- "%s: could only fetch %" PRIu64 " of %" PRIu64 " records\n",
+ "%s: numrec changed unexpectedly "
+ "from %" PRIu64 " to %" PRIu64 "\n",
name, numrec, le64_to_cpu(log->numrec));
errno = EBADSLT;
} else {
--
2.39.3

View File

@ -0,0 +1,49 @@
From 777b52152f8137048b72edc12ad2ae998df4c30a Mon Sep 17 00:00:00 2001
From: Caleb Sander <csander@purestorage.com>
Date: Fri, 12 May 2023 09:43:22 -0600
Subject: [PATCH] ioctl: fix RAE bit on last Get Log Page command
Content-type: text/plain
If nvme_get_log_page() requires multiple Get Log Page commands
because the total log length exceeds the transfer length,
args->rae is overwritten, causing the RAE bit to be set in all commands.
Retrieve the value of args->rae before overwriting it
so the RAE bit is set as requested in the last command.
Fixes: c23dbd4 ("linux: Change nvme_get_log_page to use nvme_get_log_args parm")
Signed-off-by: Caleb Sander <csander@purestorage.com>
---
src/nvme/ioctl.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c
index 6f9d724..b9710b3 100644
--- a/src/nvme/ioctl.c
+++ b/src/nvme/ioctl.c
@@ -434,7 +434,7 @@ int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args)
{
__u64 offset = 0, xfer, data_len = args->len;
__u64 start = args->lpo;
- bool retain = true;
+ bool retain = args->rae;
void *ptr = args->log;
int ret;
@@ -454,13 +454,10 @@ int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args)
* last portion of this log page so the data remains latched
* during the fetch sequence.
*/
- if (offset + xfer == data_len)
- retain = args->rae;
-
args->lpo = start + offset;
args->len = xfer;
args->log = ptr;
- args->rae = retain;
+ args->rae = offset + xfer < data_len || retain;
ret = nvme_get_log(args);
if (ret)
return ret;
--
2.39.3

View File

@ -3,20 +3,31 @@
Name: libnvme Name: libnvme
Summary: Linux-native nvme device management library Summary: Linux-native nvme device management library
Version: 1.2 Version: 1.4
Release: 2%{?dist} Release: 7%{?dist}
License: LGPLv2+ License: LGPLv2+
URL: https://github.com/linux-nvme/libnvme URL: https://github.com/linux-nvme/libnvme
Source0: %{url}/archive/v%{version_no_tilde}/%{name}-%{version_no_tilde}.tar.gz Source0: %{url}/archive/v%{version_no_tilde}/%{name}-%{version_no_tilde}.tar.gz
Patch0: 0001-fabrics-Fix-bad-UUID-size-introduced-in-recent-UUID-.patch Patch0: 0001-fabrics-Do-not-pass-unsupported-options-to-kernel.patch
Patch1: 0002-nbft-add-NBFT-v1.0-table-support.patch
Patch2: 0003-nbft-Move-added-symbols-to-LIBNVME_1_5.patch
Patch3: 0004-nbft-Fix-nbft_ssns_flags-endianness-test.patch
Patch4: 0005-nbft-Parse-the-HOSTID-HOSTNQN-_CONFIGURED-flags.patch
Patch5: 0006-nbft-Doc-typo-Use-nvme_nbft_free-instead-of-nbft_fre.patch
Patch6: 0007-NBFT-Remove-documentation-from-nbft.c-since-it-s-als.patch
Patch7: 0008-fabrics-check-genctr-after-getting-discovery-entries.patch
Patch8: 0009-ioctl-fix-RAE-bit-on-last-Get-Log-Page-command.patch
BuildRequires: gcc gcc-c++ BuildRequires: gcc gcc-c++
BuildRequires: swig BuildRequires: swig
BuildRequires: python3-devel BuildRequires: python3-devel
BuildRequires: meson >= 0.48.0 BuildRequires: meson >= 0.50.0
BuildRequires: json-c-devel >= 0.13 BuildRequires: json-c-devel >= 0.13
BuildRequires: openssl-devel BuildRequires: openssl-devel
BuildRequires: keyutils-libs-devel
Requires: keyutils-libs
%description %description
Provides type definitions for NVMe specification structures, Provides type definitions for NVMe specification structures,
@ -45,7 +56,6 @@ This package contains the reference manual for %{name}.
Summary: Python3 bindings for libnvme Summary: Python3 bindings for libnvme
Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}%{?_isa} = %{version}-%{release}
Provides: python3-nvme = %{version}-%{release} Provides: python3-nvme = %{version}-%{release}
Obsoletes: python3-nvme < 1.0~rc7
%{?python_provide:%python_provide python3-libnvme} %{?python_provide:%python_provide python3-libnvme}
%description -n python3-libnvme %description -n python3-libnvme
@ -55,7 +65,7 @@ This package contains Python bindings for libnvme.
%autosetup -p1 -n %{name}-%{version_no_tilde} %autosetup -p1 -n %{name}-%{version_no_tilde}
%build %build
%meson -Dpython=true -Ddocs=all -Ddocs-build=true -Dhtmldir=%{_pkgdocdir} %meson -Dpython=enabled -Dlibdbus=disabled -Ddocs=all -Ddocs-build=true -Dhtmldir=%{_pkgdocdir}
%meson_build %meson_build
%install %install
@ -71,9 +81,9 @@ mv %{buildroot}/usr/*.rst %{buildroot}%{_pkgdocdir}/
%files %files
%license COPYING ccan/licenses/* %license COPYING ccan/licenses/*
%{_libdir}/libnvme.so.1 %{_libdir}/libnvme.so.1
%{_libdir}/libnvme.so.1.2.0 %{_libdir}/libnvme.so.1.4.0
%{_libdir}/libnvme-mi.so.1 %{_libdir}/libnvme-mi.so.1
%{_libdir}/libnvme-mi.so.1.2.0 %{_libdir}/libnvme-mi.so.1.4.0
%files devel %files devel
%{_libdir}/libnvme.so %{_libdir}/libnvme.so
@ -93,6 +103,27 @@ mv %{buildroot}/usr/*.rst %{buildroot}%{_pkgdocdir}/
%{python3_sitearch}/libnvme/* %{python3_sitearch}/libnvme/*
%changelog %changelog
* Mon Jul 17 2023 John Meneghini <jmeneghi@redhat.com> - 1.4-7
- Fix BZ#2223429
* Mon Jun 05 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-6
- Rebuild for BZ2212307
* Tue May 16 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-5
- Add support to NBFT (BZ2188516)
* Mon May 08 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-4
- Fix BZ#2190206
* Fri May 05 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-3
- Fix Jira RHEL-258
* Thu Apr 06 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-2
- Rebuild the package
* Mon Apr 03 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-1
- Update to version 1.4
* Thu Jan 12 2023 John Meneghini <jmeneghi@redhat.com> - 1.2-2 * Thu Jan 12 2023 John Meneghini <jmeneghi@redhat.com> - 1.2-2
- Fix BZ2158264 - Fix BZ2158264