From: Daniel Wagner Date: Tue, 30 Jan 2024 17:28:40 +0000 (+0100) Subject: nvme: allow to overwrite base sysfs path X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=11a0918a9972;p=users%2Fsagi%2Flibnvme.git nvme: allow to overwrite base sysfs path In order to be able to test the topology scan code, make the lookup paths flexible. Check if the LIBNVME_SYSFS_PATH environment variable is set and if so use this as base path. We could also introduce a setter for this, but this is really a debugging interface and thus I don't really want it to be visible in the public API. Signed-off-by: Daniel Wagner --- diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index a251ab2f..981fc442 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -1188,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) { - ssize_t len; + _cleanup_free_ char *filename = uuid_ibm_filename(); _cleanup_fd_ int f = -1; + ssize_t len; - f = open(PATH_UUID_IBM, O_RDONLY); + f = open(filename, O_RDONLY); if (f < 0) return -ENXIO; @@ -1207,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 @@ -1234,13 +1263,14 @@ static bool is_dmi_uuid_valid(const char *buf, size_t len) static int uuid_from_dmi_entries(char *system_uuid) { - int f; _cleanup_dir_ DIR *d = NULL; + _cleanup_free_ char *entries_dir = dmi_entries_dir(); + int f; 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))) { @@ -1249,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; @@ -1261,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; diff --git a/src/nvme/filters.c b/src/nvme/filters.c index b5959a8e..312b8f6c 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/private.h b/src/nvme/private.h index 8a37590c..35058020 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; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 4d588454..024249ea 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; @@ -658,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"); @@ -701,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; @@ -1687,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; @@ -1697,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; @@ -1713,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; } @@ -1737,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; @@ -1799,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); @@ -1810,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; @@ -1954,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; @@ -2585,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,