Skip to content

Commit

Permalink
nvme: allow to overwrite base sysfs path
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
igaw committed Jan 30, 2024
1 parent 0ec87e7 commit 550d6fe
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 29 deletions.
42 changes: 36 additions & 6 deletions src/nvme/fabrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand Down Expand Up @@ -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))) {
Expand All @@ -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;
Expand All @@ -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;
Expand Down
59 changes: 52 additions & 7 deletions src/nvme/filters.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions src/nvme/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
48 changes: 35 additions & 13 deletions src/nvme/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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;
}

Expand All @@ -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;
Expand Down Expand Up @@ -1799,18 +1817,19 @@ 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);
if (ret < 0) {
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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 550d6fe

Please sign in to comment.