import CS nvme-cli-2.4-10.el9

This commit is contained in:
eabdullin 2023-09-21 19:40:24 +00:00
parent aee9a22d8d
commit bc56d43da1
8 changed files with 1381 additions and 23 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/nvme-cli-2.2.1.tar.gz
SOURCES/nvme-cli-2.4.tar.gz

View File

@ -1 +1 @@
1b66c5cb0d83948557c431157130565f1710b665 SOURCES/nvme-cli-2.2.1.tar.gz
6583ee6fa9f715cbff11dd40aae7417e9e791691 SOURCES/nvme-cli-2.4.tar.gz

View File

@ -0,0 +1,75 @@
From 34c197e0ac2d57734ab775f00b2d0758aca7b82f Mon Sep 17 00:00:00 2001
From: John Meneghini <jmeneghi@redhat.com>
Date: Fri, 14 Apr 2023 10:53:58 -0400
Subject: [PATCH] nbft: make lookup_ctrl function public
To prepare for the addition of nbft functionality fixup the fabrics
declarations.
Signed-off-by: John Meneghini <jmeneghi@redhat.com>
---
fabrics.c | 12 ++----------
fabrics.h | 10 ++++++++++
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/fabrics.c b/fabrics.c
index f8078e59..80827b16 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -43,6 +43,7 @@
#include "libnvme.h"
#include "nvme-print.h"
#include "nvme-print-json.h"
+#include "fabrics.h"
#define PATH_NVMF_DISC SYSCONFDIR "/nvme/discovery.conf"
#define PATH_NVMF_CONFIG SYSCONFDIR "/nvme/config.json"
@@ -110,15 +111,6 @@ static const char *nvmf_config_file = "Use specified JSON configuration file or
OPT_FLAG("data-digest", 'G', &c.data_digest, nvmf_data_digest), \
OPT_FLAG("tls", 0, &c.tls, nvmf_tls) \
-struct tr_config {
- const char *subsysnqn;
- const char *transport;
- const char *traddr;
- const char *host_traddr;
- const char *host_iface;
- const char *trsvcid;
-};
-
/*
* Compare two C strings and handle NULL pointers gracefully.
* If either of the two strings is NULL, return 0
@@ -202,7 +194,7 @@ static nvme_ctrl_t lookup_discovery_ctrl(nvme_root_t r, struct tr_config *trcfg)
return __lookup_ctrl(r, trcfg, disc_ctrl_config_match);
}
-static nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg)
+nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg)
{
return __lookup_ctrl(r, trcfg, ctrl_config_match);
}
diff --git a/fabrics.h b/fabrics.h
index d1e16fc5..02cebf5d 100644
--- a/fabrics.h
+++ b/fabrics.h
@@ -2,6 +2,16 @@
#ifndef _FABRICS_H
#define _FABRICS_H
+struct tr_config {
+ const char *subsysnqn;
+ const char *transport;
+ const char *traddr;
+ const char *host_traddr;
+ const char *host_iface;
+ const char *trsvcid;
+};
+
+extern nvme_ctrl_t lookup_ctrl(nvme_root_t r, struct tr_config *trcfg);
extern int nvmf_discover(const char *desc, int argc, char **argv, bool connect);
extern int nvmf_connect(const char *desc, int argc, char **argv);
extern int nvmf_disconnect(const char *desc, int argc, char **argv);
--
2.39.1

View File

@ -0,0 +1,451 @@
From a71a08532b5f06ee19ee2ff118a23cec4ecb6719 Mon Sep 17 00:00:00 2001
From: Stuart Hayes <stuart_hayes@dell.com>
Date: Wed, 15 Jun 2022 11:42:50 -0500
Subject: [PATCH] nbft: added NBFT v1.0 table support
Added support for parsing the contents of the NBFT table (per NVMe-oF
boot specification v1.0) with the connect-all and discover commands.
nvme discover/connect-all --nbft ignore /etc/nvme config and use NBFT tables
nvme discover/connect-all --no-nbft ignore NBFT tables and use /etc/nvme config
nvme discover/connect-all --nbft-path=<STR> user-defined path for NBFT tables
Signed-off-by: Stuart Hayes <stuart_hayes@dell.com>
Signed-off-by: Martin Belanger <martin.belanger@dell.com>
Use the new nbft public API.
Signed-off-by: Tomas Bzatek <tbzatek@redhat.com>
Signed-off-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: John Meneghini <jmeneghi@redhat.com>
---
Documentation/nvme-connect-all.txt | 25 ++++
Documentation/nvme-discover.txt | 27 +++-
fabrics.c | 17 +++
meson.build | 1 +
nbft.c | 202 +++++++++++++++++++++++++++++
nbft.h | 19 +++
6 files changed, 290 insertions(+), 1 deletion(-)
create mode 100644 nbft.c
create mode 100644 nbft.h
diff --git a/Documentation/nvme-connect-all.txt b/Documentation/nvme-connect-all.txt
index 44bb4f94..cbb7ca6c 100644
--- a/Documentation/nvme-connect-all.txt
+++ b/Documentation/nvme-connect-all.txt
@@ -35,6 +35,9 @@ SYNOPSIS
[--tls ]
[--quiet | -S]
[--dump-config | -O]
+ [--nbft]
+ [--no-nbft]
+ [--nbft-path=<STR>]
DESCRIPTION
-----------
@@ -198,6 +201,16 @@ OPTIONS
--dump-config::
Print out resulting JSON configuration file to stdout.
+--nbft::
+ Only look at NBFT tables
+
+--no-nbft::
+ Do not look at NBFT tables
+
+--nbft-path=<STR>::
+ Use a user-defined path to the NBFT tables
+
+
EXAMPLES
--------
@@ -210,6 +223,18 @@ the RDMA network. Port 4420 is used by default:
--hostnqn=host1-rogue-nqn
------------
+
+* Issue a 'nvme connect-all' command using the default system defined NBFT tables:
++
+-----------
+# nvme connect-all --nbft
+------------
++
+* Issue a 'nvme connect-all' command with a user-defined path for the NBFT table:
++
+-----------
+# nvme connet-all --nbft-path=/sys/firmware/acpi/tables/NBFT1
+------------
++
* Issue a 'nvme connect-all' command using a @SYSCONFDIR@/nvme/discovery.conf file:
+
-----------
diff --git a/Documentation/nvme-discover.txt b/Documentation/nvme-discover.txt
index d4df75c2..b040c688 100644
--- a/Documentation/nvme-discover.txt
+++ b/Documentation/nvme-discover.txt
@@ -37,6 +37,9 @@ SYNOPSIS
[--dump-config | -O]
[--output-format=<fmt> | -o <fmt>]
[--force]
+ [--nbft]
+ [--no-nbft]
+ [--nbft-path=<STR>]
DESCRIPTION
-----------
@@ -68,7 +71,7 @@ Note that the base NVMe specification defines the NQN (NVMe Qualified
Name) format which an NVMe endpoint (device, subsystem, etc) must
follow to guarantee a unique name under the NVMe standard.
In particular, the Host NQN uniquely identifies the NVMe Host, and
-may be used by the the Discovery Controller to control what NVMe Target
+may be used by the Discovery Controller to control what NVMe Target
resources are allocated to the NVMe Host for a connection.
A Discovery Controller has it's own NQN defined in the NVMe-over-Fabrics
@@ -229,6 +232,16 @@ OPTIONS
Combined with --persistent flag, always create new
persistent discovery connection.
+--nbft::
+ Only look at NBFT tables
+
+--no-nbft::
+ Do not look at NBFT tables
+
+--nbft-path=<STR>::
+ Use a user-defined path to the NBFT tables
+
+
EXAMPLES
--------
* Query the Discover Controller with IP4 address 192.168.1.3 for all
@@ -240,6 +253,18 @@ Port 4420 is used by default:
--hostnqn=host1-rogue-nqn
------------
+
+* Issue a 'nvme discover' command using the default system defined NBFT tables:
++
+-----------
+# nvme discover --nbft
+------------
++
+* Issue a 'nvme discover' command with a user-defined path for the NBFT table:
++
+-----------
+# nvme discover --nbft-path=/sys/firmware/acpi/tables/NBFT1
+------------
++
* Issue a 'nvme discover' command using a @SYSCONFDIR@/nvme/discovery.conf file:
+
-----------
diff --git a/fabrics.c b/fabrics.c
index 80827b16..0edbd299 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -40,6 +40,7 @@
#include "common.h"
#include "nvme.h"
+#include "nbft.h"
#include "libnvme.h"
#include "nvme-print.h"
#include "nvme-print-json.h"
@@ -710,6 +711,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
{
char *subsysnqn = NVME_DISC_SUBSYS_NAME;
char *hostnqn = NULL, *hostid = NULL, *hostkey = NULL;
+ char *hostnqn_arg, *hostid_arg;
char *transport = NULL, *traddr = NULL, *trsvcid = NULL;
char *config_file = PATH_NVMF_CONFIG;
char *hnqn = NULL, *hid = NULL;
@@ -724,6 +726,8 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
char *device = NULL;
bool force = false;
bool json_config = false;
+ bool nbft = false, nonbft = false;
+ char *nbft_path = NBFT_SYSFS_PATH;
OPT_ARGS(opts) = {
OPT_STRING("device", 'd', "DEV", &device, "use existing discovery controller device"),
@@ -736,6 +740,9 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
OPT_INCR("verbose", 'v', &verbose, "Increase logging verbosity"),
OPT_FLAG("dump-config", 'O', &dump_config, "Dump configuration file to stdout"),
OPT_FLAG("force", 0, &force, "Force persistent discovery controller creation"),
+ OPT_FLAG("nbft", 0, &nbft, "Only look at NBFT tables"),
+ OPT_FLAG("no-nbft", 0, &nonbft, "Do not look at NBFT tables"),
+ OPT_STRING("nbft-path", 0, "STR", &nbft_path, "user-defined path for NBFT tables"),
OPT_END()
};
@@ -768,6 +775,8 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
if (!nvme_read_config(r, config_file))
json_config = true;
+ hostnqn_arg = hostnqn;
+ hostid_arg = hostid;
if (!hostnqn)
hostnqn = hnqn = nvmf_hostnqn_from_file();
if (!hostnqn)
@@ -789,6 +798,14 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
nvme_host_set_dhchap_key(h, hostkey);
if (!device && !transport && !traddr) {
+ if (!nonbft)
+ discover_from_nbft(r, hostnqn_arg, hostid_arg,
+ hostnqn, hostid, desc, connect,
+ &cfg, nbft_path, flags, verbose);
+
+ if (nbft)
+ goto out_free;
+
if (json_config)
ret = discover_from_json_config_file(r, h, desc,
connect, &cfg,
diff --git a/meson.build b/meson.build
index 43ce5f9b..7ec357a9 100644
--- a/meson.build
+++ b/meson.build
@@ -240,6 +240,7 @@ incdir = include_directories(['ccan'])
################################################################################
sources = [
+ 'nbft.c',
'fabrics.c',
'nvme.c',
'nvme-models.c',
diff --git a/nbft.c b/nbft.c
new file mode 100644
index 00000000..14347287
--- /dev/null
+++ b/nbft.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <errno.h>
+#include <stdio.h>
+#include <fnmatch.h>
+
+#include "nvme.h"
+#include "nbft.h"
+#include "libnvme.h"
+#include "fabrics.h"
+
+#define NBFT_SYSFS_FILENAME "NBFT*"
+
+static void print_connect_msg(nvme_ctrl_t c)
+{
+ printf("device: %s\n", nvme_ctrl_get_name(c));
+}
+
+static void json_connect_msg(nvme_ctrl_t c)
+{
+ struct json_object *root;
+
+ root = json_create_object();
+ json_object_add_value_string(root, "device", nvme_ctrl_get_name(c));
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+int nbft_filter(const struct dirent *dent)
+{
+ return !fnmatch(NBFT_SYSFS_FILENAME, dent->d_name, FNM_PATHNAME);
+}
+
+int read_nbft_files(struct list_head *nbft_list, char *path)
+{
+ struct dirent **dent;
+ char filename[PATH_MAX];
+ int i, count, ret;
+ struct nbft_file_entry *entry;
+ struct nbft_info *nbft;
+
+ count = scandir(path, &dent, nbft_filter, NULL);
+ if (count < 0) {
+ fprintf(stderr, "Failed to open %s.\n", path);
+ return -1;
+ }
+
+ for (i = 0; i < count; i++) {
+ snprintf(filename, sizeof(filename), "%s/%s", path, dent[i]->d_name);
+ ret = nvme_nbft_read(&nbft, filename);
+ if (!ret) {
+ entry = calloc(1, sizeof(*entry));
+ entry->nbft = nbft;
+ list_add_tail(nbft_list, &entry->node);
+ }
+ free(dent[i]);
+ }
+ free(dent);
+ return 0;
+}
+
+void free_nbfts(struct list_head *nbft_list)
+{
+ struct nbft_file_entry *entry;
+
+ while ((entry = list_pop(nbft_list, struct nbft_file_entry, node))) {
+ nvme_nbft_free(entry->nbft);
+ free(entry);
+ }
+}
+
+int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
+ char *hostnqn_sys, char *hostid_sys,
+ const char *desc, bool connect,
+ const struct nvme_fabrics_config *cfg, char *nbft_path,
+ enum nvme_print_flags flags, bool verbose)
+{
+ char *hostnqn = NULL, *hostid = NULL, *host_traddr = NULL;
+ nvme_host_t h;
+ nvme_ctrl_t c;
+ int ret, i;
+ struct list_head nbft_list;
+ struct nbft_file_entry *entry;
+ struct nbft_info_subsystem_ns **ss;
+ struct nbft_info_hfi *hfi;
+
+ if (!connect)
+ /* to do: print discovery-type info from NBFT tables */
+ return 0;
+
+ list_head_init(&nbft_list);
+ ret = read_nbft_files(&nbft_list, nbft_path);
+ if (ret)
+ goto out_free_2;
+
+ list_for_each(&nbft_list, entry, node)
+ for (ss = entry->nbft->subsystem_ns_list; ss && *ss; ss++)
+ for (i = 0; i < (*ss)->num_hfis; i++) {
+ nvme_ctrl_t cl;
+
+ hfi = (*ss)->hfis[i];
+ if (hostnqn_arg)
+ hostnqn = hostnqn_arg;
+ else {
+ hostnqn = entry->nbft->host.nqn;
+ if (!hostnqn)
+ hostnqn = hostnqn_sys;
+ }
+
+ if (hostid_arg)
+ hostid = hostid_arg;
+ else if (*entry->nbft->host.id) {
+ hostid = (char *)util_uuid_to_string(entry->nbft->host.id);
+ if (!hostid)
+ hostid = hostid_sys;
+ }
+
+ h = nvme_lookup_host(r, hostnqn, hostid);
+ if (!h) {
+ errno = ENOMEM;
+ goto out_free;
+ }
+
+ if (!cfg->host_traddr) {
+ host_traddr = NULL;
+ if (!strncmp((*ss)->transport, "tcp", 3))
+ host_traddr = hfi->tcp_info.ipaddr;
+ }
+
+ struct tr_config trcfg = {
+ .subsysnqn = (*ss)->subsys_nqn,
+ .transport = (*ss)->transport,
+ .traddr = (*ss)->traddr,
+ .host_traddr = host_traddr,
+ .host_iface = NULL,
+ .trsvcid = (*ss)->trsvcid,
+ };
+
+ /* Already connected ? */
+ cl = lookup_ctrl(r, &trcfg);
+ if (cl && nvme_ctrl_get_name(cl))
+ continue;
+
+ c = nvme_create_ctrl(r, (*ss)->subsys_nqn, (*ss)->transport,
+ (*ss)->traddr, host_traddr, NULL,
+ (*ss)->trsvcid);
+ if (!c) {
+ errno = ENOMEM;
+ goto out_free;
+ }
+
+ errno = 0;
+ ret = nvmf_add_ctrl(h, c, cfg);
+
+ /*
+ * With TCP/DHCP, it can happen that the OS
+ * obtains a different local IP address than the
+ * firmware had. Retry without host_traddr.
+ */
+ if (ret == -1 && errno == ENVME_CONNECT_WRITE &&
+ !strcmp((*ss)->transport, "tcp") &&
+ strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) {
+ nvme_free_ctrl(c);
+
+ trcfg.host_traddr = NULL;
+ cl = lookup_ctrl(r, &trcfg);
+ if (cl && nvme_ctrl_get_name(cl))
+ continue;
+
+ c = nvme_create_ctrl(r, (*ss)->subsys_nqn, (*ss)->transport,
+ (*ss)->traddr,
+ NULL, NULL, (*ss)->trsvcid);
+ if (!c) {
+ errno = ENOMEM;
+ goto out_free;
+ }
+ errno = 0;
+ ret = nvmf_add_ctrl(h, c, cfg);
+ if (ret == 0 && verbose >= 1)
+ fprintf(stderr,
+ "connect with host_traddr=\"%s\" failed, success after omitting host_traddr\n",
+ host_traddr);
+ }
+
+ if (ret)
+ fprintf(stderr, "no controller found\n");
+ else {
+ if (flags == NORMAL)
+ print_connect_msg(c);
+ else if (flags == JSON)
+ json_connect_msg(c);
+ }
+out_free:
+ if (errno == ENOMEM)
+ goto out_free_2;
+ }
+out_free_2:
+ free_nbfts(&nbft_list);
+ return errno;
+}
diff --git a/nbft.h b/nbft.h
new file mode 100644
index 00000000..0e09733f
--- /dev/null
+++ b/nbft.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <ccan/list/list.h>
+
+#define NBFT_SYSFS_PATH "/sys/firmware/acpi/tables"
+
+struct nbft_file_entry {
+ struct list_node node;
+ struct nbft_info *nbft;
+};
+
+int read_nbft_files(struct list_head *nbft_list, char *path);
+void free_nbfts(struct list_head *nbft_list);
+
+extern int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg,
+ char *hostnqn_sys, char *hostid_sys,
+ const char *desc, bool connect,
+ const struct nvme_fabrics_config *cfg, char *nbft_path,
+ enum nvme_print_flags flags, bool verbose);
--
2.39.1

View File

@ -0,0 +1,640 @@
From 23daeedc53be9b5225cc6806434888c0a7a8e9bf Mon Sep 17 00:00:00 2001
From: Stuart Hayes <stuart_hayes@dell.com>
Date: Fri, 14 Apr 2023 22:01:07 -0400
Subject: [PATCH] nbft: add the nbft show plugin
Display contents of the ACPI NBFT files.
Usage: nvme nbft show <device> [OPTIONS]
Options:
[ --output-format=<FMT>, -o <FMT> ] --- Output format: normal|json
[ --subsystem, -s ] --- show NBFT subsystems
[ --hfi, -H ] --- show NBFT HFIs
[ --discovery, -d ] --- show NBFT discovery controllers
[ --nbft-path=<STR> ] --- user-defined path for NBFT tables
Signed-off-by: Stuart Hayes <stuart_hayes@dell.com>
Signed-off-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: John Meneghini <jmeneghi@redhat.com>
---
plugins/meson.build | 1 +
plugins/nbft/nbft-plugin.c | 568 +++++++++++++++++++++++++++++++++++++
plugins/nbft/nbft-plugin.h | 18 ++
3 files changed, 587 insertions(+)
create mode 100644 plugins/nbft/nbft-plugin.c
create mode 100644 plugins/nbft/nbft-plugin.h
diff --git a/plugins/meson.build b/plugins/meson.build
index 2cf2486f..38b7cded 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -12,6 +12,7 @@ if json_c_dep.found()
'plugins/intel/intel-nvme.c',
'plugins/memblaze/memblaze-nvme.c',
'plugins/micron/micron-nvme.c',
+ 'plugins/nbft/nbft-plugin.c',
'plugins/netapp/netapp-nvme.c',
'plugins/nvidia/nvidia-nvme.c',
'plugins/scaleflux/sfx-nvme.c',
diff --git a/plugins/nbft/nbft-plugin.c b/plugins/nbft/nbft-plugin.c
new file mode 100644
index 00000000..6ae2525a
--- /dev/null
+++ b/plugins/nbft/nbft-plugin.c
@@ -0,0 +1,568 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <errno.h>
+#include <stdio.h>
+#include <fnmatch.h>
+
+#include "nvme-print.h"
+#include "nvme.h"
+#include "nbft.h"
+#include "libnvme.h"
+#include "fabrics.h"
+
+#define CREATE_CMD
+#include "nbft-plugin.h"
+
+static const char dash[100] = {[0 ... 98] = '-', [99] = '\0'};
+
+#define PCI_SEGMENT(sbdf) ((sbdf & 0xffff0000) >> 16)
+#define PCI_BUS(sbdf) ((sbdf & 0x0000ff00) >> 8)
+#define PCI_DEV(sbdf) ((sbdf & 0x000000f8) >> 3)
+#define PCI_FUNC(sbdf) ((sbdf & 0x00000007) >> 0)
+
+static const char *pci_sbdf_to_string(__u16 pci_sbdf)
+{
+ static char pcidev[13];
+
+ snprintf(pcidev, sizeof(pcidev), "%x:%x:%x.%x",
+ PCI_SEGMENT(pci_sbdf),
+ PCI_BUS(pci_sbdf),
+ PCI_DEV(pci_sbdf),
+ PCI_FUNC(pci_sbdf));
+ return pcidev;
+}
+
+static char *mac_addr_to_string(unsigned char mac_addr[6])
+{
+ static char mac_string[18];
+
+ snprintf(mac_string, sizeof(mac_string), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac_addr[0],
+ mac_addr[1],
+ mac_addr[2],
+ mac_addr[3],
+ mac_addr[4],
+ mac_addr[5]);
+ return mac_string;
+}
+
+static json_object *hfi_to_json(struct nbft_info_hfi *hfi)
+{
+ struct json_object *hfi_json;
+
+ hfi_json = json_create_object();
+ if (!hfi_json)
+ return NULL;
+
+ if (json_object_add_value_int(hfi_json, "index", hfi->index)
+ || json_object_add_value_string(hfi_json, "transport", hfi->transport))
+ goto fail;
+
+ if (strcmp(hfi->transport, "tcp") == 0) {
+ if (json_object_add_value_string(hfi_json, "pcidev",
+ pci_sbdf_to_string(hfi->tcp_info.pci_sbdf))
+ || json_object_add_value_string(hfi_json, "mac_addr",
+ mac_addr_to_string(hfi->tcp_info.mac_addr))
+ || json_object_add_value_int(hfi_json, "vlan",
+ hfi->tcp_info.vlan)
+ || json_object_add_value_int(hfi_json, "ip_origin",
+ hfi->tcp_info.ip_origin)
+ || json_object_add_value_string(hfi_json, "ipaddr",
+ hfi->tcp_info.ipaddr)
+ || json_object_add_value_int(hfi_json, "subnet_mask_prefix",
+ hfi->tcp_info.subnet_mask_prefix)
+ || json_object_add_value_string(hfi_json, "gateway_ipaddr",
+ hfi->tcp_info.gateway_ipaddr)
+ || json_object_add_value_int(hfi_json, "route_metric",
+ hfi->tcp_info.route_metric)
+ || json_object_add_value_string(hfi_json, "primary_dns_ipaddr",
+ hfi->tcp_info.primary_dns_ipaddr)
+ || json_object_add_value_string(hfi_json, "secondary_dns_ipaddr",
+ hfi->tcp_info.secondary_dns_ipaddr)
+ || json_object_add_value_string(hfi_json, "dhcp_server_ipaddr",
+ hfi->tcp_info.dhcp_server_ipaddr)
+ || (hfi->tcp_info.host_name
+ && json_object_add_value_string(hfi_json, "host_name",
+ hfi->tcp_info.host_name))
+ || json_object_add_value_int(hfi_json, "this_hfi_is_default_route",
+ hfi->tcp_info.this_hfi_is_default_route)
+ || json_object_add_value_int(hfi_json, "dhcp_override",
+ hfi->tcp_info.dhcp_override))
+ goto fail;
+ else
+ return hfi_json;
+ }
+fail:
+ json_free_object(hfi_json);
+ return NULL;
+}
+
+static json_object *ssns_to_json(struct nbft_info_subsystem_ns *ss)
+{
+ struct json_object *ss_json;
+ struct json_object *hfi_array_json;
+ char json_str[40];
+ char *json_str_p;
+ int i;
+
+ ss_json = json_create_object();
+ if (!ss_json)
+ return NULL;
+
+ hfi_array_json = json_create_array();
+ if (!hfi_array_json)
+ goto fail;
+
+ for (i = 0; i < ss->num_hfis; i++)
+ if (json_array_add_value_object(hfi_array_json,
+ json_object_new_int(ss->hfis[i]->index)))
+ goto fail;
+
+ if (json_object_add_value_int(ss_json, "index", ss->index)
+ || json_object_add_value_int(ss_json, "num_hfis", ss->num_hfis)
+ || json_object_object_add(ss_json, "hfis", hfi_array_json)
+ || json_object_add_value_string(ss_json, "transport", ss->transport)
+ || json_object_add_value_string(ss_json, "traddr", ss->traddr)
+ || json_object_add_value_string(ss_json, "trsvcid", ss->trsvcid)
+ || json_object_add_value_int(ss_json, "subsys_port_id", ss->subsys_port_id)
+ || json_object_add_value_int(ss_json, "nsid", ss->nsid))
+ goto fail;
+
+ memset(json_str, 0, sizeof(json_str));
+ json_str_p = json_str;
+
+ switch (ss->nid_type) {
+ case NBFT_INFO_NID_TYPE_EUI64:
+ if (json_object_add_value_string(ss_json, "nid_type", "eui64"))
+ goto fail;
+ for (i = 0; i < 8; i++)
+ json_str_p += sprintf(json_str_p, "%02x", ss->nid[i]);
+ break;
+
+ case NBFT_INFO_NID_TYPE_NGUID:
+ if (json_object_add_value_string(ss_json, "nid_type", "nguid"))
+ goto fail;
+ for (i = 0; i < 16; i++)
+ json_str_p += sprintf(json_str_p, "%02x", ss->nid[i]);
+ break;
+
+ case NBFT_INFO_NID_TYPE_NS_UUID:
+ if (json_object_add_value_string(ss_json, "nid_type", "uuid"))
+ goto fail;
+ nvme_uuid_to_string(ss->nid, json_str);
+ break;
+
+ default:
+ break;
+ }
+ if (json_object_add_value_string(ss_json, "nid", json_str))
+ goto fail;
+
+ if ((ss->subsys_nqn
+ && json_object_add_value_string(ss_json, "subsys_nqn", ss->subsys_nqn))
+ || json_object_add_value_int(ss_json, "controller_id", ss->controller_id)
+ || json_object_add_value_int(ss_json, "asqsz", ss->asqsz)
+ || (ss->dhcp_root_path_string
+ && json_object_add_value_string(ss_json, "dhcp_root_path_string",
+ ss->dhcp_root_path_string))
+ || json_object_add_value_int(ss_json, "pdu_header_digest_required",
+ ss->pdu_header_digest_required)
+ || json_object_add_value_int(ss_json, "data_digest_required",
+ ss->data_digest_required))
+ goto fail;
+
+ return ss_json;
+fail:
+ json_free_object(ss_json);
+ return NULL;
+}
+
+static json_object *discovery_to_json(struct nbft_info_discovery *disc)
+{
+ struct json_object *disc_json;
+
+ disc_json = json_create_object();
+ if (!disc_json)
+ return NULL;
+
+ if (json_object_add_value_int(disc_json, "index", disc->index)
+ || (disc->security
+ && json_object_add_value_int(disc_json, "security", disc->security->index))
+ || (disc->hfi
+ && json_object_add_value_int(disc_json, "hfi", disc->hfi->index))
+ || (disc->uri
+ && json_object_add_value_string(disc_json, "uri", disc->uri))
+ || (disc->nqn
+ && json_object_add_value_string(disc_json, "nqn", disc->nqn))) {
+ json_free_object(disc_json);
+ return NULL;
+ } else
+ return disc_json;
+}
+
+static const char *primary_admin_host_flag_to_str(unsigned int primary)
+{
+ static const char * const str[] = {
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_NOT_INDICATED] = "not indicated",
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_UNSELECTED] = "unselected",
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_SELECTED] = "selected",
+ [NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_RESERVED] = "reserved",
+ };
+
+ if (primary > NBFT_INFO_PRIMARY_ADMIN_HOST_FLAG_RESERVED)
+ return "INVALID";
+ return str[primary];
+}
+
+static struct json_object *nbft_to_json(struct nbft_info *nbft, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ struct json_object *nbft_json, *host_json;
+
+ nbft_json = json_create_object();
+ if (!nbft_json)
+ return NULL;
+
+ if (json_object_add_value_string(nbft_json, "filename", nbft->filename))
+ goto fail;
+
+ host_json = json_create_object();
+ if (!host_json)
+ goto fail;
+ if ((nbft->host.nqn
+ && json_object_add_value_string(host_json, "nqn", nbft->host.nqn))
+ || (nbft->host.id
+ && json_object_add_value_string(host_json, "id",
+ util_uuid_to_string(nbft->host.id))))
+ goto fail;
+ json_object_add_value_int(host_json, "host_id_configured",
+ nbft->host.host_id_configured);
+ json_object_add_value_int(host_json, "host_nqn_configured",
+ nbft->host.host_nqn_configured);
+ json_object_add_value_string(host_json, "primary_admin_host_flag",
+ primary_admin_host_flag_to_str(nbft->host.primary));
+ if (json_object_object_add(nbft_json, "host", host_json)) {
+ json_free_object(host_json);
+ goto fail;
+ }
+
+ if (show_subsys) {
+ struct json_object *subsys_array_json, *subsys_json;
+ struct nbft_info_subsystem_ns **ss;
+
+ subsys_array_json = json_create_array();
+ if (!subsys_array_json)
+ goto fail;
+ for (ss = nbft->subsystem_ns_list; ss && *ss; ss++) {
+ subsys_json = ssns_to_json(*ss);
+ if (!subsys_json)
+ goto fail;
+ if (json_object_array_add(subsys_array_json, subsys_json)) {
+ json_free_object(subsys_json);
+ goto fail;
+ }
+ }
+ if (json_object_object_add(nbft_json, "subsystem", subsys_array_json)) {
+ json_free_object(subsys_array_json);
+ goto fail;
+ }
+ }
+ if (show_hfi) {
+ struct json_object *hfi_array_json, *hfi_json;
+ struct nbft_info_hfi **hfi;
+
+ hfi_array_json = json_create_array();
+ if (!hfi_array_json)
+ goto fail;
+ for (hfi = nbft->hfi_list; hfi && *hfi; hfi++) {
+ hfi_json = hfi_to_json(*hfi);
+ if (!hfi_json)
+ goto fail;
+ if (json_object_array_add(hfi_array_json, hfi_json)) {
+ json_free_object(hfi_json);
+ goto fail;
+ }
+ }
+ if (json_object_object_add(nbft_json, "hfi", hfi_array_json)) {
+ json_free_object(hfi_array_json);
+ goto fail;
+ }
+ }
+ if (show_discovery) {
+ struct json_object *discovery_array_json, *discovery_json;
+ struct nbft_info_discovery **disc;
+
+ discovery_array_json = json_create_array();
+ if (!discovery_array_json)
+ goto fail;
+ for (disc = nbft->discovery_list; disc && *disc; disc++) {
+ discovery_json = discovery_to_json(*disc);
+ if (!discovery_json)
+ goto fail;
+ if (json_object_array_add(discovery_array_json, discovery_json)) {
+ json_free_object(discovery_json);
+ goto fail;
+ }
+ }
+ if (json_object_object_add(nbft_json, "discovery", discovery_array_json)) {
+ json_free_object(discovery_array_json);
+ goto fail;
+ }
+ }
+ return nbft_json;
+fail:
+ json_free_object(nbft_json);
+ return NULL;
+}
+
+static int json_show_nbfts(struct list_head *nbft_list, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ struct json_object *nbft_json_array, *nbft_json;
+ struct nbft_file_entry *entry;
+
+ nbft_json_array = json_create_array();
+ if (!nbft_json_array)
+ return ENOMEM;
+
+ list_for_each(nbft_list, entry, node) {
+ nbft_json = nbft_to_json(entry->nbft, show_subsys, show_hfi, show_discovery);
+ if (!nbft_json)
+ goto fail;
+ if (json_object_array_add(nbft_json_array, nbft_json)) {
+ json_free_object(nbft_json);
+ goto fail;
+ }
+ }
+
+ json_print_object(nbft_json_array, NULL);
+ printf("\n");
+ json_free_object(nbft_json_array);
+ return 0;
+fail:
+ json_free_object(nbft_json_array);
+ return ENOMEM;
+}
+
+static void print_nbft_hfi_info(struct nbft_info *nbft)
+{
+ struct nbft_info_hfi **hfi;
+ unsigned int ip_width = 8, gw_width = 8, dns_width = 8;
+
+ hfi = nbft->hfi_list;
+ if (!hfi || !*hfi)
+ return;
+
+ for (; *hfi; hfi++) {
+ unsigned int len;
+
+ len = strlen((*hfi)->tcp_info.ipaddr);
+ if (len > ip_width)
+ ip_width = len;
+ len = strlen((*hfi)->tcp_info.gateway_ipaddr);
+ if (len > gw_width)
+ gw_width = len;
+ len = strlen((*hfi)->tcp_info.primary_dns_ipaddr);
+ if (len > dns_width)
+ dns_width = len;
+ }
+
+ printf("\nNBFT HFIs:\n\n");
+ printf("%-3.3s|%-4.4s|%-10.10s|%-17.17s|%-4.4s|%-*.*s|%-4.4s|%-*.*s|%-*.*s\n",
+ "Idx", "Trsp", "PCI Addr", "MAC Addr", "DHCP",
+ ip_width, ip_width, "IP Addr", "Mask",
+ gw_width, gw_width, "Gateway", dns_width, dns_width, "DNS");
+ printf("%-.3s+%-.4s+%-.10s+%-.17s+%-.4s+%-.*s+%-.4s+%-.*s+%-.*s\n",
+ dash, dash, dash, dash, dash, ip_width, dash, dash,
+ gw_width, dash, dns_width, dash);
+ for (hfi = nbft->hfi_list; *hfi; hfi++)
+ printf("%-3d|%-4.4s|%-10.10s|%-17.17s|%-4.4s|%-*.*s|%-4d|%-*.*s|%-*.*s\n",
+ (*hfi)->index,
+ (*hfi)->transport,
+ pci_sbdf_to_string((*hfi)->tcp_info.pci_sbdf),
+ mac_addr_to_string((*hfi)->tcp_info.mac_addr),
+ (*hfi)->tcp_info.dhcp_override ? "yes" : "no",
+ ip_width, ip_width, (*hfi)->tcp_info.ipaddr,
+ (*hfi)->tcp_info.subnet_mask_prefix,
+ gw_width, gw_width, (*hfi)->tcp_info.gateway_ipaddr,
+ dns_width, dns_width, (*hfi)->tcp_info.primary_dns_ipaddr);
+}
+
+static void print_nbft_discovery_info(struct nbft_info *nbft)
+{
+ struct nbft_info_discovery **disc;
+ unsigned int nqn_width = 20, uri_width = 12;
+
+ disc = nbft->discovery_list;
+ if (!disc || !*disc)
+ return;
+
+ for (; *disc; disc++) {
+ size_t len;
+
+ len = strlen((*disc)->uri);
+ if (len > uri_width)
+ uri_width = len;
+ len = strlen((*disc)->nqn);
+ if (len > nqn_width)
+ nqn_width = len;
+ }
+
+ printf("\nNBFT Discovery Controllers:\n\n");
+ printf("%-3.3s|%-*.*s|%-*.*s\n", "Idx", uri_width, uri_width, "URI",
+ nqn_width, nqn_width, "NQN");
+ printf("%-.3s+%-.*s+%-.*s\n", dash, uri_width, dash, nqn_width, dash);
+ for (disc = nbft->discovery_list; *disc; disc++)
+ printf("%-3d|%-*.*s|%-*.*s\n", (*disc)->index,
+ uri_width, uri_width, (*disc)->uri,
+ nqn_width, nqn_width, (*disc)->nqn);
+}
+
+#define HFIS_LEN 20
+static size_t print_hfis(const struct nbft_info_subsystem_ns *ss, char buf[HFIS_LEN])
+{
+ char hfi_buf[HFIS_LEN];
+ size_t len, ofs;
+ int i;
+
+ len = snprintf(hfi_buf, sizeof(hfi_buf), "%d", ss->hfis[0]->index);
+ for (i = 1; i < ss->num_hfis; i++) {
+ ofs = len;
+ len += snprintf(hfi_buf + ofs, sizeof(hfi_buf) - ofs, ",%d",
+ ss->hfis[i]->index);
+ /*
+ * If the list doesn't fit in HFIS_LEN characters,
+ * truncate and end with "..."
+ */
+ if (len >= sizeof(hfi_buf)) {
+ while (ofs < sizeof(hfi_buf) - 1)
+ hfi_buf[ofs++] = '.';
+ hfi_buf[ofs] = '\0';
+ len = sizeof(hfi_buf) - 1;
+ break;
+ }
+ }
+ if (buf)
+ memcpy(buf, hfi_buf, len + 1);
+ return len;
+}
+
+
+static void print_nbft_subsys_info(struct nbft_info *nbft)
+{
+ struct nbft_info_subsystem_ns **ss;
+ unsigned int nqn_width = 20, adr_width = 8, hfi_width = 4;
+
+ ss = nbft->subsystem_ns_list;
+ if (!ss || !*ss)
+ return;
+ for (; *ss; ss++) {
+ size_t len;
+
+ len = strlen((*ss)->subsys_nqn);
+ if (len > nqn_width)
+ nqn_width = len;
+ len = strlen((*ss)->traddr);
+ if (len > adr_width)
+ adr_width = len;
+ len = print_hfis(*ss, NULL);
+ if (len > hfi_width)
+ hfi_width = len;
+ }
+
+ printf("\nNBFT Subsystems:\n\n");
+ printf("%-3.3s|%-*.*s|%-4.4s|%-*.*s|%-5.5s|%-*.*s\n",
+ "Idx", nqn_width, nqn_width, "NQN",
+ "Trsp", adr_width, adr_width, "Address", "SvcId", hfi_width, hfi_width, "HFIs");
+ printf("%-.3s+%-.*s+%-.4s+%-.*s+%-.5s+%-.*s\n",
+ dash, nqn_width, dash, dash, adr_width, dash, dash, hfi_width, dash);
+ for (ss = nbft->subsystem_ns_list; *ss; ss++) {
+ char hfi_buf[HFIS_LEN];
+
+ print_hfis(*ss, hfi_buf);
+ printf("%-3d|%-*.*s|%-4.4s|%-*.*s|%-5.5s|%-*.*s\n",
+ (*ss)->index, nqn_width, nqn_width, (*ss)->subsys_nqn,
+ (*ss)->transport, adr_width, adr_width, (*ss)->traddr,
+ (*ss)->trsvcid, hfi_width, hfi_width, hfi_buf);
+ }
+}
+
+static void normal_show_nbft(struct nbft_info *nbft, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ printf("%s:\n", nbft->filename);
+ if ((!nbft->hfi_list || !*nbft->hfi_list) &&
+ (!nbft->security_list || !*nbft->security_list) &&
+ (!nbft->discovery_list || !*nbft->discovery_list) &&
+ (!nbft->subsystem_ns_list || !*nbft->subsystem_ns_list))
+ printf("(empty)\n");
+ else {
+ if (show_subsys)
+ print_nbft_subsys_info(nbft);
+ if (show_hfi)
+ print_nbft_hfi_info(nbft);
+ if (show_discovery)
+ print_nbft_discovery_info(nbft);
+ }
+}
+
+static void normal_show_nbfts(struct list_head *nbft_list, bool show_subsys,
+ bool show_hfi, bool show_discovery)
+{
+ bool not_first = false;
+ struct nbft_file_entry *entry;
+
+ list_for_each(nbft_list, entry, node) {
+ if (not_first)
+ printf("\n");
+ normal_show_nbft(entry->nbft, show_subsys, show_hfi, show_discovery);
+ not_first = true;
+ }
+}
+
+int show_nbft(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Display contents of the ACPI NBFT files.";
+ struct list_head nbft_list;
+ char *format = "normal";
+ char *nbft_path = NBFT_SYSFS_PATH;
+ enum nvme_print_flags flags = -1;
+ int ret;
+ bool show_subsys = false, show_hfi = false, show_discovery = false;
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &format, "Output format: normal|json"),
+ OPT_FLAG("subsystem", 's', &show_subsys, "show NBFT subsystems"),
+ OPT_FLAG("hfi", 'H', &show_hfi, "show NBFT HFIs"),
+ OPT_FLAG("discovery", 'd', &show_discovery, "show NBFT discovery controllers"),
+ OPT_STRING("nbft-path", 0, "STR", &nbft_path, "user-defined path for NBFT tables"),
+ OPT_END()
+ };
+
+ ret = argconfig_parse(argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ if (!(show_subsys || show_hfi || show_discovery))
+ show_subsys = show_hfi = show_discovery = true;
+
+ if (!strcmp(format, ""))
+ flags = -1;
+ else if (!strcmp(format, "normal"))
+ flags = NORMAL;
+ else if (!strcmp(format, "json"))
+ flags = JSON;
+ else
+ return EINVAL;
+
+ list_head_init(&nbft_list);
+ ret = read_nbft_files(&nbft_list, nbft_path);
+ if (!ret) {
+ if (flags == NORMAL)
+ normal_show_nbfts(&nbft_list, show_subsys, show_hfi, show_discovery);
+ else if (flags == JSON)
+ ret = json_show_nbfts(&nbft_list, show_subsys, show_hfi, show_discovery);
+ free_nbfts(&nbft_list);
+ }
+ return ret;
+}
diff --git a/plugins/nbft/nbft-plugin.h b/plugins/nbft/nbft-plugin.h
new file mode 100644
index 00000000..018349d9
--- /dev/null
+++ b/plugins/nbft/nbft-plugin.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#undef CMD_INC_FILE
+#define CMD_INC_FILE plugins/nbft/nbft-plugin
+
+#if !defined(NBFT) || defined(CMD_HEADER_MULTI_READ)
+#define NBFT
+
+#include "cmd.h"
+
+PLUGIN(NAME("nbft", "ACPI NBFT table extensions", NVME_VERSION),
+ COMMAND_LIST(
+ ENTRY("show", "Show contents of ACPI NBFT tables", show_nbft)
+ )
+);
+
+#endif
+
+#include "define_cmd.h"
--
2.39.1

View File

@ -0,0 +1,35 @@
From e1afeffcbb78e252bbb0d21d2f4ed0fffeb59105 Mon Sep 17 00:00:00 2001
From: Maurizio Lombardi <mlombard@redhat.com>
Date: Tue, 23 May 2023 15:08:40 +0200
Subject: [PATCH] Revert "nvme: Masks SSTAT in sanize-log output"
The NVME_SANITIZE_SSTAT_STATUS_MASK is used to mask the
3 least significant bits (representing the status of the most recent
sanitize operation) of the SSTAT field.
The SSTAT field is 16 bits wide and contains other information too, such
as the Global Data Erased bit and the number of completed passes.
Revert this commit so nvme-cli will print the entire SSTAT field
This reverts commit 7092ff55c5d9017231a68fa4dbb9a37b42d61d61.
---
nvme-print.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nvme-print.c b/nvme-print.c
index c989435d..735ec193 100644
--- a/nvme-print.c
+++ b/nvme-print.c
@@ -4423,7 +4423,7 @@ void nvme_show_sanitize_log(struct nvme_sanitize_log_page *sanitize,
printf("\n");
printf("Sanitize Status (SSTAT) : %#x\n",
- le16_to_cpu(sanitize->sstat) & NVME_SANITIZE_SSTAT_STATUS_MASK);
+ le16_to_cpu(sanitize->sstat));
if (human)
nvme_show_sanitize_log_sstat(le16_to_cpu(sanitize->sstat));
--
2.39.3

View File

@ -0,0 +1,118 @@
From 94d6c2b5088292e101da3e1d078e155a5af32f56 Mon Sep 17 00:00:00 2001
From: Tokunori Ikegami <ikegami.t@gmail.com>
Date: Sun, 14 May 2023 17:39:00 +0900
Subject: [PATCH] util: Fix suffix_si_parse to parse no decimal point but
suffix value correctly
For example create-ns command --ncap-si paramter value 800G parsed to 0 as invalid value.
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
---
unit/test-suffix-si-parse.c | 6 +++++
util/suffix.c | 50 +++++++++++++++++++++++++++----------
2 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/unit/test-suffix-si-parse.c b/unit/test-suffix-si-parse.c
index bc924552..54cff0e6 100644
--- a/unit/test-suffix-si-parse.c
+++ b/unit/test-suffix-si-parse.c
@@ -43,6 +43,12 @@ static struct tonum_test tonum_tests[] = {
{ "2,33", 0, -EINVAL },
{ "3..3", 0, -EINVAL },
{ "123.12MM", 0, -EINVAL },
+ { "800G", 800000000000, 0 },
+ { "800GG", 0, -EINVAL },
+ { "800G800", 0, -EINVAL },
+ { "800.0G", 800000000000, 0 },
+ { "800.G", 0, -EINVAL },
+ { "800.", 0, -EINVAL },
};
void tonum_test(struct tonum_test *test)
diff --git a/util/suffix.c b/util/suffix.c
index 8ed080d4..f010f3b6 100644
--- a/util/suffix.c
+++ b/util/suffix.c
@@ -40,6 +40,7 @@
#include <float.h>
#include <limits.h>
#include <locale.h>
+#include <stdio.h>
static struct si_suffix {
long double magnitude;
@@ -68,11 +69,26 @@ const char *suffix_si_get(double *value)
return suffix;
}
+static bool suffix_si_check(const char val)
+{
+ int i;
+ struct si_suffix *s;
+
+ for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) {
+ s = &si_suffixes[i];
+
+ if (val == *s->suffix)
+ return true;
+ }
+
+ return false;
+}
+
int suffix_si_parse(const char *str, char **endptr, uint64_t *val)
{
- unsigned long long num, frac;
+ unsigned long long num, frac = 0;
char *sep, *tmp;
- int frac_len, len, i;
+ int frac_len = 0, len, i;
num = strtoull(str, endptr, 0);
if (str == *endptr ||
@@ -93,23 +109,31 @@ int suffix_si_parse(const char *str, char **endptr, uint64_t *val)
len = 0;
for (i = 0; i < len; i++) {
+ if (suffix_si_check((*endptr)[i]))
+ break;
if (((*endptr)[i] == '\0') || (*endptr)[i] != sep[i])
return -EINVAL;
}
- *endptr += len;
- tmp = *endptr;
- /* extract the digits after decimal point */
- frac = strtoull(tmp, endptr, 0);
- if (tmp == *endptr ||
- ((frac == ULLONG_MAX) && errno == ERANGE))
- return -EINVAL;
+ if (suffix_si_check((*endptr)[i])) {
+ if ((*endptr)[i + 1] != '\0')
+ return -EINVAL;
+ } else {
+ *endptr += len;
+ tmp = *endptr;
+
+ /* extract the digits after decimal point */
+ frac = strtoull(tmp, endptr, 0);
+ if (tmp == *endptr ||
+ ((frac == ULLONG_MAX) && errno == ERANGE))
+ return -EINVAL;
- /* test that we have max one character as suffix */
- if ((*endptr)[0] != '\0' && (*endptr)[1] != '\0')
- return -EINVAL;
+ /* test that we have max one character as suffix */
+ if ((*endptr)[0] != '\0' && (*endptr)[1] != '\0')
+ return -EINVAL;
- frac_len = *endptr - tmp;
+ frac_len = *endptr - tmp;
+ }
for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) {
struct si_suffix *s = &si_suffixes[i];
--
2.39.3

View File

@ -2,21 +2,27 @@
#%%global shortcommit0 %%(c=%%{commit0}; echo ${c:0:7})
Name: nvme-cli
Version: 2.2.1
Release: 2%{?dist}
Version: 2.4
Release: 10%{?dist}
Summary: NVMe management command line interface
License: GPLv2+
URL: https://github.com/linux-nvme/nvme-cli
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
BuildRequires: meson >= 0.48.0
Patch0: 0001-nbft-make-lookup_ctrl-function-public.patch
Patch1: 0002-nbft-added-NBFT-v1.0-table-support.patch
Patch2: 0003-nbft-add-the-nbft-show-plugin.patch
Patch3: 0004-Revert-nvme-Masks-SSTAT-in-sanize-log-output.patch
Patch4: 0005-util-Fix-suffix_si_parse-to-parse-no-decimal-point-b.patch
BuildRequires: meson >= 0.50.0
BuildRequires: gcc gcc-c++
BuildRequires: libuuid-devel
BuildRequires: systemd-devel
BuildRequires: systemd-rpm-macros
BuildRequires: zlib-devel
BuildRequires: libnvme-devel >= 1.2
BuildRequires: libnvme-devel >= 1.4-5
BuildRequires: json-c-devel >= 0.14
BuildRequires: asciidoc
BuildRequires: xmlto
@ -30,6 +36,12 @@ nvme-cli provides NVM-Express user space tooling for Linux.
#%%setup -qn %%{name}-%%{commit0}
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
%meson -Dudevrulesdir=%{_udevrulesdir} -Dsystemddir=%{_unitdir} -Ddocs=all -Ddocs-build=true -Dhtmldir=%{_pkgdocdir}
%meson_build
@ -37,12 +49,8 @@ nvme-cli provides NVM-Express user space tooling for Linux.
%install
%meson_install
# hostid and hostnqn are supposed to be unique per machine. We obviously
# can't package them.
#rm -f %{buildroot}%{_sysconfdir}/nvme/hostid
#rm -f %{buildroot}%{_sysconfdir}/nvme/hostnqn
# Do not install the dracut rule yet. See rhbz 1742764
# Do we want to keep this here? Now that we have boot support for nvme/fc + tcp?
rm -f %{buildroot}/usr/lib/dracut/dracut.conf.d/70-nvmf-autoconnect.conf
# Move html docs into the right place
@ -52,13 +60,13 @@ rm -rf %{buildroot}%{_pkgdocdir}/nvme
%files
%license LICENSE
%doc README.md
%doc %{_pkgdocdir}
%doc %{_pkgdocdir}/*
%{_sbindir}/nvme
%{_mandir}/man1/nvme*.gz
%{_datadir}/bash-completion/completions/nvme
%{_datadir}/zsh/site-functions/_nvme
%dir %{_sysconfdir}/nvme
%{_sysconfdir}/nvme/discovery.conf
%config(noreplace) %{_sysconfdir}/nvme/discovery.conf
%{_unitdir}/nvmefc-boot-connections.service
%{_unitdir}/nvmf-autoconnect.service
%{_unitdir}/nvmf-connect.target
@ -66,34 +74,65 @@ rm -rf %{buildroot}%{_pkgdocdir}/nvme
%{_udevrulesdir}/70-nvmf-autoconnect.rules
%{_udevrulesdir}/71-nvmf-iopolicy-netapp.rules
# Do not install the dracut rule yet. See rhbz 1742764
# Is this still true? Now that we support nvme-of boot, do we want to install this file?
# /usr/lib/dracut/dracut.conf.d/70-nvmf-autoconnect.conf
%post
if [ $1 -eq 1 ] || [ $1 -eq 2 ]; then
if [ ! -s %{_sysconfdir}/nvme/hostnqn ]; then
echo $(nvme gen-hostnqn) > %{_sysconfdir}/nvme/hostnqn
echo $(nvme gen-hostnqn) > %{_sysconfdir}/nvme/hostnqn
fi
if [ ! -s %{_sysconfdir}/nvme/hostid ]; then
uuidgen > %{_sysconfdir}/nvme/hostid
echo $(nvme show-hostnqn | sed 's/^.*uuid://') > %{_sysconfdir}/nvme/hostid
fi
# apply udev and systemd changes that we did
if [ $1 -eq 1 ]; then
systemctl enable nvmefc-boot-connections
fi
systemctl daemon-reload
udevadm control --reload-rules && udevadm trigger
exit 0
# apply udev and systemd changes that we did
if [ $1 -eq 1 ]; then
systemctl enable nvmefc-boot-connections
fi
systemctl daemon-reload
udevadm control --reload-rules && udevadm trigger
exit 0
fi
%changelog
* Mon Aug 21 2023 John Meneghini <jmeneghi@redhat.com> - 2.4-10
- JIRA: https://issues.redhat.com/browse/RHEL-1492
* Thu Aug 10 2023 John Meneghini <jmeneghi@redhat.com> - 2.4-9
- JIRA: https://issues.redhat.com/browse/RHEL-1147
* Mon Jul 17 2023 John Meneghini <jmeneghi@redhat.com> - 2.4-8
- Fix BZ#2223436
* Wed Jun 14 2023 Maurizio Lombardi <mlombard@redhat.com> - 2.4-7
- Fix BZ#2210656
* Tue May 30 2023 Maurizio Lombardi <mlombard@redhat.com> - 2.4-6
- Rebuild for #2208399
* Thu May 25 2023 Maurizio Lombardi <mlombard@redhat.com> - 2.4-5
- Fix SSTAT print (BZ2208399)
* Tue May 16 2023 Maurizio Lombardi <mlombard@redhat.com> - 2.4-4
- Add support to NBFT (BZ2188518)
* Fri May 12 2023 Maurizio Lombardi <mlombard@redhat.com> - 2.4-3
- Fix a warning when building the package BZ2195897
* Wed May 03 2023 Maurizio Lombardi <mlombard@redhat.com> - 2.4-2
- Fix a bogus changelog date BZ2186074
* Mon Apr 03 2023 Maurizio Lombardi <mlombard@redhat.com> - 2.4-1
- Update to version v2.4
* Thu Nov 10 2022 Maurizio Lombardi <mlombard@redhat.com> - 2.1.2-2
- Do not re-enable nvmefc-boot-connections when the package gets updated
* Mon Sep 26 2022 Maurizio Lombardi <mlombard@redhat.com> - 2.1.2-1
- Update to version v2.1.2
* Fri Aug 29 2022 Maurizio Lombardi <mlombard@redhat.com> - 2.0-4
* Mon Aug 29 2022 Maurizio Lombardi <mlombard@redhat.com> - 2.0-4
- Fix BZ2104945
* Fri Jul 15 2022 Maurizio Lombardi <mlombard@redhat.com> - 2.0-3