summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-02-19 10:38:02 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-02-19 10:38:18 +0000
commit678392aa6bef5e30cb1b9452978fd0b2ce56c2ee (patch)
tree26ac06227a6fe6571157a8860bac80506f00c5d7 /src
parentReleasing debian version 1.7.1-1. (diff)
downloadlibnvme-678392aa6bef5e30cb1b9452978fd0b2ce56c2ee.tar.xz
libnvme-678392aa6bef5e30cb1b9452978fd0b2ce56c2ee.zip
Merging upstream version 1.8.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r--src/libnvme.map6
-rw-r--r--src/nvme/fabrics.c67
-rw-r--r--src/nvme/fabrics.h2
-rw-r--r--src/nvme/filters.c59
-rw-r--r--src/nvme/json.c8
-rw-r--r--src/nvme/linux.c17
-rw-r--r--src/nvme/mi.c3
-rw-r--r--src/nvme/nbft.c22
-rw-r--r--src/nvme/private.h7
-rw-r--r--src/nvme/tree.c57
-rw-r--r--src/nvme/types.h6
-rw-r--r--src/nvme/util.c25
-rw-r--r--src/nvme/util.h9
13 files changed, 238 insertions, 50 deletions
diff --git a/src/libnvme.map b/src/libnvme.map
index 742f635..c8163cb 100644
--- a/src/libnvme.map
+++ b/src/libnvme.map
@@ -1,4 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
+LIBNVME_1_8 {
+ global:
+ nvme_uuid_find;
+};
+
LIBNVME_1_7 {
global:
nvme_init_copy_range_f2;
@@ -130,6 +135,7 @@ LIBNVME_1_0 {
nvme_disconnect_ctrl;
nvme_dsm;
nvme_dump_config;
+ nvme_dump_tree;
nvme_errno_to_string;
nvme_first_host;
nvme_first_subsystem;
diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c
index 4e042d8..1f50229 100644
--- a/src/nvme/fabrics.c
+++ b/src/nvme/fabrics.c
@@ -260,6 +260,7 @@ static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c,
MERGE_CFG_OPTION(ctrl_cfg, cfg, hdr_digest, false);
MERGE_CFG_OPTION(ctrl_cfg, cfg, data_digest, false);
MERGE_CFG_OPTION(ctrl_cfg, cfg, tls, false);
+ MERGE_CFG_OPTION(ctrl_cfg, cfg, concat, false);
return ctrl_cfg;
}
@@ -289,6 +290,7 @@ void nvmf_update_config(nvme_ctrl_t c, const struct nvme_fabrics_config *cfg)
UPDATE_CFG_OPTION(ctrl_cfg, cfg, hdr_digest, false);
UPDATE_CFG_OPTION(ctrl_cfg, cfg, data_digest, false);
UPDATE_CFG_OPTION(ctrl_cfg, cfg, tls, false);
+ UPDATE_CFG_OPTION(ctrl_cfg, cfg, concat, false);
}
static int __add_bool_argument(char **argstr, char *tok, bool arg)
@@ -637,7 +639,9 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr)
(!strcmp(transport, "tcp") &&
add_bool_argument(r, argstr, data_digest, cfg->data_digest)) ||
(!strcmp(transport, "tcp") &&
- add_bool_argument(r, argstr, tls, cfg->tls))) {
+ add_bool_argument(r, argstr, tls, cfg->tls)) ||
+ (!strcmp(transport, "tcp") &&
+ add_bool_argument(r, argstr, concat, cfg->concat))) {
free(*argstr);
return -1;
}
@@ -705,6 +709,7 @@ static int __nvmf_supported_options(nvme_root_t r)
nvme_msg(r, LOG_DEBUG, "%s ", v);
parse_option(r, v, cntlid);
+ parse_option(r, v, concat);
parse_option(r, v, ctrl_loss_tmo);
parse_option(r, v, data_digest);
parse_option(r, v, dhchap_ctrl_secret);
@@ -740,7 +745,7 @@ static int __nvmf_supported_options(nvme_root_t r)
static int __nvmf_add_ctrl(nvme_root_t r, const char *argstr)
{
- _cleanup_fd_ int fd;
+ _cleanup_fd_ int fd = -1;
int ret, len = strlen(argstr);
char buf[0x1000], *options, *p;
@@ -1183,12 +1188,27 @@ struct nvmf_discovery_log *nvmf_get_discovery_wargs(struct nvme_get_discovery_ar
#define PATH_UUID_IBM "/proc/device-tree/ibm,partition-uuid"
+static char *uuid_ibm_filename(void)
+{
+ char *basepath = getenv("LIBNVME_SYSFS_PATH");
+ char *str;
+
+ if (!basepath)
+ return strdup(PATH_UUID_IBM);
+
+ if (!asprintf(&str, "%s" PATH_UUID_IBM, basepath))
+ return NULL;
+
+ return str;
+}
+
static int uuid_from_device_tree(char *system_uuid)
{
+ _cleanup_free_ char *filename = uuid_ibm_filename();
+ _cleanup_fd_ int f = -1;
ssize_t len;
- _cleanup_fd_ int f;
- f = open(PATH_UUID_IBM, O_RDONLY);
+ f = open(filename, O_RDONLY);
if (f < 0)
return -ENXIO;
@@ -1202,6 +1222,20 @@ static int uuid_from_device_tree(char *system_uuid)
#define PATH_DMI_ENTRIES "/sys/firmware/dmi/entries"
+static char *dmi_entries_dir(void)
+{
+ char *basepath = getenv("LIBNVME_SYSFS_PATH");
+ char *str;
+
+ if (!basepath)
+ return strdup(PATH_DMI_ENTRIES);
+
+ if (!asprintf(&str, "%s" PATH_DMI_ENTRIES, basepath))
+ return NULL;
+
+ return str;
+}
+
/*
* See System Management BIOS (SMBIOS) Reference Specification
* https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.2.0.pdf
@@ -1229,13 +1263,14 @@ static bool is_dmi_uuid_valid(const char *buf, size_t len)
static int uuid_from_dmi_entries(char *system_uuid)
{
+ _cleanup_dir_ DIR *d = NULL;
+ _cleanup_free_ char *entries_dir = dmi_entries_dir();
int f;
- _cleanup_dir_ DIR *d;
struct dirent *de;
char buf[512] = {0};
system_uuid[0] = '\0';
- d = opendir(PATH_DMI_ENTRIES);
+ d = opendir(entries_dir);
if (!d)
return -ENXIO;
while ((de = readdir(d))) {
@@ -1244,7 +1279,7 @@ static int uuid_from_dmi_entries(char *system_uuid)
if (de->d_name[0] == '.')
continue;
- sprintf(filename, "%s/%s/type", PATH_DMI_ENTRIES, de->d_name);
+ sprintf(filename, "%s/%s/type", entries_dir, de->d_name);
f = open(filename, O_RDONLY);
if (f < 0)
continue;
@@ -1256,7 +1291,7 @@ static int uuid_from_dmi_entries(char *system_uuid)
continue;
if (type != DMI_SYSTEM_INFORMATION)
continue;
- sprintf(filename, "%s/%s/raw", PATH_DMI_ENTRIES, de->d_name);
+ sprintf(filename, "%s/%s/raw", entries_dir, de->d_name);
f = open(filename, O_RDONLY);
if (f < 0)
continue;
@@ -1294,7 +1329,7 @@ static int uuid_from_dmi_entries(char *system_uuid)
*/
static int uuid_from_product_uuid(char *system_uuid)
{
- _cleanup_file_ FILE *stream;
+ _cleanup_file_ FILE *stream = NULL;
ssize_t nread;
_cleanup_free_ char *line = NULL;
size_t len = 0;
@@ -1364,7 +1399,7 @@ char *nvmf_hostnqn_generate()
static char *nvmf_read_file(const char *f, int len)
{
char buf[len];
- _cleanup_fd_ int fd;
+ _cleanup_fd_ int fd = -1;
int ret;
fd = open(f, O_RDONLY);
@@ -1381,11 +1416,21 @@ static char *nvmf_read_file(const char *f, int len)
char *nvmf_hostnqn_from_file()
{
+ char *hostnqn = getenv("LIBNVME_HOSTNQN");
+
+ if (hostnqn)
+ return strdup(hostnqn);
+
return nvmf_read_file(NVMF_HOSTNQN_FILE, NVMF_NQN_SIZE);
}
char *nvmf_hostid_from_file()
{
+ char *hostid = getenv("LIBNVME_HOSTID");
+
+ if (hostid)
+ return strdup(hostid);
+
return nvmf_read_file(NVMF_HOSTID_FILE, NVMF_HOSTID_SIZE);
}
@@ -1637,7 +1682,7 @@ static const char *dctype_str[] = {
*/
static int nvme_fetch_cntrltype_dctype_from_id(nvme_ctrl_t c)
{
- _cleanup_free_ struct nvme_id_ctrl *id;
+ _cleanup_free_ struct nvme_id_ctrl *id = NULL;
int ret;
id = __nvme_alloc(sizeof(*id));
diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h
index 3664a85..a2504de 100644
--- a/src/nvme/fabrics.h
+++ b/src/nvme/fabrics.h
@@ -42,6 +42,7 @@
* @hdr_digest: Generate/verify header digest (TCP)
* @data_digest: Generate/verify data digest (TCP)
* @tls: Start TLS on the connection (TCP)
+ * @concat: Enable secure concatenation (TCP)
*/
struct nvme_fabrics_config {
char *host_traddr;
@@ -63,6 +64,7 @@ struct nvme_fabrics_config {
bool hdr_digest;
bool data_digest;
bool tls;
+ bool concat;
};
/**
diff --git a/src/nvme/filters.c b/src/nvme/filters.c
index b5959a8..312b8f6 100644
--- a/src/nvme/filters.c
+++ b/src/nvme/filters.c
@@ -21,10 +21,53 @@
#include "filters.h"
#include "types.h"
#include "util.h"
+#include "cleanup.h"
-const char *nvme_ctrl_sysfs_dir = "/sys/class/nvme";
-const char *nvme_ns_sysfs_dir = "/sys/block";
-const char *nvme_subsys_sysfs_dir = "/sys/class/nvme-subsystem";
+#define PATH_SYSFS_NVME "/sys/class/nvme"
+#define PATH_SYSFS_NVME_SUBSYSTEM "/sys/class/nvme-subsystem"
+#define PATH_SYSFS_BLOCK "/sys/block"
+
+char *nvme_ctrl_sysfs_dir(void)
+{
+ char *basepath = getenv("LIBNVME_SYSFS_PATH");
+ char *str;
+
+ if (!basepath)
+ return strdup(PATH_SYSFS_NVME);
+
+ if (!asprintf(&str, "%s" PATH_SYSFS_NVME, basepath))
+ return NULL;
+
+ return str;
+}
+
+char *nvme_ns_sysfs_dir(void)
+{
+ char *basepath = getenv("LIBNVME_SYSFS_PATH");
+ char *str;
+
+ if (!basepath)
+ return strdup(PATH_SYSFS_BLOCK);
+
+ if (!asprintf(&str, "%s" PATH_SYSFS_BLOCK, basepath))
+ return NULL;
+
+ return str;
+}
+
+char *nvme_subsys_sysfs_dir(void)
+{
+ char *basepath = getenv("LIBNVME_SYSFS_PATH");
+ char *str;
+
+ if (!basepath)
+ return strdup(PATH_SYSFS_NVME_SUBSYSTEM);
+
+ if (!asprintf(&str, "%s" PATH_SYSFS_NVME_SUBSYSTEM, basepath))
+ return NULL;
+
+ return str;
+}
int nvme_namespace_filter(const struct dirent *d)
{
@@ -89,8 +132,9 @@ int nvme_subsys_filter(const struct dirent *d)
int nvme_scan_subsystems(struct dirent ***subsys)
{
- return scandir(nvme_subsys_sysfs_dir, subsys, nvme_subsys_filter,
- alphasort);
+ _cleanup_free_ char *dir = nvme_subsys_sysfs_dir();
+
+ return scandir(dir, subsys, nvme_subsys_filter, alphasort);
}
int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***ns)
@@ -101,8 +145,9 @@ int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***ns)
int nvme_scan_ctrls(struct dirent ***ctrls)
{
- return scandir(nvme_ctrl_sysfs_dir, ctrls, nvme_ctrls_filter,
- alphasort);
+ _cleanup_free_ char *dir = nvme_ctrl_sysfs_dir();
+
+ return scandir(dir, ctrls, nvme_ctrls_filter, alphasort);
}
int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***paths)
diff --git a/src/nvme/json.c b/src/nvme/json.c
index 4d0f987..b49498a 100644
--- a/src/nvme/json.c
+++ b/src/nvme/json.c
@@ -60,6 +60,8 @@ static void json_update_attributes(nvme_ctrl_t c,
data_digest, val_obj);
JSON_UPDATE_BOOL_OPTION(cfg, key_str,
tls, val_obj);
+ JSON_UPDATE_BOOL_OPTION(cfg, key_str,
+ concat, val_obj);
if (!strcmp("persistent", key_str) &&
!nvme_ctrl_is_persistent(c))
nvme_ctrl_set_persistent(c, true);
@@ -325,6 +327,7 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c)
JSON_BOOL_OPTION(cfg, port_obj, hdr_digest);
JSON_BOOL_OPTION(cfg, port_obj, data_digest);
JSON_BOOL_OPTION(cfg, port_obj, tls);
+ JSON_BOOL_OPTION(cfg, port_obj, concat);
if (nvme_ctrl_is_persistent(c))
json_object_object_add(port_obj, "persistent",
json_object_new_boolean(true));
@@ -501,6 +504,7 @@ static void json_dump_ctrl(struct json_object *ctrl_array, nvme_ctrl_t c)
JSON_BOOL_OPTION(cfg, ctrl_obj, hdr_digest);
JSON_BOOL_OPTION(cfg, ctrl_obj, data_digest);
JSON_BOOL_OPTION(cfg, ctrl_obj, tls);
+ JSON_BOOL_OPTION(cfg, ctrl_obj, concat);
if (nvme_ctrl_is_persistent(c))
json_object_object_add(ctrl_obj, "persistent",
json_object_new_boolean(true));
@@ -572,9 +576,9 @@ int json_dump_tree(nvme_root_t r)
}
json_object_object_add(json_root, "hosts", host_array);
- ret = json_object_to_fd(1, json_root, JSON_C_TO_STRING_PRETTY);
+ ret = json_object_to_fd(fileno(r->fp), json_root, JSON_C_TO_STRING_PRETTY);
if (ret < 0) {
- nvme_msg(r, LOG_ERR, "Failed to write to stdout, %s\n",
+ nvme_msg(r, LOG_ERR, "Failed to write, %s\n",
json_util_get_last_err());
ret = -1;
errno = EIO;
diff --git a/src/nvme/linux.c b/src/nvme/linux.c
index 163086e..e29d9e7 100644
--- a/src/nvme/linux.c
+++ b/src/nvme/linux.c
@@ -124,7 +124,7 @@ 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)
{
- _cleanup_free_ struct nvme_id_ctrl *id_ctrl;
+ _cleanup_free_ struct nvme_id_ctrl *id_ctrl = NULL;
int err;
id_ctrl = __nvme_alloc(sizeof(*id_ctrl));
@@ -385,7 +385,7 @@ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
int nvme_get_ana_log_len(int fd, size_t *analen)
{
- _cleanup_free_ struct nvme_id_ctrl *ctrl;
+ _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
int ret;
ctrl = __nvme_alloc(sizeof(*ctrl));
@@ -405,7 +405,7 @@ int nvme_get_ana_log_len(int fd, size_t *analen)
int nvme_get_logical_block_size(int fd, __u32 nsid, int *blksize)
{
- _cleanup_free_ struct nvme_id_ns *ns;
+ _cleanup_free_ struct nvme_id_ns *ns = NULL;
__u8 flbas;
int ret;
@@ -426,7 +426,7 @@ int nvme_get_logical_block_size(int fd, __u32 nsid, int *blksize)
static int __nvme_set_attr(const char *path, const char *value)
{
- _cleanup_fd_ int fd;
+ _cleanup_fd_ int fd = -1;
fd = open(path, O_WRONLY);
if (fd < 0) {
@@ -725,7 +725,7 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac,
unsigned char *key)
{
const char hmac_seed[] = "NVMe-over-Fabrics";
- _cleanup_hmac_ctx_ HMAC_CTX *hmac_ctx;
+ _cleanup_hmac_ctx_ HMAC_CTX *hmac_ctx = NULL;
const EVP_MD *md;
ENGINE_load_builtin_engines();
@@ -881,7 +881,7 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac,
{
const char hmac_seed[] = "NVMe-over-Fabrics";
OSSL_PARAM params[2], *p = params;
- _cleanup_ossl_lib_ctx_ OSSL_LIB_CTX *lib_ctx;
+ _cleanup_ossl_lib_ctx_ OSSL_LIB_CTX *lib_ctx = NULL;
_cleanup_evp_mac_ctx_ EVP_MAC_CTX *mac_ctx = NULL;
_cleanup_evp_mac_ EVP_MAC *mac = NULL;
char *progq = NULL;
@@ -1104,6 +1104,11 @@ static size_t nvme_identity_len(int hmac, int version, const char *hostnqn,
{
size_t len;
+ if (!hostnqn || !subsysnqn) {
+ errno = EINVAL;
+ return -1;
+ }
+
len = strlen(hostnqn) + strlen(subsysnqn) + 12;
if (version == 1) {
len += 66;
diff --git a/src/nvme/mi.c b/src/nvme/mi.c
index 82ed88a..84d51b0 100644
--- a/src/nvme/mi.c
+++ b/src/nvme/mi.c
@@ -433,7 +433,8 @@ int nvme_mi_submit(nvme_mi_ep_t ep, struct nvme_mi_req *req,
rc = nvme_mi_verify_resp_mic(resp);
if (rc) {
nvme_msg(ep->root, LOG_WARNING, "crc mismatch\n");
- return rc;
+ errno = EBADMSG;
+ return -1;
}
}
diff --git a/src/nvme/nbft.c b/src/nvme/nbft.c
index 2c87088..f2ffc21 100644
--- a/src/nvme/nbft.c
+++ b/src/nvme/nbft.c
@@ -274,7 +274,29 @@ static int read_ssns(struct nbft_info *nbft,
ret = -EINVAL;
goto fail;
}
+ ssns->num_hfis = 1;
for (i = 0; i < le16_to_cpu(raw_ssns->secondary_hfi_assoc_obj.length); i++) {
+ bool duplicate = false;
+ int j;
+
+ for (j = 0; j < i; j++) {
+ if (ss_hfi_indexes[i] == ss_hfi_indexes[j]) {
+ duplicate = true;
+ break;
+ }
+ }
+
+ if (!duplicate &&
+ ss_hfi_indexes[i] == raw_ssns->primary_hfi_desc_index)
+ duplicate = true;
+
+ if (duplicate) {
+ nvme_msg(NULL, LOG_DEBUG,
+ "file %s: SSNS %d skipping duplicate HFI index %d\n",
+ nbft->filename, ssns->index, ss_hfi_indexes[i]);
+ continue;
+ }
+
ssns->hfis[i + 1] = hfi_from_index(nbft, ss_hfi_indexes[i]);
if (ss_hfi_indexes[i] && !ssns->hfis[i + 1])
nvme_msg(NULL, LOG_DEBUG,
diff --git a/src/nvme/private.h b/src/nvme/private.h
index ee9d738..3505802 100644
--- a/src/nvme/private.h
+++ b/src/nvme/private.h
@@ -17,9 +17,9 @@
#include "mi.h"
-extern const char *nvme_ctrl_sysfs_dir;
-extern const char *nvme_subsys_sysfs_dir;
-extern const char *nvme_ns_sysfs_dir;
+char *nvme_ctrl_sysfs_dir(void);
+char *nvme_subsys_sysfs_dir(void);
+char *nvme_ns_sysfs_dir(void);
struct nvme_path {
struct list_node entry;
@@ -125,6 +125,7 @@ struct nvme_host {
struct nvme_fabric_options {
bool cntlid;
+ bool concat;
bool ctrl_loss_tmo;
bool data_digest;
bool dhchap_ctrl_secret;
diff --git a/src/nvme/tree.c b/src/nvme/tree.c
index 07a3c53..344f8bc 100644
--- a/src/nvme/tree.c
+++ b/src/nvme/tree.c
@@ -61,7 +61,21 @@ struct candidate_args {
};
typedef bool (*ctrl_match_t)(struct nvme_ctrl *c, struct candidate_args *candidate);
-const char *nvme_slots_sysfs_dir = "/sys/bus/pci/slots";
+#define PATH_SYSFS_SLOTS "/sys/bus/pci/slots"
+
+static char *nvme_slots_sysfs_dir(void)
+{
+ char *basepath = getenv("LIBNVME_SYSFS_PATH");
+ char *str;
+
+ if (!basepath)
+ return strdup(PATH_SYSFS_SLOTS);
+
+ if (!asprintf(&str, "%s" PATH_SYSFS_SLOTS, basepath))
+ return NULL;
+
+ return str;
+}
static struct nvme_host *default_host;
@@ -122,7 +136,8 @@ static void cleanup_dirents(struct dirents *ents)
nvme_host_t nvme_default_host(nvme_root_t r)
{
struct nvme_host *h;
- _cleanup_free_ char *hostnqn, *hostid;
+ _cleanup_free_ char *hostnqn = NULL;
+ _cleanup_free_ char *hostid = NULL;
hostnqn = nvmf_hostnqn_from_file();
if (!hostnqn)
@@ -657,9 +672,10 @@ static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s,
static int nvme_init_subsystem(nvme_subsystem_t s, const char *name)
{
+ _cleanup_free_ char *subsys_dir = nvme_subsys_sysfs_dir();
char *path;
- if (asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name) < 0)
+ if (asprintf(&path, "%s/%s", subsys_dir, name) < 0)
return -1;
s->model = nvme_get_attr(path, "model");
@@ -700,11 +716,12 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
{
struct nvme_subsystem *s = NULL, *_s;
_cleanup_free_ char *path = NULL, *subsysnqn = NULL;
+ _cleanup_free_ char *subsys_dir = nvme_subsys_sysfs_dir();
nvme_host_t h = NULL;
int ret;
nvme_msg(r, LOG_DEBUG, "scan subsystem %s\n", name);
- ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name);
+ ret = asprintf(&path, "%s/%s", subsys_dir, name);
if (ret < 0)
return ret;
@@ -1686,6 +1703,7 @@ static int nvme_ctrl_scan_namespaces(nvme_root_t r, struct nvme_ctrl *c)
static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
const char *ctrl_name)
{
+ _cleanup_free_ char *subsys_dir = nvme_subsys_sysfs_dir();
_cleanup_dirents_ struct dirents subsys = {};
int i;
@@ -1696,7 +1714,7 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
struct stat st;
_cleanup_free_ char *path = NULL;
- if (asprintf(&path, "%s/%s/%s", nvme_subsys_sysfs_dir,
+ if (asprintf(&path, "%s/%s/%s", subsys_dir,
subsys.ents[i]->d_name, ctrl_name) < 0) {
errno = ENOMEM;
return NULL;
@@ -1712,18 +1730,19 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
static char *nvme_ctrl_lookup_phy_slot(nvme_root_t r, const char *address)
{
+ _cleanup_free_ char *slots_sysfs_dir = nvme_slots_sysfs_dir();
_cleanup_free_ char *target_addr = NULL;
- int ret;
_cleanup_dir_ DIR *slots_dir = NULL;
+ int ret;
struct dirent *entry;
if (!address)
return NULL;
- slots_dir = opendir(nvme_slots_sysfs_dir);
+ slots_dir = opendir(slots_sysfs_dir);
if (!slots_dir) {
nvme_msg(r, LOG_WARNING, "failed to open slots dir %s\n",
- nvme_slots_sysfs_dir);
+ slots_sysfs_dir);
return NULL;
}
@@ -1736,7 +1755,7 @@ static char *nvme_ctrl_lookup_phy_slot(nvme_root_t r, const char *address)
_cleanup_free_ char *addr = NULL;
ret = asprintf(&path, "%s/%s",
- nvme_slots_sysfs_dir, entry->d_name);
+ slots_sysfs_dir, entry->d_name);
if (ret < 0) {
errno = ENOMEM;
return NULL;
@@ -1798,10 +1817,11 @@ static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path,
int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance)
{
- nvme_subsystem_t s;
+ _cleanup_free_ char *ctrl_dir = nvme_ctrl_sysfs_dir();
_cleanup_free_ char *subsys_name = NULL;
- char *path;
_cleanup_free_ char *name = NULL;
+ nvme_subsystem_t s;
+ char *path;
int ret;
ret = asprintf(&name, "nvme%d", instance);
@@ -1809,7 +1829,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance)
errno = ENOMEM;
return -1;
}
- ret = asprintf(&path, "%s/nvme%d", nvme_ctrl_sysfs_dir, instance);
+ ret = asprintf(&path, "%s/nvme%d", ctrl_dir, instance);
if (ret < 0) {
errno = ENOMEM;
return ret;
@@ -1853,7 +1873,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s,
nvme_ctrl_t c, p;
_cleanup_free_ char *addr = NULL, *address = NULL;
char *a, *e;
- _cleanup_free_ char *transport;
+ _cleanup_free_ char *transport = NULL;
char *traddr = NULL, *trsvcid = NULL;
char *host_traddr = NULL, *host_iface = NULL;
int ret;
@@ -1953,10 +1973,11 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name)
_cleanup_free_ char *path = NULL;
_cleanup_free_ char *hostnqn = NULL, *hostid = NULL;
_cleanup_free_ char *subsysnqn = NULL, *subsysname = NULL;
+ _cleanup_free_ char *ctrl_dir = nvme_ctrl_sysfs_dir();
int ret;
nvme_msg(r, LOG_DEBUG, "scan controller %s\n", name);
- ret = asprintf(&path, "%s/%s", nvme_ctrl_sysfs_dir, name);
+ ret = asprintf(&path, "%s/%s", ctrl_dir, name);
if (ret < 0) {
errno = ENOMEM;
return NULL;
@@ -1989,7 +2010,7 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name)
}
subsysname = nvme_ctrl_lookup_subsystem_name(r, name);
if (!subsysname) {
- nvme_msg(r, LOG_ERR,
+ nvme_msg(r, LOG_DEBUG,
"failed to lookup subsystem for controller %s\n",
name);
errno = ENXIO;
@@ -2436,7 +2457,7 @@ static int nvme_ns_init(const char *path, struct nvme_ns *ns)
struct sysfs_attr_table base[] = {
{ &ns->nsid, nvme_strtou32, true, "nsid" },
{ &ns->lba_count, nvme_strtou64, true, "size" },
- { &ns->lba_size, nvme_strtou64, true, "queue/physical_block_size" },
+ { &ns->lba_size, nvme_strtou64, true, "queue/logical_block_size" },
{ ns->eui64, nvme_strtoeuid, false, "eui" },
{ ns->nguid, nvme_strtouuid, false, "nguid" },
{ ns->uuid, nvme_strtouuid, false, "uuid" }
@@ -2584,7 +2605,9 @@ static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, const char *
nvme_ns_t nvme_scan_namespace(const char *name)
{
- return __nvme_scan_namespace(nvme_ns_sysfs_dir, name);
+ _cleanup_free_ char *ns_dir = nvme_ns_sysfs_dir();
+
+ return __nvme_scan_namespace(ns_dir, name);
}
static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,
diff --git a/src/nvme/types.h b/src/nvme/types.h
index 29ac050..fe79b6e 100644
--- a/src/nvme/types.h
+++ b/src/nvme/types.h
@@ -161,6 +161,9 @@ enum nvme_csi {
* @NVME_REG_BPMBL: Boot Partition Memory Buffer Location
* @NVME_REG_CMBMSC: Controller Memory Buffer Memory Space Control
* @NVME_REG_CMBSTS: Controller Memory Buffer Status
+ * @NVME_REG_CMBEBS: Controller Memory Buffer Elasticity Buffer Size
+ * @NVME_REG_CMBSWTP: Controller Memory Buffer Sustained Write Throughput
+ * @NVME_REG_NSSD: NVM Subsystem Shutdown
* @NVME_REG_CRTO: Controller Ready Timeouts
* @NVME_REG_PMRCAP: Persistent Memory Capabilities
* @NVME_REG_PMRCTL: Persistent Memory Region Control
@@ -188,6 +191,9 @@ enum nvme_register_offsets {
NVME_REG_BPMBL = 0x0048,
NVME_REG_CMBMSC = 0x0050,
NVME_REG_CMBSTS = 0x0058,
+ NVME_REG_CMBEBS = 0x005c,
+ NVME_REG_CMBSWTP = 0x0060,
+ NVME_REG_NSSD = 0x0064,
NVME_REG_CRTO = 0x0068,
NVME_REG_PMRCAP = 0x0e00,
NVME_REG_PMRCTL = 0x0e04,
diff --git a/src/nvme/util.c b/src/nvme/util.c
index 45512ff..f091da7 100644
--- a/src/nvme/util.c
+++ b/src/nvme/util.c
@@ -757,7 +757,7 @@ char *kv_keymatch(const char *kv, const char *key)
static size_t read_file(const char * fname, char *buffer, size_t *bufsz)
{
char *p;
- _cleanup_file_ FILE *file;
+ _cleanup_file_ FILE *file = NULL;
size_t len;
file = fopen(fname, "re");
@@ -806,7 +806,7 @@ size_t get_entity_name(char *buffer, size_t bufsz)
size_t get_entity_version(char *buffer, size_t bufsz)
{
- _cleanup_file_ FILE *file;
+ _cleanup_file_ FILE *file = NULL;
size_t num_bytes = 0;
/* /proc/sys/kernel/ostype typically contains the string "Linux" */
@@ -928,7 +928,7 @@ int nvme_uuid_from_string(const char *str, unsigned char uuid[NVME_UUID_LEN])
int nvme_uuid_random(unsigned char uuid[NVME_UUID_LEN])
{
- _cleanup_fd_ int f;
+ _cleanup_fd_ int f = -1;
ssize_t n;
f = open("/dev/urandom", O_RDONLY);
@@ -951,6 +951,25 @@ int nvme_uuid_random(unsigned char uuid[NVME_UUID_LEN])
return 0;
}
+int nvme_uuid_find(struct nvme_id_uuid_list *uuid_list, const unsigned char uuid[NVME_UUID_LEN])
+{
+ const unsigned char uuid_end[NVME_UUID_LEN] = {0};
+
+ if ((!uuid_list) || (!uuid)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (int i = 0; i < NVME_ID_UUID_LIST_MAX; i++) {
+ if (memcmp(uuid, &uuid_list->entry[i].uuid, NVME_UUID_LEN) == 0)
+ return i + 1;
+ if (memcmp(uuid_end, &uuid_list->entry[i].uuid, NVME_UUID_LEN) == 0)
+ break;
+ }
+ errno = ENOENT;
+ return -1;
+}
+
#ifdef HAVE_NETDB
static bool _nvme_ipaddrs_eq(struct sockaddr *addr1, struct sockaddr *addr2)
{
diff --git a/src/nvme/util.h b/src/nvme/util.h
index 16d5b9c..517c696 100644
--- a/src/nvme/util.h
+++ b/src/nvme/util.h
@@ -667,6 +667,15 @@ int nvme_uuid_from_string(const char *str, unsigned char uuid[NVME_UUID_LEN]);
int nvme_uuid_random(unsigned char uuid[NVME_UUID_LEN]);
/**
+ * nvme_uuid_find - Find UUID position on UUID list
+ * @uuid_list: UUID list returned by identify UUID
+ * @uuid: Binary encoded input UUID
+ *
+ * Return: The array position where given UUID is present, or -1 on failure with errno set.
+ */
+int nvme_uuid_find(struct nvme_id_uuid_list *uuid_list, const unsigned char uuid[NVME_UUID_LEN]);
+
+/**
* nvme_ipaddrs_eq - Check if 2 IP addresses are equal.
* @addr1: IP address (can be IPv4 or IPv6)
* @addr2: IP address (can be IPv4 or IPv6)