]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
nvme: allow to overwrite base sysfs path
authorDaniel Wagner <dwagner@suse.de>
Tue, 30 Jan 2024 17:28:40 +0000 (18:28 +0100)
committerDaniel Wagner <wagi@monom.org>
Fri, 2 Feb 2024 07:28:06 +0000 (08:28 +0100)
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 <dwagner@suse.de>
src/nvme/fabrics.c
src/nvme/filters.c
src/nvme/private.h
src/nvme/tree.c

index a251ab2f8b00684c9e0db2244e9bab3b8c3993e6..981fc442d7da4a55ce1b409e39a652e079a2c25e 100644 (file)
@@ -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;
index b5959a8ef2952f4da072e4d6da6190ea30ec687b..312b8f6c896766e048552d451d2606da675cd787 100644 (file)
 #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)
index 8a37590c1b9d74f3a83db9a9ce70329222dbc612..35058020b33d39b4163347a27f972e8448c8f44b 100644 (file)
@@ -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;
index 4d58845474cfa902ffec3655068bbcce83f12938..024249eafe8d4b3e1b1014be8878e8c97e278025 100644 (file)
@@ -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,