Compare commits

...

No commits in common. "c9-beta" and "c10s" have entirely different histories.

16 changed files with 1103 additions and 369 deletions

16
.gitignore vendored
View File

@ -1 +1,15 @@
SOURCES/libnvme-1.6.tar.gz
/libnvme-1.0-rc4.tar.gz
/libnvme-1.0-rc5.tar.gz
/libnvme-1.0-rc6.tar.gz
/libnvme-1.0-rc7.tar.gz
/libnvme-1.0-rc8.tar.gz
/libnvme-1.0.tar.gz
/libnvme-1.1-rc0.tar.gz
/libnvme-1.1.tar.gz
/libnvme-1.2.tar.gz
/libnvme-1.3.tar.gz
/libnvme-1.4.tar.gz
/libnvme-1.5.tar.gz
/libnvme-1.6.tar.gz
/libnvme-1.7.1.tar.gz
/libnvme-1.9.tar.gz

View File

@ -1 +0,0 @@
e4570f82f86ebeda9974a8884b2a74ce82767e7d SOURCES/libnvme-1.6.tar.gz

View File

@ -0,0 +1,39 @@
From 849cea06f88790eca5b0407aa4bf9ed94ac6403e Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Thu, 18 Jul 2024 17:23:50 +0200
Subject: [PATCH] linux: Remove the use of OpenSSL Engine API
OpenSSL engines are not FIPS compatible and corresponding API
is deprecated since OpenSSL 3.0. It appears this API is not
actually used in the code, so remove it.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/nvme/linux.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/nvme/linux.c b/src/nvme/linux.c
index 9d472e408b5d..7785416727ed 100644
--- a/src/nvme/linux.c
+++ b/src/nvme/linux.c
@@ -18,7 +18,6 @@
#include <unistd.h>
#ifdef CONFIG_OPENSSL
-#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/kdf.h>
@@ -739,9 +738,6 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac,
_cleanup_hmac_ctx_ HMAC_CTX *hmac_ctx = NULL;
const EVP_MD *md;
- ENGINE_load_builtin_engines();
- ENGINE_register_all_complete();
-
hmac_ctx = HMAC_CTX_new();
if (!hmac_ctx) {
errno = ENOMEM;
--
2.43.0

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# libnvme
The libnvme package

View File

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

View File

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

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

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

@ -0,0 +1,40 @@
From 91f7671ca54a200d652b9b9f34915325313511f5 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Fri, 3 May 2024 17:19:39 +0200
Subject: [PATCH] linux: Fix uninitialized variables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In file included from ../src/nvme/linux.c:40:
In function freep,
inlined from nvme_get_telemetry_log at ../src/nvme/linux.c:169:23:
../src/nvme/cleanup.h:24:9: warning: log may be used uninitialized [-Wmaybe-uninitialized]
24 | free(*(void **)p);
| ^~~~~~~~~~~~~~~~~
../src/nvme/linux.c: In function nvme_get_telemetry_log:
../src/nvme/linux.c:169:30: note: log was declared here
169 | _cleanup_free_ void *log;
| ^~~
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/nvme/linux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nvme/linux.c b/src/nvme/linux.c
index 25196fd5..35976011 100644
--- a/src/nvme/linux.c
+++ b/src/nvme/linux.c
@@ -166,7 +166,7 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, size_t max_
struct nvme_telemetry_log *telem;
enum nvme_cmd_get_log_lid lid;
- _cleanup_free_ void *log;
+ _cleanup_free_ void *log = NULL;
void *tmp;
int err;
size_t dalb;
--
2.44.0

View File

@ -0,0 +1,609 @@
From 6829a6903c7a32a7b4dd32597c7f2a811b5a58bb Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Wed, 17 Apr 2024 18:04:34 +0200
Subject: [PATCH 1/3] fabrics: Introduce simple URI parser
A very simple URI parser implementing URI syntax described
in the Boot Specification, rev. 1.0.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/libnvme.map | 2 +
src/nvme/fabrics.c | 116 +++++++++++++++++++++++++++++++++++++++++++++
src/nvme/fabrics.h | 44 +++++++++++++++++
3 files changed, 162 insertions(+)
diff -up libnvme-1.9/src/libnvme.map.bak libnvme-1.9/src/libnvme.map
--- libnvme-1.9/src/libnvme.map.bak 2024-05-03 14:08:20.000000000 +0200
+++ libnvme-1.9/src/libnvme.map 2024-06-21 15:46:53.920532333 +0200
@@ -10,6 +10,8 @@ LIBNVME_1.9 {
nvme_submit_passthru64;
nvme_update_key;
nvme_ctrl_get_cntlid;
+ nvme_parse_uri;
+ nvme_free_uri;
};
LIBNVME_1_8 {
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index 6738e9dc..324a7321 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -1703,3 +1703,119 @@ int nvmf_register_ctrl(nvme_ctrl_t c, enum nvmf_dim_tas tas, __u32 *result)
*/
return nvmf_dim(c, tas, NVMF_TRTYPE_TCP, nvme_get_adrfam(c), "", NULL, result);
}
+
+struct nvme_fabrics_uri *nvme_parse_uri(const char *str)
+{
+ struct nvme_fabrics_uri *uri;
+ _cleanup_free_ char *scheme = NULL;
+ _cleanup_free_ char *authority = NULL;
+ _cleanup_free_ char *path = NULL;
+ const char *host;
+ int i;
+
+ /* As defined in Boot Specification rev. 1.0:
+ *
+ * section 1.5.7: NVMe-oF URI Format
+ * nvme+tcp://192.168.1.1:4420/
+ * nvme+tcp://[FE80::1010]:4420/
+ *
+ * section 3.1.2.5.3: DHCP Root-Path - a hierarchical NVMe-oF URI Format
+ * NVME<+PROTOCOL>://<SERVERNAME/IP>[:TRANSPORT PORT]/<SUBSYS NQN>/<NID>
+ * or
+ * NVME<+PROTOCOL>://<DISCOVERY CONTROLLER ADDRESS>[:DISCOVERY-
+ * -CONTROLLER PORT]/NQN.2014-08.ORG.NVMEXPRESS.DISCOVERY/<NID>
+ */
+
+ /* TODO: unescape? */
+
+ uri = calloc(1, sizeof(struct nvme_fabrics_uri));
+ if (!uri)
+ return NULL;
+
+ if (sscanf(str, "%m[^:/]://%m[^/?#]%ms",
+ &scheme, &authority, &path) < 2) {
+ nvme_free_uri(uri);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (sscanf(scheme, "%m[^+]+%ms",
+ &uri->scheme, &uri->protocol) < 1) {
+ nvme_free_uri(uri);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* split userinfo */
+ host = strrchr(authority, '@');
+ if (host) {
+ host++;
+ uri->userinfo = strndup(authority, host - authority);
+ } else
+ host = authority;
+
+ /* try matching IPv6 address first */
+ if (sscanf(host, "[%m[^]]]:%d",
+ &uri->host, &uri->port) < 1)
+ /* treat it as IPv4/hostname */
+ if (sscanf(host, "%m[^:]:%d",
+ &uri->host, &uri->port) < 1) {
+ nvme_free_uri(uri);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* split path into elements */
+ if (path) {
+ char *e, *elem;
+
+ /* separate the fragment */
+ e = strrchr(path, '#');
+ if (e) {
+ uri->fragment = strdup(e + 1);
+ *e = '\0';
+ }
+ /* separate the query string */
+ e = strrchr(path, '?');
+ if (e) {
+ uri->query = strdup(e + 1);
+ *e = '\0';
+ }
+
+ /* count elements first */
+ for (i = 0, e = path; *e; e++)
+ if (*e == '/' && *(e + 1) != '/')
+ i++;
+ uri->path_segments = calloc(i + 2, sizeof(char *));
+
+ i = 0;
+ elem = strtok_r(path, "/", &e);
+ if (elem)
+ uri->path_segments[i++] = strdup(elem);
+ while (elem && strlen(elem)) {
+ elem = strtok_r(NULL, "/", &e);
+ if (elem)
+ uri->path_segments[i++] = strdup(elem);
+ }
+ }
+
+ return uri;
+}
+
+void nvme_free_uri(struct nvme_fabrics_uri *uri)
+{
+ char **s;
+
+ if (!uri)
+ return;
+ free(uri->scheme);
+ free(uri->protocol);
+ free(uri->userinfo);
+ free(uri->host);
+ for (s = uri->path_segments; s && *s; s++)
+ free(*s);
+ free(uri->path_segments);
+ free(uri->query);
+ free(uri->fragment);
+ free(uri);
+}
diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h
index 4ebeb35e..3be35310 100644
--- a/src/nvme/fabrics.h
+++ b/src/nvme/fabrics.h
@@ -67,6 +67,28 @@ struct nvme_fabrics_config {
bool concat;
};
+/**
+ * struct nvme_fabrics_uri - Parsed URI structure
+ * @scheme: Scheme name (typically 'nvme')
+ * @protocol: Optional protocol/transport (e.g. 'tcp')
+ * @userinfo: Optional user information component of the URI authority
+ * @host: Host transport address
+ * @port: The port subcomponent or 0 if not specified
+ * @path_segments: NULL-terminated array of path segments
+ * @query: Optional query string component (separated by '?')
+ * @fragment: Optional fragment identifier component (separated by '#')
+ */
+struct nvme_fabrics_uri {
+ char *scheme;
+ char *protocol;
+ char *userinfo;
+ char *host;
+ int port;
+ char **path_segments;
+ char *query;
+ char *fragment;
+};
+
/**
* nvmf_trtype_str() - Decode TRTYPE field
* @trtype: value to be decoded
@@ -324,4 +346,26 @@ bool nvmf_is_registration_supported(nvme_ctrl_t c);
*/
int nvmf_register_ctrl(nvme_ctrl_t c, enum nvmf_dim_tas tas, __u32 *result);
+/**
+ * nvme_parse_uri() - Parse the URI string
+ * @str: URI string
+ *
+ * Parse the URI string as defined in the NVM Express Boot Specification.
+ * Supported URI elements looks as follows:
+ *
+ * nvme+tcp://user@host:port/subsys_nqn/nid?query=val#fragment
+ *
+ * Return: &nvme_fabrics_uri structure on success; NULL on failure with errno
+ * set.
+ */
+struct nvme_fabrics_uri *nvme_parse_uri(const char *str);
+
+/**
+ * nvme_free_uri() - Free the URI structure
+ * @uri: &nvme_fabrics_uri structure
+ *
+ * Free an &nvme_fabrics_uri structure.
+ */
+void nvme_free_uri(struct nvme_fabrics_uri *uri);
+
#endif /* _LIBNVME_FABRICS_H */
From 27ea060ef42c76ed1c88d92c435b88b481e7defb Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Wed, 17 Apr 2024 18:06:23 +0200
Subject: [PATCH 2/3] tests: Add uriparser tests
Simple testcase both for valid and malformed URI strings.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
test/meson.build | 9 ++
test/uriparser.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 217 insertions(+)
create mode 100644 test/uriparser.c
diff --git a/test/meson.build b/test/meson.build
index 93e69991..55992df7 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -66,6 +66,15 @@ uuid = executable(
test('uuid', uuid)
+uriparser = executable(
+ 'test-uriparser',
+ ['uriparser.c'],
+ dependencies: libnvme_dep,
+ include_directories: [incdir, internal_incdir]
+)
+
+test('uriparser', uriparser)
+
if conf.get('HAVE_NETDB')
mock_ifaddrs = library(
'mock-ifaddrs',
diff --git a/test/uriparser.c b/test/uriparser.c
new file mode 100644
index 00000000..cf26bfd2
--- /dev/null
+++ b/test/uriparser.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/**
+ * This file is part of libnvme.
+ * Copyright (c) 2024 Tomas Bzatek <tbzatek@redhat.com>
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <ccan/array_size/array_size.h>
+
+#include <libnvme.h>
+#include <nvme/private.h>
+
+struct test_data {
+ const char *uri;
+ /* parsed data */
+ const char *scheme;
+ const char *host;
+ const char *user;
+ const char *proto;
+ int port;
+ const char *path[7];
+ const char *query;
+ const char *frag;
+};
+
+static struct test_data test_data[] = {
+ { "nvme://192.168.1.1", "nvme", "192.168.1.1" },
+ { "nvme://192.168.1.1/", "nvme", "192.168.1.1" },
+ { "nvme://192.168.1.1:1234", "nvme", "192.168.1.1", .port = 1234 },
+ { "nvme://192.168.1.1:1234/", "nvme", "192.168.1.1", .port = 1234 },
+ { "nvme+tcp://192.168.1.1", "nvme", "192.168.1.1", .proto = "tcp" },
+ { "nvme+rdma://192.168.1.1/", "nvme", "192.168.1.1", .proto = "rdma" },
+ { "nvme+tcp://192.168.1.1:1234",
+ "nvme", "192.168.1.1", .proto = "tcp", .port = 1234 },
+ { "nvme+tcp://192.168.1.1:1234/",
+ "nvme", "192.168.1.1", .proto = "tcp", .port = 1234 },
+ { "nvme+tcp://192.168.1.1:4420/path",
+ "nvme", "192.168.1.1", .proto = "tcp", .port = 4420,
+ .path = { "path", NULL }},
+ { "nvme+tcp://192.168.1.1/path/",
+ "nvme", "192.168.1.1", .proto = "tcp", .path = { "path", NULL }},
+ { "nvme+tcp://192.168.1.1:4420/p1/p2/p3",
+ "nvme", "192.168.1.1", .proto = "tcp", .port = 4420,
+ .path = { "p1", "p2", "p3", NULL }},
+ { "nvme+tcp://192.168.1.1:4420/p1/p2/p3/",
+ "nvme", "192.168.1.1", .proto = "tcp", .port = 4420,
+ .path = { "p1", "p2", "p3", NULL }},
+ { "nvme+tcp://192.168.1.1:4420//p1//p2/////p3",
+ "nvme", "192.168.1.1", .proto = "tcp", .port = 4420,
+ .path = { "p1", "p2", "p3", NULL }},
+ { "nvme+tcp://192.168.1.1:4420//p1//p2/////p3/",
+ "nvme", "192.168.1.1", .proto = "tcp", .port = 4420,
+ .path = { "p1", "p2", "p3", NULL }},
+ { "nvme://[fe80::1010]", "nvme", "fe80::1010" },
+ { "nvme://[fe80::1010]/", "nvme", "fe80::1010" },
+ { "nvme://[fe80::1010]:1234", "nvme", "fe80::1010", .port = 1234 },
+ { "nvme://[fe80::1010]:1234/", "nvme", "fe80::1010", .port = 1234 },
+ { "nvme+tcp://[fe80::1010]", "nvme", "fe80::1010", .proto = "tcp" },
+ { "nvme+rdma://[fe80::1010]/", "nvme", "fe80::1010", .proto = "rdma" },
+ { "nvme+tcp://[fe80::1010]:1234",
+ "nvme", "fe80::1010", .proto = "tcp", .port = 1234 },
+ { "nvme+tcp://[fe80::1010]:1234/",
+ "nvme", "fe80::1010", .proto = "tcp", .port = 1234 },
+ { "nvme+tcp://[fe80::1010]:4420/path",
+ "nvme", "fe80::1010", .proto = "tcp", .port = 4420,
+ .path = { "path", NULL }},
+ { "nvme+tcp://[fe80::1010]/path/",
+ "nvme", "fe80::1010", .proto = "tcp", .path = { "path", NULL }},
+ { "nvme+tcp://[fe80::1010]:4420/p1/p2/p3",
+ "nvme", "fe80::1010", .proto = "tcp", .port = 4420,
+ .path = { "p1", "p2", "p3", NULL }},
+ { "nvme+tcp://[fe80::fc7d:8cff:fe5b:962e]:666/p1/p2/p3/",
+ "nvme", "fe80::fc7d:8cff:fe5b:962e", .proto = "tcp", .port = 666,
+ .path = { "p1", "p2", "p3", NULL }},
+ { "nvme://h?query", "nvme", "h", .query = "query" },
+ { "nvme://h/?query", "nvme", "h", .query = "query" },
+ { "nvme://h/x?query",
+ "nvme", "h", .path = { "x" }, .query = "query" },
+ { "nvme://h/p1/?query",
+ "nvme", "h", .path = { "p1" }, .query = "query" },
+ { "nvme://h/p1/x?query",
+ "nvme", "h", .path = { "p1", "x" }, .query = "query" },
+ { "nvme://h#fragment", "nvme", "h", .frag = "fragment" },
+ { "nvme://h/#fragment", "nvme", "h", .frag = "fragment" },
+ { "nvme://h/x#fragment",
+ "nvme", "h", .path = { "x" }, .frag = "fragment" },
+ { "nvme://h/p1/#fragment",
+ "nvme", "h", .path = { "p1" }, .frag = "fragment" },
+ { "nvme://h/p1/x#fragment",
+ "nvme", "h", .path = { "p1", "x" }, .frag = "fragment" },
+ { "nvme://h/?query#fragment",
+ "nvme", "h", .query = "query", .frag = "fragment" },
+ { "nvme://h/x?query#fragment",
+ "nvme", "h", .path = { "x" }, .query = "query", .frag = "fragment" },
+ { "nvme://h/p1/?query#fragment",
+ "nvme", "h", .path = { "p1" }, .query = "query", .frag = "fragment" },
+ { "nvme://h/p1/x?query#fragment",
+ "nvme", "h", .path = { "p1", "x" }, .query = "query",
+ .frag = "fragment" },
+ { "nvme://h/#fragment?query",
+ "nvme", "h", .frag = "fragment?query" },
+ { "nvme://h/x#fragment?query",
+ "nvme", "h", .path = { "x" }, .frag = "fragment?query" },
+ { "nvme://h/p1/#fragment?query",
+ "nvme", "h", .path = { "p1" }, .frag = "fragment?query" },
+ { "nvme://h/p1/x#fragment?query",
+ "nvme", "h", .path = { "p1", "x" }, .frag = "fragment?query" },
+ { "nvme://user@h", "nvme", "h", .user = "user" },
+ { "nvme://user@h/", "nvme", "h", .user = "user" },
+ { "nvme://user:pass@h/", "nvme", "h", .user = "user:pass" },
+ { "nvme://[fe80::1010]@h/", "nvme", "h", .user = "[fe80::1010]" },
+ { "nvme://u[fe80::1010]@h/", "nvme", "h", .user = "u[fe80::1010]" },
+ { "nvme://u[aa:bb::cc]@h/", "nvme", "h", .user = "u[aa:bb::cc]" },
+ { "nvme+rdma://u[aa:bb::cc]@[aa:bb::cc]:12345/p1/x?q=val#fr",
+ "nvme", "aa:bb::cc", .proto = "rdma", .port = 12345,
+ .user = "u[aa:bb::cc]", .path = { "p1", "x" },
+ .query = "q=val", .frag = "fr" },
+};
+
+const char *test_data_bad[] = {
+ "",
+ " ",
+ "nonsense",
+ "vnme:",
+ "vnme:/",
+ "vnme://",
+ "vnme:///",
+ "vnme+foo://",
+ "nvme:hostname/",
+ "nvme:/hostname/",
+ "nvme:///hostname/",
+ "nvme+foo:///hostname/",
+};
+
+static void test_uriparser(void)
+{
+ printf("Testing URI parser:\n");
+ for (int i = 0; i < ARRAY_SIZE(test_data); i++) {
+ const struct test_data *d = &test_data[i];
+ struct nvme_fabrics_uri *parsed_data;
+ char **s;
+ int i;
+
+ printf(" '%s'...", d->uri);
+ parsed_data = nvme_parse_uri(d->uri);
+ assert(parsed_data);
+
+ assert(strcmp(d->scheme, parsed_data->scheme) == 0);
+ if (d->proto) {
+ assert(parsed_data->protocol != NULL);
+ assert(strcmp(d->proto, parsed_data->protocol) == 0);
+ } else
+ assert(d->proto == parsed_data->protocol);
+ assert(strcmp(d->host, parsed_data->host) == 0);
+ assert(d->port == parsed_data->port);
+
+ if (!parsed_data->path_segments)
+ assert(d->path[0] == NULL);
+ else {
+ for (i = 0, s = parsed_data->path_segments;
+ s && *s; s++, i++) {
+ assert(d->path[i] != NULL);
+ assert(strcmp(d->path[i], *s) == 0);
+ }
+ /* trailing NULL element */
+ assert(d->path[i] == parsed_data->path_segments[i]);
+ }
+ if (d->query) {
+ assert(parsed_data->query != NULL);
+ assert(strcmp(d->query, parsed_data->query) == 0);
+ } else
+ assert(d->query == parsed_data->query);
+ if (d->frag) {
+ assert(parsed_data->fragment != NULL);
+ assert(strcmp(d->frag, parsed_data->fragment) == 0);
+ } else
+ assert(d->frag == parsed_data->fragment);
+ nvme_free_uri(parsed_data);
+ printf(" OK\n");
+ }
+}
+
+static void test_uriparser_bad(void)
+{
+ printf("Testing malformed URI strings:\n");
+ for (int i = 0; i < ARRAY_SIZE(test_data_bad); i++) {
+ struct nvme_fabrics_uri *parsed_data;
+
+ printf(" '%s'...", test_data_bad[i]);
+ parsed_data = nvme_parse_uri(test_data_bad[i]);
+ assert(parsed_data == NULL);
+ printf(" OK\n");
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ test_uriparser();
+ test_uriparser_bad();
+
+ fflush(stdout);
+
+ return 0;
+}
From b2044e8f416b54df34e0d162b59ca0745db92927 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Mon, 13 May 2024 17:38:25 +0200
Subject: [PATCH 3/3] fabrics: Unescape URI elements
This adds support for unescaping percent-encoded URI parts.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
---
src/nvme/fabrics.c | 47 +++++++++++++++++++++++++++++++++++++---------
test/uriparser.c | 13 +++++++++++++
2 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index 324a7321..e5921f8b 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -1704,12 +1704,41 @@ int nvmf_register_ctrl(nvme_ctrl_t c, enum nvmf_dim_tas tas, __u32 *result)
return nvmf_dim(c, tas, NVMF_TRTYPE_TCP, nvme_get_adrfam(c), "", NULL, result);
}
+#define IS_XDIGIT(c) ((c >= '0' && c <= '9') || \
+ (c >= 'A' && c <= 'F') || \
+ (c >= 'a' && c <= 'f'))
+#define XDIGIT_VAL(c) ((c >= '0' && c <= '9') ? c - '0' : ( \
+ (c >= 'A' && c <= 'F') ? c - 'A' + 10 : c - 'a' + 10))
+
+/* returns newly allocated string */
+static char *unescape_uri(const char *str, int len)
+{
+ char *dst;
+ int l;
+ int i, j;
+
+ l = len > 0 ? len : strlen(str);
+ dst = malloc(l + 1);
+ for (i = 0, j = 0; i < l; i++, j++) {
+ if (str[i] == '%' && i + 2 < l &&
+ IS_XDIGIT(str[i + 1]) && IS_XDIGIT(str[i + 2])) {
+ dst[j] = (XDIGIT_VAL(str[i + 1]) << 4) +
+ XDIGIT_VAL(str[i + 2]);
+ i += 2;
+ } else
+ dst[j] = str[i];
+ }
+ dst[j] = '\0';
+ return dst;
+}
+
struct nvme_fabrics_uri *nvme_parse_uri(const char *str)
{
struct nvme_fabrics_uri *uri;
_cleanup_free_ char *scheme = NULL;
_cleanup_free_ char *authority = NULL;
_cleanup_free_ char *path = NULL;
+ _cleanup_free_ char *h = NULL;
const char *host;
int i;
@@ -1726,8 +1755,6 @@ struct nvme_fabrics_uri *nvme_parse_uri(const char *str)
* -CONTROLLER PORT]/NQN.2014-08.ORG.NVMEXPRESS.DISCOVERY/<NID>
*/
- /* TODO: unescape? */
-
uri = calloc(1, sizeof(struct nvme_fabrics_uri));
if (!uri)
return NULL;
@@ -1750,20 +1777,22 @@ struct nvme_fabrics_uri *nvme_parse_uri(const char *str)
host = strrchr(authority, '@');
if (host) {
host++;
- uri->userinfo = strndup(authority, host - authority);
+ uri->userinfo = unescape_uri(authority, host - authority);
} else
host = authority;
/* try matching IPv6 address first */
if (sscanf(host, "[%m[^]]]:%d",
- &uri->host, &uri->port) < 1)
+ &uri->host, &uri->port) < 1) {
/* treat it as IPv4/hostname */
if (sscanf(host, "%m[^:]:%d",
- &uri->host, &uri->port) < 1) {
+ &h, &uri->port) < 1) {
nvme_free_uri(uri);
errno = EINVAL;
return NULL;
}
+ uri->host = unescape_uri(h, 0);
+ }
/* split path into elements */
if (path) {
@@ -1772,13 +1801,13 @@ struct nvme_fabrics_uri *nvme_parse_uri(const char *str)
/* separate the fragment */
e = strrchr(path, '#');
if (e) {
- uri->fragment = strdup(e + 1);
+ uri->fragment = unescape_uri(e + 1, 0);
*e = '\0';
}
/* separate the query string */
e = strrchr(path, '?');
if (e) {
- uri->query = strdup(e + 1);
+ uri->query = unescape_uri(e + 1, 0);
*e = '\0';
}
@@ -1791,11 +1820,11 @@ struct nvme_fabrics_uri *nvme_parse_uri(const char *str)
i = 0;
elem = strtok_r(path, "/", &e);
if (elem)
- uri->path_segments[i++] = strdup(elem);
+ uri->path_segments[i++] = unescape_uri(elem, 0);
while (elem && strlen(elem)) {
elem = strtok_r(NULL, "/", &e);
if (elem)
- uri->path_segments[i++] = strdup(elem);
+ uri->path_segments[i++] = unescape_uri(elem, 0);
}
}
diff --git a/test/uriparser.c b/test/uriparser.c
index cf26bfd2..09b2a732 100644
--- a/test/uriparser.c
+++ b/test/uriparser.c
@@ -119,6 +119,19 @@ static struct test_data test_data[] = {
"nvme", "aa:bb::cc", .proto = "rdma", .port = 12345,
.user = "u[aa:bb::cc]", .path = { "p1", "x" },
.query = "q=val", .frag = "fr" },
+ { "nvme://ex%5Cmp%3Ae", "nvme", "ex\\mp:e" },
+ { "nvme://ex%5Cmp%3Ae.com/", "nvme", "ex\\mp:e.com" },
+ { "nvme://u%24er@ex%5Cmp%3Ae.com/", "nvme", "ex\\mp:e.com",
+ .user = "u$er" },
+ { "nvme+tcp://ex%5Cmp%3Ae.com:1234",
+ "nvme", "ex\\mp:e.com", .proto = "tcp", .port = 1234 },
+ { "nvme+tcp://ex%5Cmp%3Ae.com:1234/p1/ex%3Camp%3Ele/p3",
+ "nvme", "ex\\mp:e.com", .proto = "tcp", .port = 1234,
+ .path = { "p1", "ex<amp>le", "p3", NULL } },
+ { "nvme+tcp://ex%5Cmp%3Ae.com:1234/p1/%3C%3E/p3?q%5E%24ry#fr%26gm%23nt",
+ "nvme", "ex\\mp:e.com", .proto = "tcp", .port = 1234,
+ .path = { "p1", "<>", "p3", NULL }, .query = "q^$ry",
+ .frag = "fr&gm#nt" },
};
const char *test_data_bad[] = {

View File

@ -3,26 +3,29 @@
Name: libnvme
Summary: Linux-native nvme device management library
Version: 1.6
Release: 1%{?dist}
Version: 1.9
Release: 4%{?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-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
# https://github.com/linux-nvme/libnvme/pull/833
Patch0: libnvme-1.10-linux-Fix-uninitialized-variables.patch
Patch1: 0002-linux-Remove-the-use-of-OpenSSL-Engine-API.patch
Patch2: libnvme-1.10-uriparser.patch
BuildRequires: gcc gcc-c++
BuildRequires: swig
BuildRequires: python3-devel
BuildRequires: meson >= 0.50.0
BuildRequires: meson >= 0.50
BuildRequires: json-c-devel >= 0.13
BuildRequires: openssl-devel
BuildRequires: dbus-devel
BuildRequires: keyutils-libs-devel
Requires: keyutils-libs
%if 0%{?fedora} || 0%{?rhel} > 9
BuildRequires: kernel-headers >= 5.15
%endif
%description
Provides type definitions for NVMe specification structures,
@ -51,6 +54,7 @@ This package contains the reference manual for %{name}.
Summary: Python3 bindings for libnvme
Requires: %{name}%{?_isa} = %{version}-%{release}
Provides: python3-nvme = %{version}-%{release}
Obsoletes: python3-nvme < 1.0~rc7
%{?python_provide:%python_provide python3-libnvme}
%description -n python3-libnvme
@ -60,7 +64,7 @@ This package contains Python bindings for libnvme.
%autosetup -p1 -n %{name}-%{version_no_tilde}
%build
%meson -Dpython=enabled -Dlibdbus=disabled -Ddocs=all -Ddocs-build=true -Dhtmldir=%{_pkgdocdir}
%meson -Dpython=enabled -Dlibdbus=enabled -Ddocs=all -Ddocs-build=true -Dhtmldir=%{_pkgdocdir}
%meson_build
%install
@ -70,15 +74,16 @@ This package contains Python bindings for libnvme.
mv %{buildroot}%{_pkgdocdir}/nvme/html %{buildroot}%{_pkgdocdir}/html
rm -rf %{buildroot}%{_pkgdocdir}/nvme
mv %{buildroot}/usr/*.rst %{buildroot}%{_pkgdocdir}/
rm -r %{buildroot}%{_pkgdocdir}/html/{.buildinfo,.doctrees/}
%ldconfig_scriptlets
%files
%license COPYING ccan/licenses/*
%{_libdir}/libnvme.so.1
%{_libdir}/libnvme.so.1.6.0
%{_libdir}/libnvme.so.1.9.0
%{_libdir}/libnvme-mi.so.1
%{_libdir}/libnvme-mi.so.1.6.0
%{_libdir}/libnvme-mi.so.1.9.0
%files devel
%{_libdir}/libnvme.so
@ -98,50 +103,81 @@ 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
* Fri Jul 26 2024 Maurizio Lombardi <mlombard@redhat.com> - 1.9-4
- Fix RHEL-37611
* Mon Jul 17 2023 John Meneghini <jmeneghi@redhat.com> - 1.4-7
- Fix BZ#2223429
* Thu Jul 25 2024 Maurizio Lombardi <mlombard@redhat.com> - 1.9-3
- Fix RHEL-46699
* Mon Jun 05 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-6
- Rebuild for BZ2212307
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 1.9-2
- Bump release for June 2024 mass rebuild
* Tue May 16 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-5
- Add support to NBFT (BZ2188516)
* Fri May 03 2024 Tomas Bzatek <tbzatek@redhat.com> - 1.9-1
- Upstream v1.9 release
* Mon May 08 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-4
- Fix BZ#2190206
* Wed Feb 28 2024 Davide Cavalca <dcavalca@fedoraproject.org> - 1.8-2
- Do not package doctrees to make the package build reproducible
* Fri May 05 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-3
- Fix Jira RHEL-258
* Wed Feb 14 2024 Tomas Bzatek <tbzatek@redhat.com> - 1.8-1
- Upstream v1.8 release
* Thu Apr 06 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-2
- Rebuild the package
* Fri Feb 09 2024 Tomas Bzatek <tbzatek@redhat.com> - 1.7.1-4
- nbft: Fix SSNS HFI indexes parsing
- cleanup: Explicitly initialize auto-cleanup variables
* Mon Apr 03 2023 Maurizio Lombardi <mlombard@redhat.com> - 1.4-1
- Update to version 1.4
* Thu Jan 25 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu Jan 12 2023 John Meneghini <jmeneghi@redhat.com> - 1.2-2
- Fix BZ2158264
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Fri Nov 04 2022 Maurizio Lombardi <mlombard@redhat.com> - 1.2-1
- Update to upstream version v1.2
* Thu Dec 28 2023 Tomas Bzatek <tbzatek@redhat.com> - 1.7.1-1
- Upstream v1.7.1 release
* Mon Sep 19 2022 Maurizio Lombardi <mlombard@redhat.com> - 1.1-1
- Update to upstream version v1.1
* Tue Oct 24 2023 Tomas Bzatek <tbzatek@redhat.com> - 1.6-2
- Backport stack smashing fixes (#2245707)
* Fri Jun 24 2022 Maurizio Lombardi <mlombard@redhat.com> - 1.0-5
- Rebuild for RHEL9.1
* Fri Sep 29 2023 Tomas Bzatek <tbzatek@redhat.com> - 1.6-1
- Upstream v1.6 release
* Thu Jun 09 2022 Maurizio Lombardi <mlombard@redhat.com> - 1.0-4
- Add gating tests
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Wed Jun 01 2022 Maurizio Lombardi <mlombard@redhat.com> - 1.0-3
- Rebuild for RHEL 9.1
* Tue Jul 04 2023 Python Maint <python-maint@redhat.com> - 1.5-2
- Rebuilt for Python 3.12
* Wed Apr 27 2022 Maurizio Lombardi <mlombard@redhat.com> - 1.0-2
- Porting to RHEL 9
* Tue Jul 04 2023 Tomas Bzatek <tbzatek@redhat.com> - 1.5-1
- Upstream v1.5 release
* Thu Jun 15 2023 Python Maint <python-maint@redhat.com> - 1.4-3
- Rebuilt for Python 3.12
* Thu Apr 20 2023 Tomas Bzatek <tbzatek@redhat.com> - 1.4-2
- Backport the NBFT parser from git master
* Mon Apr 03 2023 Tomas Bzatek <tbzatek@redhat.com> - 1.4-1
- Upstream v1.4 release
* Tue Jan 31 2023 Tomas Bzatek <tbzatek@redhat.com> - 1.3-1
- Upstream v1.3 release
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Tue Nov 01 2022 Tomas Bzatek <tbzatek@redhat.com> - 1.2-1
- Upstream v1.2 release
* Fri Aug 05 2022 Tomas Bzatek <tbzatek@redhat.com> - 1.1-1
- Upstream v1.1 release
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.1~rc0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Fri Jul 15 2022 Tomas Bzatek <tbzatek@redhat.com> - 1.1~rc0-1
- Upstream v1.1 Release Candidate 0
* Mon Jun 13 2022 Python Maint <python-maint@redhat.com> - 1.0-2
- Rebuilt for Python 3.11
* Mon Apr 11 2022 Tomas Bzatek <tbzatek@redhat.com> - 1.0-1
- Upstream v1.0 release

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (libnvme-1.9.tar.gz) = 39a3346805143f93a17d00cfcb6fb75f82154658db6079134c09dfa989995ac5de79b1ce1ac091b4e997523d3216829ce9eac44110c9f59f9fd21636529c8b25

272
tests/include/tc.sh Normal file
View File

@ -0,0 +1,272 @@
#!/bin/bash
# Copyright (c) 2016 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Author: Yi Zhang <yizhan@redhat.com>
# filename: function
# USAGE
test x$LXT_TC = x || return
LXT_TC=1
#
# print the current date
# usage: d=$(tdate)
#
tdate ()
{
date '+%T' 2>/dev/null
}
#
# print the log information
# usage: tlog "hello world" "WARNING"
#
tlog ()
{
local msg=$1
local log_level=${2:-INFO}
local cur_date=$(tdate)
echo "[$log_level][$cur_date]$msg"
return 0
}
#
# run the cmd and format the log. return the exitint status of cmd
# use the global variables: tSTDOUT and tSTDERR to return the stdout and stderr
# usage: trun "ls"
# trun "ls"; echo $?
# stdout=$tSTDOUT
# stderr=$tSTDERR
#
trun ()
{
local cmd="$*"
_trun_ "$cmd"
}
#
# verify the execution of command
# if the cmd return 0, mark this checkpoint failed and return 1
# if not, mark it passed and return 0
# usage: tnot "ls /not_existing"
#
tnot () {
local cmd="$*"
_trun_ "$cmd" 1
if test $? -eq 0; then
tfail_ "$cmd" ;
else
tpass_ "$cmd" ;
fi
}
#
# verify the execution of command
# if the cmd return 0, mark this checkpoint passed and return 0
# if not, mark it failed and return 1
# usage: tok "ls /"
#
tok ()
{
local cmd="$*"
_trun_ "$cmd" 0
if test $? -eq 0; then
tpass_ "$cmd" ;
else
tfail_ "$cmd" ;
fi
}
#
# verify the execution of command
# if the cmd return 0, mark this checkpoint passed and return 0
# if not, mark it failes and exit
# usage: terr "ls"
#
#terr ()
#{
# tok "$*" || tend
#}
#
# verify the execution of command
# if the cmd return 0, will continue to run the script
# if not, mark it failes and exit
# usage: terr "ls"
#
terr ()
{
local cmd="$*"
_trun_ "$cmd" 0
if test $? -ne 0; then
tfail_ "$cmd" ;
tend ;
fi
}
#
# exit the program and print the log message
# usage: texit "error message" 100
# similar to the exception
#
texit ()
{
msg=$1
err=$2
is_null $err && err=1
test $err -lt 1 || err=1
tlog "$msg" "ERROR"
exit $2
}
#
# print the test report, cleanup the testing bed and close the testing.
# usage: tend
#
tend ()
{
local pcount=$(wc -l $tPASS_FILE | awk '{print $1}')
local fcount=$(wc -l $tFAIL_FILE | awk '{print $1}')
local total=$(( $pcount + $fcount ))
echo "#################################Test Report###############################"
echo "TOTAL : $total"
echo "PASSED : $pcount"
echo "FAILED : $fcount"
cat $tPASS_FILE $tFAIL_FILE
echo "###########################End of running $0########################"
#cleanup
rm -f $tPASS_FILE $tFAIL_FILE $tRETURN_FILE $tSTDERR_FILE
# rm -rf $LXT_TMP_DIR
if [[ $pcount -eq 0 ]] && [[ $total -eq 0 ]];then
exit 0
fi
test $pcount -eq 0 && exit 1
test $pcount -eq $total && exit 0
exit 1
}
#
# private function
#
#
# print the error message and call stack. return 1
#
tfail_ ()
{
local msg=$*
tlog "$msg" "ERROR" >>$tFAIL_FILE
return 1
}
#
# print the sucessful message. return 0
#
tpass_ ()
{
local msg=$*
tlog "$msg" "PASS" >> $tPASS_FILE
return 0
}
_trun_ ()
{
local cmd="$1"
local chk="$2"
local cur_date=$(tdate)
local stdout=$(eval "$cmd" 2>$tSTDERR_FILE; echo $? >$tRETURN_FILE 2>/dev/null)
#timeout -- how to set timeout?
local exit_status=$(< $tRETURN_FILE)
local stderr=$(< $tSTDERR_FILE)
local msg=CMD
#tnot
if test x$chk = x1; then
test $exit_status -eq 0 || msg=PASS
test $exit_status -eq 0 && msg=FAIL
#should let the tester know this is the negative testing
#if cmd return 0 we will return 1 and vice versa
cmd="[NOT] $cmd"
fi
#tok
if test x$chk = x0; then
test $exit_status -eq 0 && msg=PASS
test $exit_status -eq 0 || msg=FAIL
fi
tSTDOUT=$stdout
tSTDERR=$stderr
test $tIGNORE_STDOUT -eq 1 && stdout='redirect the stdout to /dev/null'
test $tIGNORE_STDERR -eq 1 && stderr='redirect the stderr to /dev/null'
echo "[$msg][$cur_date][$HOSTNAME]$cmd"
echo "STDOUT:"
test "x$stdout" = x || echo "$stdout"
echo "STDERR:$stderr"
echo "RETURN:$exit_status"
echo
return $exit_status
}
#
# setup the testing environment
#
_tsetup_ ()
{
LXT_TMP_DIR="/mnt/testarea/lxt";
test -z "$HOSTNAME" && HOSTNAME=$(hostname)
test -d "$LXT_TMP_DIR" || mkdir -p "$LXT_TMP_DIR" >& /dev/null || exit 1
tSTDERR_FILE="$LXT_TMP_DIR/stderr.$$"
test -e "$tSTDERR_FILE" || > "$tSTDERR_FILE" || exit 1
tRETURN_FILE="$LXT_TMP_DIR/return.$$"
test -e "$tRETURN_FILE" || > "$tRETURN_FILE" || exit 1
tPASS_FILE="$LXT_TMP_DIR/tc.pass.$$"
test -e "$tPASS_FILE" || > "$tPASS_FILE" || exit 1
tFAIL_FILE="$LXT_TMP_DIR/tc.fail.$$"
test -e "$tFAIL_FILE" || > "$tFAIL_FILE" || exit 1
}
#
# main
#
# global variables
tIGNORE_STDOUT=0
tIGNORE_STDERR=0
tSTDOUT=
tSTDERR=
#LXT_TMP_DIR
# only used in this file
tPASS_FILE=
tFAIL_FILE=
_tsetup_

29
tests/sanity/runtest.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
# Copyright (c) 2016 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Author: Yi Zhang <yizhan@redhat.com>
#set -x
source ../include/tc.sh || exit 200
tlog "running $0"
tok "yum -y reinstall libnvme"
tok "yum -y remove libnvme"
tok "yum -y install libnvme"
tend

11
tests/tests.yml Normal file
View File

@ -0,0 +1,11 @@
- hosts: localhost
roles:
- role: standard-test-basic
tags:
- classic
tests:
- simple:
dir: sanity
run: ./runtest.sh
required_packages:
- which