Skip to content

Commit 11a0918

Browse files
dwsuseigaw
authored andcommitted
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 <[email protected]>
1 parent 6209257 commit 11a0918

4 files changed

Lines changed: 126 additions & 29 deletions

File tree

src/nvme/fabrics.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,12 +1188,27 @@ struct nvmf_discovery_log *nvmf_get_discovery_wargs(struct nvme_get_discovery_ar
11881188

11891189
#define PATH_UUID_IBM "/proc/device-tree/ibm,partition-uuid"
11901190

1191+
static char *uuid_ibm_filename(void)
1192+
{
1193+
char *basepath = getenv("LIBNVME_SYSFS_PATH");
1194+
char *str;
1195+
1196+
if (!basepath)
1197+
return strdup(PATH_UUID_IBM);
1198+
1199+
if (!asprintf(&str, "%s" PATH_UUID_IBM, basepath))
1200+
return NULL;
1201+
1202+
return str;
1203+
}
1204+
11911205
static int uuid_from_device_tree(char *system_uuid)
11921206
{
1193-
ssize_t len;
1207+
_cleanup_free_ char *filename = uuid_ibm_filename();
11941208
_cleanup_fd_ int f = -1;
1209+
ssize_t len;
11951210

1196-
f = open(PATH_UUID_IBM, O_RDONLY);
1211+
f = open(filename, O_RDONLY);
11971212
if (f < 0)
11981213
return -ENXIO;
11991214

@@ -1207,6 +1222,20 @@ static int uuid_from_device_tree(char *system_uuid)
12071222

12081223
#define PATH_DMI_ENTRIES "/sys/firmware/dmi/entries"
12091224

1225+
static char *dmi_entries_dir(void)
1226+
{
1227+
char *basepath = getenv("LIBNVME_SYSFS_PATH");
1228+
char *str;
1229+
1230+
if (!basepath)
1231+
return strdup(PATH_DMI_ENTRIES);
1232+
1233+
if (!asprintf(&str, "%s" PATH_DMI_ENTRIES, basepath))
1234+
return NULL;
1235+
1236+
return str;
1237+
}
1238+
12101239
/*
12111240
* See System Management BIOS (SMBIOS) Reference Specification
12121241
* 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)
12341263

12351264
static int uuid_from_dmi_entries(char *system_uuid)
12361265
{
1237-
int f;
12381266
_cleanup_dir_ DIR *d = NULL;
1267+
_cleanup_free_ char *entries_dir = dmi_entries_dir();
1268+
int f;
12391269
struct dirent *de;
12401270
char buf[512] = {0};
12411271

12421272
system_uuid[0] = '\0';
1243-
d = opendir(PATH_DMI_ENTRIES);
1273+
d = opendir(entries_dir);
12441274
if (!d)
12451275
return -ENXIO;
12461276
while ((de = readdir(d))) {
@@ -1249,7 +1279,7 @@ static int uuid_from_dmi_entries(char *system_uuid)
12491279

12501280
if (de->d_name[0] == '.')
12511281
continue;
1252-
sprintf(filename, "%s/%s/type", PATH_DMI_ENTRIES, de->d_name);
1282+
sprintf(filename, "%s/%s/type", entries_dir, de->d_name);
12531283
f = open(filename, O_RDONLY);
12541284
if (f < 0)
12551285
continue;
@@ -1261,7 +1291,7 @@ static int uuid_from_dmi_entries(char *system_uuid)
12611291
continue;
12621292
if (type != DMI_SYSTEM_INFORMATION)
12631293
continue;
1264-
sprintf(filename, "%s/%s/raw", PATH_DMI_ENTRIES, de->d_name);
1294+
sprintf(filename, "%s/%s/raw", entries_dir, de->d_name);
12651295
f = open(filename, O_RDONLY);
12661296
if (f < 0)
12671297
continue;

src/nvme/filters.c

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,53 @@
2121
#include "filters.h"
2222
#include "types.h"
2323
#include "util.h"
24+
#include "cleanup.h"
2425

25-
const char *nvme_ctrl_sysfs_dir = "/sys/class/nvme";
26-
const char *nvme_ns_sysfs_dir = "/sys/block";
27-
const char *nvme_subsys_sysfs_dir = "/sys/class/nvme-subsystem";
26+
#define PATH_SYSFS_NVME "/sys/class/nvme"
27+
#define PATH_SYSFS_NVME_SUBSYSTEM "/sys/class/nvme-subsystem"
28+
#define PATH_SYSFS_BLOCK "/sys/block"
29+
30+
char *nvme_ctrl_sysfs_dir(void)
31+
{
32+
char *basepath = getenv("LIBNVME_SYSFS_PATH");
33+
char *str;
34+
35+
if (!basepath)
36+
return strdup(PATH_SYSFS_NVME);
37+
38+
if (!asprintf(&str, "%s" PATH_SYSFS_NVME, basepath))
39+
return NULL;
40+
41+
return str;
42+
}
43+
44+
char *nvme_ns_sysfs_dir(void)
45+
{
46+
char *basepath = getenv("LIBNVME_SYSFS_PATH");
47+
char *str;
48+
49+
if (!basepath)
50+
return strdup(PATH_SYSFS_BLOCK);
51+
52+
if (!asprintf(&str, "%s" PATH_SYSFS_BLOCK, basepath))
53+
return NULL;
54+
55+
return str;
56+
}
57+
58+
char *nvme_subsys_sysfs_dir(void)
59+
{
60+
char *basepath = getenv("LIBNVME_SYSFS_PATH");
61+
char *str;
62+
63+
if (!basepath)
64+
return strdup(PATH_SYSFS_NVME_SUBSYSTEM);
65+
66+
if (!asprintf(&str, "%s" PATH_SYSFS_NVME_SUBSYSTEM, basepath))
67+
return NULL;
68+
69+
return str;
70+
}
2871

2972
int nvme_namespace_filter(const struct dirent *d)
3073
{
@@ -89,8 +132,9 @@ int nvme_subsys_filter(const struct dirent *d)
89132

90133
int nvme_scan_subsystems(struct dirent ***subsys)
91134
{
92-
return scandir(nvme_subsys_sysfs_dir, subsys, nvme_subsys_filter,
93-
alphasort);
135+
_cleanup_free_ char *dir = nvme_subsys_sysfs_dir();
136+
137+
return scandir(dir, subsys, nvme_subsys_filter, alphasort);
94138
}
95139

96140
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)
101145

102146
int nvme_scan_ctrls(struct dirent ***ctrls)
103147
{
104-
return scandir(nvme_ctrl_sysfs_dir, ctrls, nvme_ctrls_filter,
105-
alphasort);
148+
_cleanup_free_ char *dir = nvme_ctrl_sysfs_dir();
149+
150+
return scandir(dir, ctrls, nvme_ctrls_filter, alphasort);
106151
}
107152

108153
int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***paths)

src/nvme/private.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
#include "mi.h"
1818

1919

20-
extern const char *nvme_ctrl_sysfs_dir;
21-
extern const char *nvme_subsys_sysfs_dir;
22-
extern const char *nvme_ns_sysfs_dir;
20+
char *nvme_ctrl_sysfs_dir(void);
21+
char *nvme_subsys_sysfs_dir(void);
22+
char *nvme_ns_sysfs_dir(void);
2323

2424
struct nvme_path {
2525
struct list_node entry;

src/nvme/tree.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,21 @@ struct candidate_args {
6161
};
6262
typedef bool (*ctrl_match_t)(struct nvme_ctrl *c, struct candidate_args *candidate);
6363

64-
const char *nvme_slots_sysfs_dir = "/sys/bus/pci/slots";
64+
#define PATH_SYSFS_SLOTS "/sys/bus/pci/slots"
65+
66+
static char *nvme_slots_sysfs_dir(void)
67+
{
68+
char *basepath = getenv("LIBNVME_SYSFS_PATH");
69+
char *str;
70+
71+
if (!basepath)
72+
return strdup(PATH_SYSFS_SLOTS);
73+
74+
if (!asprintf(&str, "%s" PATH_SYSFS_SLOTS, basepath))
75+
return NULL;
76+
77+
return str;
78+
}
6579

6680
static struct nvme_host *default_host;
6781

@@ -658,9 +672,10 @@ static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s,
658672

659673
static int nvme_init_subsystem(nvme_subsystem_t s, const char *name)
660674
{
675+
_cleanup_free_ char *subsys_dir = nvme_subsys_sysfs_dir();
661676
char *path;
662677

663-
if (asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name) < 0)
678+
if (asprintf(&path, "%s/%s", subsys_dir, name) < 0)
664679
return -1;
665680

666681
s->model = nvme_get_attr(path, "model");
@@ -701,11 +716,12 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
701716
{
702717
struct nvme_subsystem *s = NULL, *_s;
703718
_cleanup_free_ char *path = NULL, *subsysnqn = NULL;
719+
_cleanup_free_ char *subsys_dir = nvme_subsys_sysfs_dir();
704720
nvme_host_t h = NULL;
705721
int ret;
706722

707723
nvme_msg(r, LOG_DEBUG, "scan subsystem %s\n", name);
708-
ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name);
724+
ret = asprintf(&path, "%s/%s", subsys_dir, name);
709725
if (ret < 0)
710726
return ret;
711727

@@ -1687,6 +1703,7 @@ static int nvme_ctrl_scan_namespaces(nvme_root_t r, struct nvme_ctrl *c)
16871703
static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
16881704
const char *ctrl_name)
16891705
{
1706+
_cleanup_free_ char *subsys_dir = nvme_subsys_sysfs_dir();
16901707
_cleanup_dirents_ struct dirents subsys = {};
16911708
int i;
16921709

@@ -1697,7 +1714,7 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
16971714
struct stat st;
16981715
_cleanup_free_ char *path = NULL;
16991716

1700-
if (asprintf(&path, "%s/%s/%s", nvme_subsys_sysfs_dir,
1717+
if (asprintf(&path, "%s/%s/%s", subsys_dir,
17011718
subsys.ents[i]->d_name, ctrl_name) < 0) {
17021719
errno = ENOMEM;
17031720
return NULL;
@@ -1713,18 +1730,19 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
17131730

17141731
static char *nvme_ctrl_lookup_phy_slot(nvme_root_t r, const char *address)
17151732
{
1733+
_cleanup_free_ char *slots_sysfs_dir = nvme_slots_sysfs_dir();
17161734
_cleanup_free_ char *target_addr = NULL;
1717-
int ret;
17181735
_cleanup_dir_ DIR *slots_dir = NULL;
1736+
int ret;
17191737
struct dirent *entry;
17201738

17211739
if (!address)
17221740
return NULL;
17231741

1724-
slots_dir = opendir(nvme_slots_sysfs_dir);
1742+
slots_dir = opendir(slots_sysfs_dir);
17251743
if (!slots_dir) {
17261744
nvme_msg(r, LOG_WARNING, "failed to open slots dir %s\n",
1727-
nvme_slots_sysfs_dir);
1745+
slots_sysfs_dir);
17281746
return NULL;
17291747
}
17301748

@@ -1737,7 +1755,7 @@ static char *nvme_ctrl_lookup_phy_slot(nvme_root_t r, const char *address)
17371755
_cleanup_free_ char *addr = NULL;
17381756

17391757
ret = asprintf(&path, "%s/%s",
1740-
nvme_slots_sysfs_dir, entry->d_name);
1758+
slots_sysfs_dir, entry->d_name);
17411759
if (ret < 0) {
17421760
errno = ENOMEM;
17431761
return NULL;
@@ -1799,18 +1817,19 @@ static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path,
17991817

18001818
int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance)
18011819
{
1802-
nvme_subsystem_t s;
1820+
_cleanup_free_ char *ctrl_dir = nvme_ctrl_sysfs_dir();
18031821
_cleanup_free_ char *subsys_name = NULL;
1804-
char *path;
18051822
_cleanup_free_ char *name = NULL;
1823+
nvme_subsystem_t s;
1824+
char *path;
18061825
int ret;
18071826

18081827
ret = asprintf(&name, "nvme%d", instance);
18091828
if (ret < 0) {
18101829
errno = ENOMEM;
18111830
return -1;
18121831
}
1813-
ret = asprintf(&path, "%s/nvme%d", nvme_ctrl_sysfs_dir, instance);
1832+
ret = asprintf(&path, "%s/nvme%d", ctrl_dir, instance);
18141833
if (ret < 0) {
18151834
errno = ENOMEM;
18161835
return ret;
@@ -1954,10 +1973,11 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name)
19541973
_cleanup_free_ char *path = NULL;
19551974
_cleanup_free_ char *hostnqn = NULL, *hostid = NULL;
19561975
_cleanup_free_ char *subsysnqn = NULL, *subsysname = NULL;
1976+
_cleanup_free_ char *ctrl_dir = nvme_ctrl_sysfs_dir();
19571977
int ret;
19581978

19591979
nvme_msg(r, LOG_DEBUG, "scan controller %s\n", name);
1960-
ret = asprintf(&path, "%s/%s", nvme_ctrl_sysfs_dir, name);
1980+
ret = asprintf(&path, "%s/%s", ctrl_dir, name);
19611981
if (ret < 0) {
19621982
errno = ENOMEM;
19631983
return NULL;
@@ -2585,7 +2605,9 @@ static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, const char *
25852605

25862606
nvme_ns_t nvme_scan_namespace(const char *name)
25872607
{
2588-
return __nvme_scan_namespace(nvme_ns_sysfs_dir, name);
2608+
_cleanup_free_ char *ns_dir = nvme_ns_sysfs_dir();
2609+
2610+
return __nvme_scan_namespace(ns_dir, name);
25892611
}
25902612

25912613
static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,

0 commit comments

Comments
 (0)