import CS libnvme-1.6-1.el9

This commit is contained in:
eabdullin 2024-03-28 10:48:36 +00:00
parent 12f0921500
commit 3c73f90106
16 changed files with 339 additions and 2839 deletions

2
.gitignore vendored
View File

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

View File

@ -1 +1 @@
1708e8659912cb695c3ac618a28518027f5833db SOURCES/libnvme-1.4.tar.gz
e4570f82f86ebeda9974a8884b2a74ce82767e7d SOURCES/libnvme-1.6.tar.gz

View File

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

@ -0,0 +1,58 @@
From a2b8e52e46cfd888ac5a48d8ce632bd70a5caa93 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Tue, 10 Oct 2023 18:16:24 +0200
Subject: [PATCH] util: Introduce alloc helper with alignment support
Similar to nvme-cli an alloc helper is needed for a couple
of ioctls sent out during tree scan.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/nvme/private.h | 2 ++
src/nvme/util.c | 13 +++++++++++++
2 files changed, 15 insertions(+)
diff --git a/src/nvme/private.h b/src/nvme/private.h
index 6fb9784a696d..ee9d738bd0af 100644
--- a/src/nvme/private.h
+++ b/src/nvme/private.h
@@ -182,6 +182,8 @@ nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport,
const char *host_iface, const char *trsvcid,
const char *subsysnqn, nvme_ctrl_t p);
+void *__nvme_alloc(size_t len);
+
#if (LOG_FUNCNAME == 1)
#define __nvme_log_func __func__
#else
diff --git a/src/nvme/util.c b/src/nvme/util.c
index 8fe094d55ef8..20679685bc8b 100644
--- a/src/nvme/util.c
+++ b/src/nvme/util.c
@@ -7,6 +7,7 @@
* Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
*/
+#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
@@ -1058,3 +1059,15 @@ bool nvme_iface_primary_addr_matches(const struct ifaddrs *iface_list, const cha
}
#endif /* HAVE_NETDB */
+
+void *__nvme_alloc(size_t len)
+{
+ size_t _len = round_up(len, 0x1000);
+ void *p;
+
+ if (posix_memalign((void *)&p, getpagesize(), _len))
+ return NULL;
+
+ memset(p, 0, _len);
+ return p;
+}
--
2.39.3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
From 68c6ffb11d40a427fc1fd70ac2ac97fd01952913 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Tue, 10 Oct 2023 18:18:38 +0200
Subject: [PATCH] tree: Allocate aligned payloads for ns scan
libnvme is actually doing some namespace identification
during tree scan, leading to stack smash on some systems.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/nvme/tree.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/src/nvme/tree.c b/src/nvme/tree.c
index 00cf96f7b458..5636aa1809ec 100644
--- a/src/nvme/tree.c
+++ b/src/nvme/tree.c
@@ -2404,26 +2404,33 @@ static void nvme_ns_parse_descriptors(struct nvme_ns *n,
static int nvme_ns_init(struct nvme_ns *n)
{
- struct nvme_id_ns ns = { };
- uint8_t buffer[NVME_IDENTIFY_DATA_SIZE] = { };
- struct nvme_ns_id_desc *descs = (void *)buffer;
+ struct nvme_id_ns *ns;
+ struct nvme_ns_id_desc *descs;
uint8_t flbas;
int ret;
- ret = nvme_ns_identify(n, &ns);
- if (ret)
+ ns = __nvme_alloc(sizeof(*ns));
+ if (!ns)
+ return 0;
+ ret = nvme_ns_identify(n, ns);
+ if (ret) {
+ free(ns);
return ret;
+ }
- nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbas);
- n->lba_shift = ns.lbaf[flbas].ds;
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &flbas);
+ n->lba_shift = ns->lbaf[flbas].ds;
n->lba_size = 1 << n->lba_shift;
- n->lba_count = le64_to_cpu(ns.nsze);
- n->lba_util = le64_to_cpu(ns.nuse);
- n->meta_size = le16_to_cpu(ns.lbaf[flbas].ms);
+ n->lba_count = le64_to_cpu(ns->nsze);
+ n->lba_util = le64_to_cpu(ns->nuse);
+ n->meta_size = le16_to_cpu(ns->lbaf[flbas].ms);
- if (!nvme_ns_identify_descs(n, descs))
+ descs = __nvme_alloc(NVME_IDENTIFY_DATA_SIZE);
+ if (descs && !nvme_ns_identify_descs(n, descs))
nvme_ns_parse_descriptors(n, descs);
+ free(ns);
+ free(descs);
return 0;
}
--
2.39.3

View File

@ -0,0 +1,122 @@
From 3bf6e153a1c02b1c684ac3f5949cd32dec5f46c9 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Thu, 12 Oct 2023 18:42:34 +0200
Subject: [PATCH] linux: Allocate aligned payloads for id_ctrl and id_ns calls
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/nvme/linux.c | 61 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 43 insertions(+), 18 deletions(-)
diff --git a/src/nvme/linux.c b/src/nvme/linux.c
index adbc4cdbd5f6..66be9eb81722 100644
--- a/src/nvme/linux.c
+++ b/src/nvme/linux.c
@@ -124,28 +124,37 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset,
int nvme_get_telemetry_max(int fd, enum nvme_telemetry_da *da, size_t *data_tx)
{
- struct nvme_id_ctrl id_ctrl;
- int err = nvme_identify_ctrl(fd, &id_ctrl);
+ struct nvme_id_ctrl *id_ctrl;
+ int err;
- if (err)
+ id_ctrl = __nvme_alloc(sizeof(*id_ctrl));
+ if (!id_ctrl) {
+ errno = ENOMEM;
+ return -1;
+ }
+ err = nvme_identify_ctrl(fd, id_ctrl);
+ if (err) {
+ free(id_ctrl);
return err;
+ }
if (data_tx) {
- *data_tx = id_ctrl.mdts;
- if (id_ctrl.mdts) {
+ *data_tx = id_ctrl->mdts;
+ if (id_ctrl->mdts) {
/* assuming CAP.MPSMIN is zero minimum Memory Page Size is at least
* 4096 bytes
*/
- *data_tx = (1 << id_ctrl.mdts) * 4096;
+ *data_tx = (1 << id_ctrl->mdts) * 4096;
}
}
if (da) {
- if (id_ctrl.lpa & 0x8)
+ if (id_ctrl->lpa & 0x8)
*da = NVME_TELEMETRY_DA_3;
- if (id_ctrl.lpa & 0x40)
+ if (id_ctrl->lpa & 0x40)
*da = NVME_TELEMETRY_DA_4;
}
+ free(id_ctrl);
return err;
}
@@ -376,32 +385,48 @@ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
int nvme_get_ana_log_len(int fd, size_t *analen)
{
- struct nvme_id_ctrl ctrl;
+ struct nvme_id_ctrl *ctrl;
int ret;
- ret = nvme_identify_ctrl(fd, &ctrl);
- if (ret)
+ ctrl = __nvme_alloc(sizeof(*ctrl));
+ if (!ctrl) {
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = nvme_identify_ctrl(fd, ctrl);
+ if (ret) {
+ free(ctrl);
return ret;
+ }
*analen = sizeof(struct nvme_ana_log) +
- le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) +
- le32_to_cpu(ctrl.mnan) * sizeof(__le32);
+ le32_to_cpu(ctrl->nanagrpid) * sizeof(struct nvme_ana_group_desc) +
+ le32_to_cpu(ctrl->mnan) * sizeof(__le32);
+ free(ctrl);
return 0;
}
int nvme_get_logical_block_size(int fd, __u32 nsid, int *blksize)
{
- struct nvme_id_ns ns;
+ struct nvme_id_ns *ns;
__u8 flbas;
int ret;
- ret = nvme_identify_ns(fd, nsid, &ns);
- if (ret)
+ ns = __nvme_alloc(sizeof(*ns));
+ if (!ns) {
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = nvme_identify_ns(fd, nsid, ns);
+ if (ret) {
+ free(ns);
return ret;
+ }
- nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbas);
- *blksize = 1 << ns.lbaf[flbas].ds;
+ nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &flbas);
+ *blksize = 1 << ns->lbaf[flbas].ds;
+ free(ns);
return 0;
}
--
2.39.3

View File

@ -1,37 +0,0 @@
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,80 @@
From da8c28e5e220be4742442114252d136097056928 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Thu, 12 Oct 2023 18:43:16 +0200
Subject: [PATCH] fabrics: Allocate aligned payloads for id_ctrl and discovery
log calls
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/nvme/fabrics.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index 21fb29200b4b..2e48ac869679 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -1073,7 +1073,7 @@ static struct nvmf_discovery_log *nvme_discovery_log(nvme_ctrl_t c,
size = sizeof(struct nvmf_discovery_log);
free(log);
- log = calloc(1, size);
+ log = __nvme_alloc(size);
if (!log) {
nvme_msg(r, LOG_ERR,
"could not allocate memory for discovery log header\n");
@@ -1105,7 +1105,7 @@ static struct nvmf_discovery_log *nvme_discovery_log(nvme_ctrl_t c,
sizeof(struct nvmf_disc_log_entry) * numrec;
free(log);
- log = calloc(1, size);
+ log = __nvme_alloc(size);
if (!log) {
nvme_msg(r, LOG_ERR,
"could not alloc memory for discovery log page\n");
@@ -1709,26 +1709,35 @@ static const char *dctype_str[] = {
*/
static int nvme_fetch_cntrltype_dctype_from_id(nvme_ctrl_t c)
{
- struct nvme_id_ctrl id = { 0 };
+ struct nvme_id_ctrl *id;
int ret;
- ret = nvme_ctrl_identify(c, &id);
- if (ret)
+ id = __nvme_alloc(sizeof(*id));
+ if (!id) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = nvme_ctrl_identify(c, id);
+ if (ret) {
+ free(id);
return ret;
+ }
if (!c->cntrltype) {
- if (id.cntrltype > NVME_CTRL_CNTRLTYPE_ADMIN || !cntrltype_str[id.cntrltype])
+ if (id->cntrltype > NVME_CTRL_CNTRLTYPE_ADMIN || !cntrltype_str[id->cntrltype])
c->cntrltype = strdup("reserved");
else
- c->cntrltype = strdup(cntrltype_str[id.cntrltype]);
+ c->cntrltype = strdup(cntrltype_str[id->cntrltype]);
}
- if (!c->dctype) {
- if (id.dctype > NVME_CTRL_DCTYPE_CDC || !dctype_str[id.dctype])
+ if (!c->dctype) {
+ if (id->dctype > NVME_CTRL_DCTYPE_CDC || !dctype_str[id->dctype])
c->dctype = strdup("reserved");
else
- c->dctype = strdup(dctype_str[id.dctype]);
+ c->dctype = strdup(dctype_str[id->dctype]);
}
+ free(id);
return 0;
}
--
2.39.3

View File

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

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

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

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

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

@ -1,49 +0,0 @@
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,21 +3,16 @@
Name: libnvme
Summary: Linux-native nvme device management library
Version: 1.4
Release: 7%{?dist}
License: LGPLv2+
Version: 1.6
Release: 1%{?dist}
License: LGPL-2.1-or-later
URL: https://github.com/linux-nvme/libnvme
Source0: %{url}/archive/v%{version_no_tilde}/%{name}-%{version_no_tilde}.tar.gz
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
Patch0: 0001-util-Introduce-alloc-helper-with-alignment-support.patch
Patch1: 0002-tree-Allocate-aligned-payloads-for-ns-scan.patch
Patch2: 0003-linux-Allocate-aligned-payloads-for-id_ctrl-and-id_n.patch
Patch3: 0004-fabrics-Allocate-aligned-payloads-for-id_ctrl-and-di.patch
BuildRequires: gcc gcc-c++
BuildRequires: swig
@ -81,9 +76,9 @@ mv %{buildroot}/usr/*.rst %{buildroot}%{_pkgdocdir}/
%files
%license COPYING ccan/licenses/*
%{_libdir}/libnvme.so.1
%{_libdir}/libnvme.so.1.4.0
%{_libdir}/libnvme.so.1.6.0
%{_libdir}/libnvme-mi.so.1
%{_libdir}/libnvme-mi.so.1.4.0
%{_libdir}/libnvme-mi.so.1.6.0
%files devel
%{_libdir}/libnvme.so
@ -103,6 +98,9 @@ mv %{buildroot}/usr/*.rst %{buildroot}%{_pkgdocdir}/
%{python3_sitearch}/libnvme/*
%changelog
* Fri Nov 03 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.6-1
- Update to version 1.6, including the stack-smashing fixes
* Mon Jul 17 2023 John Meneghini <jmeneghi@redhat.com> - 1.4-7
- Fix BZ#2223429