From 678392aa6bef5e30cb1b9452978fd0b2ce56c2ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 19 Feb 2024 11:38:02 +0100 Subject: Merging upstream version 1.8. Signed-off-by: Daniel Baumann --- src/libnvme.map | 6 +++++ src/nvme/fabrics.c | 67 +++++++++++++++++++++++++++++++++++++++++++++--------- src/nvme/fabrics.h | 2 ++ src/nvme/filters.c | 59 +++++++++++++++++++++++++++++++++++++++++------ src/nvme/json.c | 8 +++++-- src/nvme/linux.c | 17 +++++++++----- src/nvme/mi.c | 3 ++- src/nvme/nbft.c | 22 ++++++++++++++++++ src/nvme/private.h | 7 +++--- src/nvme/tree.c | 57 ++++++++++++++++++++++++++++++++-------------- src/nvme/types.h | 6 +++++ src/nvme/util.c | 25 +++++++++++++++++--- src/nvme/util.h | 9 ++++++++ 13 files changed, 238 insertions(+), 50 deletions(-) (limited to 'src') 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 @@ -666,6 +666,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) -- cgit v1.2.3