diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-07-26 05:25:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-07-26 05:25:24 +0000 |
commit | acf73199fa227b97217238334236af367c8ab2d7 (patch) | |
tree | b6812bd6cbe6b977884ec94def20de59555983d5 /src/nvme/tree.c | |
parent | Adding upstream version 1.0. (diff) | |
download | libnvme-a8ab4da9e004c83c3b8a68f348b1cd00b984fe86.tar.xz libnvme-a8ab4da9e004c83c3b8a68f348b1cd00b984fe86.zip |
Adding upstream version 1.1~rc0.upstream/1.1_rc0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/nvme/tree.c')
-rw-r--r-- | src/nvme/tree.c | 108 |
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; } |