summaryrefslogtreecommitdiffstats
path: root/src/nvme/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvme/tree.c')
-rw-r--r--src/nvme/tree.c108
1 files changed, 71 insertions, 37 deletions
diff --git a/src/nvme/tree.c b/src/nvme/tree.c
index a2cfa6a..9161791 100644
--- a/src/nvme/tree.c
+++ b/src/nvme/tree.c
@@ -141,6 +141,7 @@ nvme_root_t nvme_create_root(FILE *fp, int log_level)
if (fp)
r->fp = fp;
list_head_init(&r->hosts);
+ list_head_init(&r->endpoints);
return r;
}
@@ -414,7 +415,8 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h,
struct nvme_subsystem *s;
nvme_for_each_subsystem(h, s) {
- if (strcmp(s->subsysnqn, subsysnqn))
+ if (subsysnqn && s->subsysnqn &&
+ strcmp(s->subsysnqn, subsysnqn))
continue;
if (name && s->name &&
strcmp(s->name, name))
@@ -578,6 +580,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
nvme_msg(r, LOG_WARNING, "NQN mismatch for subsystem '%s'\n",
name);
s = NULL;
+ free(subsysnqn);
errno = EINVAL;
return -1;
}
@@ -957,6 +960,8 @@ static bool traddr_is_hostname(const char *transport, const char *traddr)
if (!traddr || !transport)
return false;
+ if (!strcmp(traddr, "none"))
+ return false;
if (strcmp(transport, "tcp") &&
strcmp(transport, "rdma"))
return false;
@@ -1018,17 +1023,14 @@ struct nvme_ctrl *nvme_create_ctrl(nvme_root_t r,
return c;
}
-nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport,
- const char *traddr, const char *host_traddr,
- const char *host_iface, const char *trsvcid,
- nvme_ctrl_t p)
+nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport,
+ const char *traddr, const char *host_traddr,
+ const char *host_iface, const char *trsvcid,
+ nvme_ctrl_t p)
+
{
- nvme_root_t r;
struct nvme_ctrl *c;
- if (!s || !transport)
- return NULL;
- r = s->h ? s->h->r : NULL;
c = p ? nvme_subsystem_next_ctrl(s, p) : nvme_subsystem_first_ctrl(s);
for (; c != NULL; c = nvme_subsystem_next_ctrl(s, c)) {
if (strcmp(c->transport, transport))
@@ -1047,6 +1049,27 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport,
continue;
return c;
}
+
+ return NULL;
+}
+
+nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport,
+ const char *traddr, const char *host_traddr,
+ const char *host_iface, const char *trsvcid,
+ nvme_ctrl_t p)
+{
+ nvme_root_t r;
+ struct nvme_ctrl *c;
+
+ if (!s || !transport)
+ return NULL;
+
+ c = __nvme_lookup_ctrl(s, transport, traddr, host_traddr,
+ host_iface, trsvcid, p);
+ if (c)
+ return c;
+
+ r = s->h ? s->h->r : NULL;
c = nvme_create_ctrl(r, s->subsysnqn, transport, traddr,
host_traddr, host_iface, trsvcid);
if (c) {
@@ -1092,20 +1115,26 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r,
struct dirent **subsys;
char *subsys_name = NULL;
int ret, i;
- char path[PATH_MAX];
ret = nvme_scan_subsystems(&subsys);
if (ret < 0)
return NULL;
for (i = 0; i < ret; i++) {
struct stat st;
+ char *path;
- sprintf(path, "%s/%s/%s", nvme_subsys_sysfs_dir,
- subsys[i]->d_name, ctrl_name);
+ if (asprintf(&path, "%s/%s/%s", nvme_subsys_sysfs_dir,
+ subsys[i]->d_name, ctrl_name) < 0) {
+ errno = ENOMEM;
+ return NULL;
+ }
nvme_msg(r, LOG_DEBUG, "lookup subsystem %s\n", path);
- if (stat(path, &st) < 0)
+ if (stat(path, &st) < 0) {
+ free(path);
continue;
+ }
subsys_name = strdup(subsys[i]->d_name);
+ free(path);
break;
}
nvme_free_dirents(subsys, ret);
@@ -1293,12 +1322,10 @@ skip_address:
free(transport);
if (address)
free(address);
- if (!c) {
- if (!p) {
- nvme_msg(r, LOG_ERR, "failed to lookup ctrl\n");
- errno = ENODEV;
- } else
- errno = ENOMEM;
+ if (!c && !p) {
+ nvme_msg(r, LOG_ERR, "failed to lookup ctrl\n");
+ errno = ENODEV;
+ free(addr);
return NULL;
}
c->address = addr;
@@ -1360,6 +1387,7 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name)
nvme_msg(r, LOG_ERR,
"failed to lookup subsystem for controller %s\n",
name);
+ free(subsysnqn);
free(path);
errno = ENXIO;
return NULL;
@@ -1815,7 +1843,7 @@ nvme_ns_t nvme_scan_namespace(const char *name)
static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,
char *name)
{
- struct nvme_ns *n;
+ struct nvme_ns *n, *_n, *__n;
nvme_msg(r, LOG_DEBUG, "scan controller %s namespace %s\n",
c->name, name);
@@ -1829,7 +1857,11 @@ static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,
nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s\n", name);
return -1;
}
-
+ nvme_ctrl_for_each_ns_safe(c, _n, __n) {
+ if (strcmp(n->name, _n->name))
+ continue;
+ __nvme_free_ns(_n);
+ }
n->s = c->s;
n->c = c;
list_add(&c->namespaces, &n->entry);
@@ -1865,7 +1897,7 @@ static void nvme_subsystem_set_ns_path(nvme_subsystem_t s, nvme_ns_t n)
static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
char *name, nvme_scan_filter_t f, void *f_args)
{
- struct nvme_ns *n;
+ struct nvme_ns *n, *_n, *__n;
nvme_msg(r, LOG_DEBUG, "scan subsystem %s namespace %s\n",
s->name, name);
@@ -1879,6 +1911,19 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
__nvme_free_ns(n);
return 0;
}
+ nvme_subsystem_for_each_ns_safe(s, _n, __n) {
+ struct nvme_path *p, *_p;
+
+ if (strcmp(n->name, _n->name))
+ continue;
+ /* Detach paths */
+ nvme_namespace_for_each_path_safe(_n, p, _p) {
+ list_del_init(&p->nentry);
+ p->n = NULL;
+ }
+ list_head_init(&_n->paths);
+ __nvme_free_ns(_n);
+ }
n->s = s;
list_add(&s->namespaces, &n->entry);
nvme_subsystem_set_ns_path(s, n);
@@ -1888,22 +1933,11 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
struct nvme_ns *nvme_subsystem_lookup_namespace(struct nvme_subsystem *s,
__u32 nsid)
{
- nvme_root_t r = s->h ? s->h->r : NULL;
struct nvme_ns *n;
- char *name;
- int ret;
- ret = asprintf(&name, "%sn%u", s->name, nsid);
- if (ret < 0)
- return NULL;
- n = __nvme_scan_namespace(s->sysfs_dir, name);
- free(name);
- if (!n) {
- nvme_msg(r, LOG_DEBUG, "failed to scan namespace %d\n", nsid);
- return NULL;
+ nvme_subsystem_for_each_ns(s, n) {
+ if (nvme_ns_get_nsid(n) == nsid)
+ return n;
}
-
- n->s = s;
- list_add(&s->namespaces, &n->entry);
- return n;
+ return NULL;
}