#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;
#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
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))) {
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;
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;
#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)
{
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)
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)
};
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;
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");
{
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;
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;
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;
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;
}
_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;
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);
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;
_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;
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,