Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sysfs tests #775

Merged
merged 5 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions scripts/collect-sysfs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later

filename=nvme-sysfs-$(hostname)-$(uname -r).tar.xz

declare -a dirs=(
"/sys/class/nvme"
"/sys/class/nvme-fabrics"
"/sys/class/nvme-generic"
"/sys/class/nvme-subsystem"
"/sys/bus/pci/slots"
)

files=""
for d in "${dirs[@]}"; do
files+="${d} "
for l in "${d}"/*; do
files+="$(readlink -f $l) "
done
done

tar -c -J -p -f "${filename}" ${files} 2> /dev/null
1 change: 1 addition & 0 deletions src/libnvme.map
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ LIBNVME_1_0 {
nvme_disconnect_ctrl;
nvme_dsm;
nvme_dump_config;
nvme_dump_tree;
nvme_errno_to_string;
nvme_first_host;
nvme_first_subsystem;
Expand Down
52 changes: 46 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 Expand Up @@ -1386,11 +1416,21 @@ static char *nvmf_read_file(const char *f, int len)

char *nvmf_hostnqn_from_file()
{
char *hostnqn = getenv("LIBNVME_HOSTNQN");

if (hostnqn)
return strdup(hostnqn);

return nvmf_read_file(NVMF_HOSTNQN_FILE, NVMF_NQN_SIZE);
}

char *nvmf_hostid_from_file()
{
char *hostid = getenv("LIBNVME_HOSTID");

if (hostid)
return strdup(hostid);

return nvmf_read_file(NVMF_HOSTID_FILE, NVMF_HOSTID_SIZE);
}

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
4 changes: 2 additions & 2 deletions src/nvme/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,9 +576,9 @@ int json_dump_tree(nvme_root_t r)
}
json_object_object_add(json_root, "hosts", host_array);

ret = json_object_to_fd(1, json_root, JSON_C_TO_STRING_PRETTY);
ret = json_object_to_fd(fileno(r->fp), json_root, JSON_C_TO_STRING_PRETTY);
if (ret < 0) {
nvme_msg(r, LOG_ERR, "Failed to write to stdout, %s\n",
nvme_msg(r, LOG_ERR, "Failed to write, %s\n",
json_util_get_last_err());
ret = -1;
errno = EIO;
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
4 changes: 4 additions & 0 deletions test/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,7 @@ endif

subdir('ioctl')
subdir('nbft')

if json_c_dep.found()
subdir('sysfs')
endif
Loading
Loading