]> www.infradead.org Git - users/hch/nvme-cli.git/commitdiff
Relocate functions and constants to the files that use them
authorKeith Busch <kbusch@kernel.org>
Mon, 4 Nov 2019 14:50:34 +0000 (23:50 +0900)
committerKeith Busch <kbusch@kernel.org>
Thu, 7 Nov 2019 23:36:44 +0000 (08:36 +0900)
Make more things static helps reduce what exports need to be tracked.

Signed-off-by: Keith Busch <kbusch@kernel.org>
fabrics.c
linux/nvme.h
nvme-print.c
nvme-print.h
nvme-topology.c
nvme.c
nvme.h
plugins/huawei/huawei-nvme.c

index 5cc6181caafe4c91d39774170f27d1a2d6440017..655bd36c5639911fa471d9abbc0abe34ece8447e 100644 (file)
--- a/fabrics.c
+++ b/fabrics.c
 
 #define NVMF_HOSTID_SIZE       36
 
+const char *conarg_nqn = "nqn";
+const char *conarg_transport = "transport";
+const char *conarg_traddr = "traddr";
+const char *conarg_trsvcid = "trsvcid";
+const char *conarg_host_traddr = "host_traddr";
+
 static struct config {
        char *nqn;
        char *transport;
@@ -76,6 +82,14 @@ static struct config {
        bool quiet;
 } cfg = { NULL };
 
+struct connect_args {
+       char *subsysnqn;
+       char *transport;
+       char *traddr;
+       char *trsvcid;
+       char *host_traddr;
+};
+
 #define BUF_SIZE               4096
 #define PATH_NVME_FABRICS      "/dev/nvme-fabrics"
 #define PATH_NVMF_DISC         "/etc/nvme/discovery.conf"
@@ -201,7 +215,7 @@ static int do_discover(char *argstr, bool connect);
  * If field found, return string containing field value. If field
  * not found, return an empty string.
  */
-char *__parse_connect_arg(char *conargs, const char delim, const char *fieldnm)
+static char *parse_conn_arg(char *conargs, const char delim, const char *field)
 {
        char *s, *e;
        size_t cnt;
@@ -215,13 +229,13 @@ char *__parse_connect_arg(char *conargs, const char delim, const char *fieldnm)
         * However, better to be prepared.
         */
        do {
-               s = strstr(conargs, fieldnm);
+               s = strstr(conargs, field);
                if (!s)
                        goto empty_field;
                /* validate prior character is delimiter */
                if (s == conargs || *(s - 1) == delim) {
                        /* match requires next character to be assignment */
-                       s += strlen(fieldnm);
+                       s += strlen(field);
                        if (*s == '=')
                                /* match */
                                break;
@@ -260,6 +274,86 @@ static int ctrl_instance(char *device)
        return instance;
 }
 
+/*
+ * Given a controller name, create a connect_args with its
+ * attributes and compare the attributes against the connect args
+ * given.
+ * Return true/false based on whether it matches
+ */
+static bool ctrl_matches_connectargs(char *name, struct connect_args *args)
+{
+       struct connect_args cargs;
+       bool found = false;
+       char *path, *addr;
+       int ret;
+
+       ret = asprintf(&path, "%s/%s", SYS_NVME, name);
+       if (ret < 0)
+               return found;
+
+       addr = nvme_get_ctrl_attr(path, "address");
+       cargs.subsysnqn = nvme_get_ctrl_attr(path, "subsysnqn");
+       cargs.transport = nvme_get_ctrl_attr(path, "transport");
+       cargs.traddr = parse_conn_arg(addr, ' ', conarg_traddr);
+       cargs.trsvcid = parse_conn_arg(addr, ' ', conarg_trsvcid);
+       cargs.host_traddr = parse_conn_arg(addr, ' ', conarg_host_traddr);
+
+       if (!strcmp(cargs.subsysnqn, args->subsysnqn) &&
+           !strcmp(cargs.transport, args->transport) &&
+           (!strcmp(cargs.traddr, args->traddr) ||
+            !strcmp(args->traddr, "none")) &&
+           (!strcmp(cargs.trsvcid, args->trsvcid) ||
+            !strcmp(args->trsvcid, "none")) &&
+           (!strcmp(cargs.host_traddr, args->host_traddr) ||
+            !strcmp(args->host_traddr, "none")))
+               found = true;
+
+       free(cargs.subsysnqn);
+       free(cargs.transport);
+       free(cargs.traddr);
+       free(cargs.trsvcid);
+       free(cargs.host_traddr);
+
+       return found;
+}
+
+/*
+ * Look through the system to find an existing controller whose
+ * attributes match the connect arguments specified
+ * If found, a string containing the controller name (ex: "nvme?")
+ * is returned.
+ * If not found, a NULL is returned.
+ */
+static char *find_ctrl_with_connectargs(struct connect_args *args)
+{
+       struct dirent **devices;
+       char *devname = NULL;
+       int i, n;
+
+       n = scandir(SYS_NVME, &devices, scan_ctrls_filter, alphasort);
+       if (n < 0) {
+               fprintf(stderr, "no NVMe controller(s) detected.\n");
+               return NULL;
+       }
+
+       for (i = 0; i < n; i++) {
+               if (ctrl_matches_connectargs(devices[i]->d_name, args)) {
+                       devname = strdup(devices[i]->d_name);
+                       if (devname == NULL)
+                               fprintf(stderr, "no memory for ctrl name %s\n",
+                                               devices[i]->d_name);
+                       goto cleanup_devices;
+               }
+       }
+
+cleanup_devices:
+       for (i = 0; i < n; i++)
+               free(devices[i]);
+       free(devices);
+
+       return devname;
+}
+
 static int add_ctrl(const char *argstr)
 {
        substring_t args[MAX_OPT_ARGS];
@@ -984,8 +1078,6 @@ static int connect_ctrls(struct nvmf_disc_rsp_page_hdr *log, int numrec)
        return ret;
 }
 
-static const char delim_comma  = ',';
-
 static int do_discover(char *argstr, bool connect)
 {
        struct nvmf_disc_rsp_page_hdr *log = NULL;
@@ -997,16 +1089,11 @@ static int do_discover(char *argstr, bool connect)
                struct connect_args cargs;
 
                memset(&cargs, 0, sizeof(cargs));
-               cargs.subsysnqn = __parse_connect_arg(argstr, delim_comma,
-                                               conarg_nqn);
-               cargs.transport = __parse_connect_arg(argstr, delim_comma,
-                                               conarg_transport);
-               cargs.traddr = __parse_connect_arg(argstr, delim_comma,
-                                               conarg_traddr);
-               cargs.trsvcid = __parse_connect_arg(argstr, delim_comma,
-                                               conarg_trsvcid);
-               cargs.host_traddr = __parse_connect_arg(argstr, delim_comma,
-                                               conarg_host_traddr);
+               cargs.subsysnqn = parse_conn_arg(argstr, '.', conarg_nqn);
+               cargs.transport = parse_conn_arg(argstr, '.', conarg_transport);
+               cargs.traddr = parse_conn_arg(argstr, '.', conarg_traddr);
+               cargs.trsvcid = parse_conn_arg(argstr, '.', conarg_trsvcid);
+               cargs.host_traddr = parse_conn_arg(argstr, '.', conarg_host_traddr);
 
                /*
                 * if the cfg.device passed in matches the connect args
@@ -1386,34 +1473,38 @@ out:
 
 int disconnect_all(const char *desc, int argc, char **argv)
 {
-       struct subsys_list_item *slist;
-       int i, j, ret, subcnt = 0;
+       struct nvme_topology t = { };
+       int i, j, err;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       ret = argconfig_parse(argc, argv, desc, opts);
-       if (ret)
+       err = argconfig_parse(argc, argv, desc, opts);
+       if (err)
+               goto out;
+
+       err = scan_subsystems(&t, NULL, 0);
+       if (err) {
+               fprintf(stderr, "Failed to scan namespaces\n");
                goto out;
+       }
 
-       slist = get_subsys_list(&subcnt, NULL, NVME_NSID_ALL);
-       for (i = 0; i < subcnt; i++) {
-               struct subsys_list_item *subsys = &slist[i];
+       for (i = 0; i < t.nr_subsystems; i++) {
+               struct nvme_subsystem *s = &t.subsystems[i];
 
-               for (j = 0; j < subsys->nctrls; j++) {
-                       struct ctrl_list_item *ctrl = &subsys->ctrls[j];
-                       if (!strcmp(ctrl->transport, "pcie"))
-                               continue;
+               for (j = 0; j < s->nr_ctrls; j++) {
+                       struct nvme_ctrl *c = &s->ctrls[j];
 
-                       ret = disconnect_by_device(ctrl->name);
-                       if (ret)
+                       if (!strcmp(c->transport, "pcie"))
+                               continue;
+                       err = disconnect_by_device(c->name);
+                       if (err)
                                goto free;
                }
        }
-
 free:
-       free_subsys_list(slist, subcnt);
+       free_topology(&t);
 out:
-       return nvme_status_to_errno(ret, true);
+       return nvme_status_to_errno(err, true);
 }
index ffb8eed7acba0dc7f23c26098fee116c6e9219a2..2b9dc77b776ece23aed25745b49bc23d613dc628 100644 (file)
@@ -25,6 +25,37 @@ typedef struct {
 } uuid_t;
 #endif
 
+#ifdef __CHECKER__
+#define __force       __attribute__((force))
+#else
+#define __force
+#endif
+
+static inline __le16 cpu_to_le16(uint16_t x)
+{
+       return (__force __le16)htole16(x);
+}
+static inline __le32 cpu_to_le32(uint32_t x)
+{
+       return (__force __le32)htole32(x);
+}
+static inline __le64 cpu_to_le64(uint64_t x)
+{
+       return (__force __le64)htole64(x);
+}
+
+static inline uint16_t le16_to_cpu(__le16 x)
+{
+       return le16toh((__force __u16)x);
+}
+static inline uint32_t le32_to_cpu(__le32 x)
+{
+       return le32toh((__force __u32)x);
+}
+static inline uint64_t le64_to_cpu(__le64 x)
+{
+       return le64toh((__force __u64)x);
+}
 
 /* NQN names in commands fields specified one size */
 #define NVMF_NQN_FIELD_LEN     256
@@ -1225,38 +1256,6 @@ static inline bool is_64bit_reg(__u32 offset)
        return false;
 }
 
-#ifdef __CHECKER__
-#define __force       __attribute__((force))
-#else
-#define __force
-#endif
-
-static inline __le16 cpu_to_le16(uint16_t x)
-{
-       return (__force __le16)htole16(x);
-}
-static inline __le32 cpu_to_le32(uint32_t x)
-{
-       return (__force __le32)htole32(x);
-}
-static inline __le64 cpu_to_le64(uint64_t x)
-{
-       return (__force __le64)htole64(x);
-}
-
-static inline uint16_t le16_to_cpu(__le16 x)
-{
-       return le16toh((__force __u16)x);
-}
-static inline uint32_t le32_to_cpu(__le32 x)
-{
-       return le32toh((__force __u32)x);
-}
-static inline uint64_t le64_to_cpu(__le64 x)
-{
-       return le64toh((__force __u64)x);
-}
-
 enum {
        NVME_SCT_GENERIC                = 0x0,
        NVME_SCT_CMD_SPECIFIC           = 0x1,
index baa61950397b40eb2b8cbd9ff05b47bddef7b6ab..ca233a5320b7247c8baee54c3e73f527a30d98c2 100644 (file)
@@ -844,62 +844,59 @@ static void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
        json_free_object(root);
 }
 
-static void nvme_show_subsystem(struct subsys_list_item *item)
+static void nvme_show_subsystem(struct nvme_subsystem *s)
 {
        int i;
 
-       printf("%s - NQN=%s\n", item->name, item->subsysnqn);
+       printf("%s - NQN=%s\n", s->name, s->subsysnqn);
        printf("\\\n");
 
-       for (i = 0; i < item->nctrls; i++) {
-               printf(" +- %s %s %s %s %s\n", item->ctrls[i].name,
-                               item->ctrls[i].transport,
-                               item->ctrls[i].address,
-                               item->ctrls[i].state,
-                               item->ctrls[i].ana_state ?
-                                       item->ctrls[i].ana_state : "");
+       for (i = 0; i < s->nr_ctrls; i++) {
+               printf(" +- %s %s %s %s %s\n", s->ctrls[i].name,
+                               s->ctrls[i].transport,
+                               s->ctrls[i].address,
+                               s->ctrls[i].state,
+                               s->ctrls[i].ana_state ? : "");
        }
 }
 
-static void json_print_nvme_subsystem_list(struct subsys_list_item *slist,
-                                          int n)
+static void json_print_nvme_subsystem_list(struct nvme_topology *t)
 {
+       struct json_object *subsystem_attrs, *path_attrs;
+       struct json_array *subsystems, *paths;
        struct json_object *root;
-       struct json_array *subsystems;
-       struct json_object *subsystem_attrs;
-       struct json_array *paths;
-       struct json_object *path_attrs;
        int i, j;
 
        root = json_create_object();
        subsystems = json_create_array();
 
-       for (i = 0; i < n; i++) {
-               subsystem_attrs = json_create_object();
+       for (i = 0; i < t->nr_subsystems; i++) {
+               struct nvme_subsystem *s = &t->subsystems[i];
 
+               subsystem_attrs = json_create_object();
                json_object_add_value_string(subsystem_attrs,
-                                            "Name", slist[i].name);
+                                            "Name", s->name);
                json_object_add_value_string(subsystem_attrs,
-                                            "NQN", slist[i].subsysnqn);
+                                            "NQN", s->subsysnqn);
 
                json_array_add_value_object(subsystems, subsystem_attrs);
 
                paths = json_create_array();
+               for (j = 0; j < s->nr_ctrls; j++) {
+                       struct nvme_ctrl *c = &s->ctrls[j];
 
-               for (j = 0; j < slist[i].nctrls; j++) {
                        path_attrs = json_create_object();
                        json_object_add_value_string(path_attrs, "Name",
-                                       slist[i].ctrls[j].name);
+                                       c->name);
                        json_object_add_value_string(path_attrs, "Transport",
-                                       slist[i].ctrls[j].transport);
+                                       c->transport);
                        json_object_add_value_string(path_attrs, "Address",
-                                       slist[i].ctrls[j].address);
+                                       c->address);
                        json_object_add_value_string(path_attrs, "State",
-                                       slist[i].ctrls[j].state);
-                       if (slist[i].ctrls[j].ana_state)
+                                       c->state);
+                       if (c->ana_state)
                                json_object_add_value_string(path_attrs,
-                                               "ANAState",
-                                               slist[i].ctrls[j].ana_state);
+                                               "ANAState", c->ana_state);
                        json_array_add_value_object(paths, path_attrs);
                }
                if (j)
@@ -914,16 +911,16 @@ static void json_print_nvme_subsystem_list(struct subsys_list_item *slist,
        json_free_object(root);
 }
 
-void nvme_show_subsystem_list(struct subsys_list_item *slist, int n,
-                            enum nvme_print_flags flags)
+void nvme_show_subsystem_list(struct nvme_topology *t,
+                             enum nvme_print_flags flags)
 {
        int i;
 
        if (flags & JSON)
-               return json_print_nvme_subsystem_list(slist, n);
+               return json_print_nvme_subsystem_list(t);
 
-       for (i = 0; i < n; i++)
-               nvme_show_subsystem(&slist[i]);
+       for (i = 0; i < t->nr_subsystems; i++)
+               nvme_show_subsystem(&t->subsystems[i]);
 }
 
 static void nvme_show_registers_cap(struct nvme_bar_cap *cap)
@@ -1593,26 +1590,29 @@ void nvme_show_relatives(const char *name)
                return;
 
        if (block) {
+               struct nvme_topology t = { };
                char *subsysnqn;
-               struct subsys_list_item *slist;
-               int subcnt = 0;
+               int err;
 
                subsysnqn = get_nvme_subsnqn(path);
-               if (!subsysnqn)
+               if (!subsysnqn) {
+                       free(path);
                        return;
-               slist = get_subsys_list(&subcnt, subsysnqn, nsid);
-               if (subcnt != 1) {
+               }
+               err = scan_subsystems(&t, subsysnqn, 0);
+               if (err || t.nr_subsystems != 1) {
                        free(subsysnqn);
                        free(path);
                        return;
                }
 
                fprintf(stderr, "Namespace %s has parent controller(s):", name);
-               for (i = 0; i < slist[0].nctrls; i++)
+               for (i = 0; i < t.subsystems[0].nr_ctrls; i++)
                        fprintf(stderr, "%s%s", i ? ", " : "",
-                               slist[0].ctrls[i].name);
+                               t.subsystems[0].ctrls[i].name);
                fprintf(stderr, "\n\n");
                free(subsysnqn);
+               free_topology(&t);
        } else {
                struct dirent **paths;
                bool comma = false;
index 29f09829f0c7a75a2dbee3801cbe3af494e084ee..2a6f5ee51074a308543acfa98fd12e8951d983d2 100644 (file)
@@ -43,8 +43,8 @@ void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flag
 void nvme_show_lba_status(struct nvme_lba_status *list, unsigned long len,
        enum nvme_print_flags flags);
 void nvme_show_list_items(struct nvme_topology *t, enum nvme_print_flags flags);
-void nvme_show_subsystem_list(struct subsys_list_item *slist, int n,
-       enum nvme_print_flags flags);
+void nvme_show_subsystem_list(struct nvme_topology *t,
+      enum nvme_print_flags flags);
 void nvme_show_id_nvmset(struct nvme_id_nvmset *nvmset, unsigned nvmset_id,
        enum nvme_print_flags flags);
 void nvme_show_list_secondary_ctrl(const struct nvme_secondary_controllers_list *sc_list,
index 058e1855c57be40b312d4c4b6ce1386f1d6194aa..f2d0e7a4e344d12c47b42089c727f5e033fb6f0f 100644 (file)
@@ -9,26 +9,13 @@
 #include "nvme.h"
 #include "nvme-ioctl.h"
 
-static const char delim_space  = ' ';
-
-int get_nsid(int fd)
-{
-       int nsid = nvme_get_nsid(fd);
-
-       if (nsid <= 0) {
-               fprintf(stderr,
-                       "%s: failed to return namespace id\n",
-                       devicename);
-       }
-       return nsid < 0 ? 0 : nsid;
-}
+static const char *dev = "/dev/";
+static const char *subsys_dir = "/sys/class/nvme-subsystem/";
 
 char *get_nvme_subsnqn(char *path)
 {
-       char sspath[320];
-       char *subsysnqn;
-       int fd;
-       int ret;
+       char sspath[320], *subsysnqn;
+       int fd, ret;
 
        snprintf(sspath, sizeof(sspath), "%s/subsysnqn", path);
 
@@ -55,17 +42,14 @@ char *get_nvme_subsnqn(char *path)
 
 close_fd:
        close(fd);
-
        return subsysnqn;
 }
 
-char *get_nvme_ctrl_attr(char *path, const char *attr)
+char *nvme_get_ctrl_attr(char *path, const char *attr)
 {
-       char *attrpath;
-       char *value;
-       int fd;
+       char *attrpath, *value;
        ssize_t ret;
-       int i;
+       int fd, i;
 
        ret = asprintf(&attrpath, "%s/%s", path, attr);
        if (ret < 0)
@@ -98,16 +82,13 @@ char *get_nvme_ctrl_attr(char *path, const char *attr)
 
        close(fd);
        free(attrpath);
-
        return value;
-
 err_close_fd:
        close(fd);
 err_free_value:
        free(value);
 err_free_path:
        free(attrpath);
-
        return NULL;
 }
 
@@ -124,7 +105,10 @@ static int scan_namespace(struct nvme_namespace *n)
        if (fd < 0)
                goto free;
 
-       n->nsid = get_nsid(fd);
+       n->nsid = nvme_get_nsid(fd);
+       if (n->nsid < 0)
+               goto close_fd;
+
        ret = nvme_identify_ns(fd, n->nsid, 0, &n->ns);
        if (ret < 0)
                goto close_fd;
@@ -135,7 +119,69 @@ free:
        return 0;
 }
 
-static int scan_ctrl(struct nvme_ctrl *c, char *p)
+static char *get_nvme_ctrl_path_ana_state(char *path, int nsid)
+{
+       struct dirent **paths;
+       char *ana_state;
+       int i, n;
+
+       ana_state = calloc(1, 16);
+       if (!ana_state)
+               return NULL;
+
+       n = scandir(path, &paths, scan_ctrl_paths_filter, alphasort);
+       if (n <= 0) {
+               free(ana_state);
+               return NULL;
+       }
+       for (i = 0; i < n; i++) {
+               int id, cntlid, ns, fd;
+               char *ctrl_path;
+               ssize_t ret;
+
+               if (sscanf(paths[i]->d_name, "nvme%dc%dn%d",
+                          &id, &cntlid, &ns) != 3) {
+                       if (sscanf(paths[i]->d_name, "nvme%dn%d",
+                                  &id, &ns) != 2) {
+                               continue;
+                       }
+               }
+               if (ns != nsid)
+                       continue;
+
+               ret = asprintf(&ctrl_path, "%s/%s/ana_state",
+                              path, paths[i]->d_name);
+               if (ret < 0) {
+                       free(ana_state);
+                       ana_state = NULL;
+                       break;
+               }
+               fd = open(ctrl_path, O_RDONLY);
+               if (fd < 0) {
+                       free(ctrl_path);
+                       free(ana_state);
+                       ana_state = NULL;
+                       break;
+               }
+               ret = read(fd, ana_state, 16);
+               if (ret < 0) {
+                       fprintf(stderr, "Failed to read ANA state from %s\n",
+                               ctrl_path);
+                       free(ana_state);
+                       ana_state = NULL;
+               } else if (ana_state[strlen(ana_state) - 1] == '\n')
+                       ana_state[strlen(ana_state) - 1] = '\0';
+               close(fd);
+               free(ctrl_path);
+               break;
+       }
+       for (i = 0; i < n; i++)
+               free(paths[i]);
+       free(paths);
+       return ana_state;
+}
+
+static int scan_ctrl(struct nvme_ctrl *c, char *p, __u32 ns_instance)
 {
        struct nvme_namespace *n;
        struct dirent **ns;
@@ -146,9 +192,12 @@ static int scan_ctrl(struct nvme_ctrl *c, char *p)
        if (ret < 0)
                return ret;
 
-       c->address = get_nvme_ctrl_attr(path, "address");
-       c->transport = get_nvme_ctrl_attr(path, "transport");
-       c->state = get_nvme_ctrl_attr(path, "state");
+       c->address = nvme_get_ctrl_attr(path, "address");
+       c->transport = nvme_get_ctrl_attr(path, "transport");
+       c->state = nvme_get_ctrl_attr(path, "state");
+
+       if (ns_instance)
+               c->ana_state = get_nvme_ctrl_path_ana_state(path, ns_instance);
 
        ret = scandir(path, &ns, scan_namespace_filter, alphasort);
        if (ret == -1) {
@@ -190,7 +239,7 @@ free:
        return 0;
 }
 
-static int scan_subsystem(struct nvme_subsystem *s)
+static int scan_subsystem(struct nvme_subsystem *s, __u32 ns_instance)
 {
        struct dirent **ctrls, **ns;
        struct nvme_namespace *n;
@@ -214,7 +263,7 @@ static int scan_subsystem(struct nvme_subsystem *s)
                c = &s->ctrls[i];
                c->name = strdup(ctrls[i]->d_name);
                c->subsys = s;
-               scan_ctrl(c, path);
+               scan_ctrl(c, path, ns_instance);
        }
 
        while (i--)
@@ -345,22 +394,62 @@ free:
        return ret;
 }
 
-int scan_subsystems(struct nvme_topology *t)
+static void free_ctrl(struct nvme_ctrl *c)
+{
+       int i;
+
+       for (i = 0; i < c->nr_namespaces; i++) {
+               struct nvme_namespace *n = &c->namespaces[i];
+               free(n->name);
+       }
+       free(c->name);
+       free(c->transport);
+       free(c->address);
+       free(c->state);
+       free(c->ana_state);
+       free(c->namespaces);
+}
+
+static void free_subsystem(struct nvme_subsystem *s)
+{
+       int i;
+
+       for (i = 0; i < s->nr_ctrls; i++)
+               free_ctrl(&s->ctrls[i]);
+       for (i = 0; i < s->nr_namespaces; i++) {
+               struct nvme_namespace *n = &s->namespaces[i];
+               free(n->name);
+       }
+       free(s->name);
+       free(s->subsysnqn);
+       free(s->ctrls);
+       free(s->namespaces);
+}
+
+int scan_subsystems(struct nvme_topology *t, const char *subsysnqn,
+                   __u32 ns_instance)
 {
        struct nvme_subsystem *s;
        struct dirent **subsys;
-       int i;
+       int i, j = 0;
 
-       t->nr_subsystems = scandir(subsys_dir, &subsys, scan_subsys_filter, alphasort);
+       t->nr_subsystems = scandir(subsys_dir, &subsys, scan_subsys_filter,
+                                  alphasort);
        if (t->nr_subsystems < 0)
                return legacy_list(t);
 
        t->subsystems = calloc(t->nr_subsystems, sizeof(*s));
        for (i = 0; i < t->nr_subsystems; i++) {
-               s = &t->subsystems[i];
+               s = &t->subsystems[j];
                s->name = strdup(subsys[i]->d_name);
-               scan_subsystem(s);
+               scan_subsystem(s, ns_instance);
+
+               if (!subsysnqn || !strcmp(s->subsysnqn, subsysnqn))
+                       j++;
+               else
+                       free_subsystem(s);
        }
+       t->nr_subsystems = j;
 
        while (i--)
                free(subsys[i]);
@@ -369,280 +458,12 @@ int scan_subsystems(struct nvme_topology *t)
 }
 
 void free_topology(struct nvme_topology *t)
-{
-       int i, j, k;
-
-       for (i = 0; i < t->nr_subsystems; i++) {
-               struct nvme_subsystem *s = &t->subsystems[i];
-
-               for (j = 0; j < s->nr_ctrls; j++) {
-                       struct nvme_ctrl *c = &s->ctrls[j];
-
-                       for (k = 0; k < c->nr_namespaces; k++) {
-                               struct nvme_namespace *n = &c->namespaces[k];
-                               free(n->name);
-                       }
-                       free(c->name);
-                       if (c->transport)
-                               free(c->transport);
-                       if (c->address)
-                               free(c->address);
-                       if (c->state)
-                               free(c->state);
-                       if (c->namespaces)
-                               free(c->namespaces);
-               }
-               free(s->name);
-               free(s->subsysnqn);
-               free(s->ctrls);
-               free(s->namespaces);
-       }
-       free(t->subsystems);
-}
-
-static char *get_nvme_ctrl_path_ana_state(char *path, int nsid)
-{
-       struct dirent **paths;
-       char *ana_state;
-       int i, n;
-
-       ana_state = calloc(1, 16);
-       if (!ana_state)
-               return NULL;
-
-       n = scandir(path, &paths, scan_ctrl_paths_filter, alphasort);
-       if (n <= 0) {
-               free(ana_state);
-               return NULL;
-       }
-       for (i = 0; i < n; i++) {
-               int id, cntlid, ns, fd;
-               ssize_t ret;
-               char *ctrl_path;
-
-               if (sscanf(paths[i]->d_name, "nvme%dc%dn%d",
-                          &id, &cntlid, &ns) != 3) {
-                       if (sscanf(paths[i]->d_name, "nvme%dn%d",
-                                  &id, &ns) != 2) {
-                               continue;
-                       }
-               }
-               if (ns != nsid)
-                       continue;
-
-               ret = asprintf(&ctrl_path, "%s/%s/ana_state",
-                              path, paths[i]->d_name);
-               if (ret < 0) {
-                       free(ana_state);
-                       ana_state = NULL;
-                       break;
-               }
-               fd = open(ctrl_path, O_RDONLY);
-               if (fd < 0) {
-                       free(ctrl_path);
-                       free(ana_state);
-                       ana_state = NULL;
-                       break;
-               }
-               ret = read(fd, ana_state, 16);
-               if (ret < 0) {
-                       fprintf(stderr, "Failed to read ANA state from %s\n",
-                               ctrl_path);
-                       free(ana_state);
-                       ana_state = NULL;
-               } else if (ana_state[strlen(ana_state) - 1] == '\n')
-                       ana_state[strlen(ana_state) - 1] = '\0';
-               close(fd);
-               free(ctrl_path);
-               break;
-       }
-       for (i = 0; i < n; i++)
-               free(paths[i]);
-       free(paths);
-       return ana_state;
-}
-
-void free_ctrl_list_item(struct ctrl_list_item *ctrls)
-{
-       free(ctrls->name);
-       free(ctrls->transport);
-       free(ctrls->address);
-       free(ctrls->state);
-       free(ctrls->ana_state);
-       free(ctrls->subsysnqn);
-       free(ctrls->traddr);
-       free(ctrls->trsvcid);
-       free(ctrls->host_traddr);
-}
-
-int get_nvme_ctrl_info(char *name, char *path, struct ctrl_list_item *ctrl,
-                       __u32 nsid)
-{
-       char ctrl_path[512];
-
-       ctrl->name = strdup(name);
-
-       snprintf(ctrl_path, sizeof(ctrl_path), "%s/%s", path, ctrl->name);
-
-       ctrl->address = get_nvme_ctrl_attr(ctrl_path, "address");
-       if (!ctrl->address) {
-               fprintf(stderr, "%s: failed to get controller address.\n",
-                       ctrl->name);
-               goto free_ctrl_items;
-       }
-
-       ctrl->transport = get_nvme_ctrl_attr(ctrl_path, "transport");
-       if (!ctrl->transport) {
-               fprintf(stderr, "%s: failed to get controller transport.\n",
-                       ctrl->name);
-               goto free_ctrl_items;
-       }
-
-       ctrl->state = get_nvme_ctrl_attr(ctrl_path, "state");
-       if (!ctrl->state) {
-               fprintf(stderr, "%s: failed to get controller state.\n",
-                       ctrl->name);
-               goto free_ctrl_items;
-       }
-
-       if (nsid != NVME_NSID_ALL)
-               ctrl->ana_state = get_nvme_ctrl_path_ana_state(ctrl_path, nsid);
-
-       ctrl->subsysnqn = get_nvme_ctrl_attr(ctrl_path, "subsysnqn");
-       if (!ctrl->subsysnqn) {
-               fprintf(stderr, "%s: failed to get controller subsysnqn.\n",
-                       ctrl->name);
-               goto free_ctrl_items;
-       }
-
-       ctrl->traddr = __parse_connect_arg(ctrl->address, delim_space,
-                                       conarg_traddr);
-       ctrl->trsvcid = __parse_connect_arg(ctrl->address, delim_space,
-                                       conarg_trsvcid);
-       ctrl->host_traddr = __parse_connect_arg(ctrl->address, delim_space,
-                                       conarg_host_traddr);
-
-       return 0;       /* success */
-
-free_ctrl_items:
-       free_ctrl_list_item(ctrl);
-
-       return 1;       /* failure */
-}
-
-static int get_nvme_subsystem_info(char *name, char *path,
-                               struct subsys_list_item *item, __u32 nsid)
-{
-       struct dirent **ctrls;
-       int n, i, ret = 1, ccnt = 0;
-
-       item->subsysnqn = get_nvme_subsnqn(path);
-       if (!item->subsysnqn) {
-               fprintf(stderr, "failed to get subsystem nqn.\n");
-               return ret;
-       }
-
-       item->name = strdup(name);
-
-       n = scandir(path, &ctrls, scan_ctrls_filter, alphasort);
-       if (n < 0) {
-               fprintf(stderr, "failed to scan controller(s).\n");
-               return ret;
-       }
-
-       item->ctrls = calloc(n, sizeof(struct ctrl_list_item));
-       if (!item->ctrls) {
-               fprintf(stderr, "failed to allocate subsystem controller(s)\n");
-               goto free_ctrls;
-       }
-
-       item->nctrls = n;
-
-       for (i = 0; i < n; i++) {
-               if (get_nvme_ctrl_info(ctrls[i]->d_name, path,
-                               &item->ctrls[ccnt], nsid)) {
-                       fprintf(stderr, "failed to get controller[%d] info.\n",
-                                       i);
-               }
-               ccnt++;
-       }
-
-       item->nctrls = ccnt;
-
-       ret = 0;
-
-free_ctrls:
-       for (i = 0; i < n; i++)
-               free(ctrls[i]);
-       free(ctrls);
-
-       return ret;
-
-}
-
-static void free_subsys_list_item(struct subsys_list_item *item)
 {
        int i;
 
-       for (i = 0; i < item->nctrls; i++)
-               free_ctrl_list_item(&item->ctrls[i]);
-
-       free(item->ctrls);
-       free(item->subsysnqn);
-       free(item->name);
-}
-
-void free_subsys_list(struct subsys_list_item *slist, int n)
-{
-       int i;
-
-       for (i = 0; i < n; i++)
-               free_subsys_list_item(&slist[i]);
-
-       free(slist);
-}
-
-struct subsys_list_item *get_subsys_list(int *subcnt, char *subsysnqn,
-                                        __u32 nsid)
-{
-       char path[310];
-       struct dirent **subsys;
-       struct subsys_list_item *slist;
-       int n, i, ret = 0;
-
-       n = scandir(subsys_dir, &subsys, scan_subsys_filter, alphasort);
-       if (n < 0) {
-               fprintf(stderr, "no NVMe subsystem(s) detected.\n");
-               return NULL;
-       }
-
-       slist = calloc(n, sizeof(struct subsys_list_item));
-       if (!slist)
-               goto free_subsys;
-
-       for (i = 0; i < n; i++) {
-               snprintf(path, sizeof(path), "%s%s", subsys_dir,
-                       subsys[i]->d_name);
-               ret = get_nvme_subsystem_info(subsys[i]->d_name, path,
-                               &slist[*subcnt], nsid);
-               if (ret) {
-                       fprintf(stderr,
-                               "%s: failed to get subsystem info: %s\n",
-                               path, strerror(errno));
-                       free_subsys_list_item(&slist[*subcnt]);
-               } else if (subsysnqn &&
-                          strncmp(slist[*subcnt].subsysnqn, subsysnqn, 255))
-                       free_subsys_list_item(&slist[*subcnt]);
-               else
-                       (*subcnt)++;
-       }
-
-free_subsys:
-       for (i = 0; i < n; i++)
-               free(subsys[i]);
-       free(subsys);
-
-       return slist;
+       for (i = 0; i < t->nr_subsystems; i++)
+               free_subsystem(&t->subsystems[i]);
+       free(t->subsystems);
 }
 
 char *nvme_char_from_block(char *dev)
diff --git a/nvme.c b/nvme.c
index 26aa2ab091eeeff71bae2723a298eb1ae33235f0..81ecac7c5d569355182b58f5908ca9e1ecd48194 100644 (file)
--- a/nvme.c
+++ b/nvme.c
 #include "argconfig.h"
 #include "fabrics.h"
 
+#define CREATE_CMD
+#include "nvme-builtin.h"
+
 static struct stat nvme_stat;
 const char *devicename;
 
 static const char nvme_version_string[] = NVME_VERSION;
 
-#define CREATE_CMD
-#include "nvme-builtin.h"
-
 static struct plugin builtin = {
        .commands = commands,
        .name = NULL,
@@ -85,18 +85,9 @@ static struct program nvme = {
        .extensions = &builtin,
 };
 
-
 static const char *output_format = "Output format: normal|json|binary";
 static const char *output_format_no_binary = "Output format: normal|json";
 
-const char *conarg_nqn = "nqn";
-const char *conarg_transport = "transport";
-const char *conarg_traddr = "traddr";
-const char *conarg_trsvcid = "trsvcid";
-const char *conarg_host_traddr = "host_traddr";
-const char *dev = "/dev/";
-const char *subsys_dir = "/sys/class/nvme-subsystem/";
-
 static void *__nvme_alloc(size_t len, bool *huge)
 {
        void *p;
@@ -1028,9 +1019,9 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
                goto ret;
 
        if (S_ISBLK(nvme_stat.st_mode)) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        } else if (!cfg.namespace_id) {
@@ -1250,23 +1241,27 @@ ret:
 static int list_subsys(int argc, char **argv, struct command *cmd,
                struct plugin *plugin)
 {
-       struct subsys_list_item *slist;
+       struct nvme_topology t = { };
        enum nvme_print_flags flags;
-       int err, subcnt = 0;
        char *subsysnqn = NULL;
        const char *desc = "Retrieve information for subsystems";
-       __u32 namespace_id;
+       const char *verbose = "Increase output verbosity";
+       __u32 ns_instance = 0;
+       int err;
 
        struct config {
                char *output_format;
+               int verbose;
        };
 
        struct config cfg = {
                .output_format = "normal",
+               .verbose = 0,
        };
 
        OPT_ARGS(opts) = {
-               OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json"),
+               OPT_FMT("output-format", 'o', &cfg.output_format, output_format_no_binary), 
+               OPT_FLAG("verbose",      'v', &cfg.verbose,       verbose),
                OPT_END()
        };
 
@@ -1280,7 +1275,7 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
                int id;
 
                devicename = basename(argv[optind]);
-               if (sscanf(devicename, "nvme%dn%d", &id, &namespace_id) != 2) {
+               if (sscanf(devicename, "nvme%dn%d", &id, &ns_instance) != 2) {
                        fprintf(stderr, "%s is not a NVMe namespace device\n",
                                argv[optind]);
                        err = -EINVAL;
@@ -1304,11 +1299,17 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
                err = -EINVAL;
                goto free;
        }
+       if (cfg.verbose)
+               flags |= VERBOSE;
 
-       slist = get_subsys_list(&subcnt, subsysnqn, namespace_id);
-       nvme_show_subsystem_list(slist, subcnt, flags);
-       free_subsys_list(slist, subcnt);
+       err = scan_subsystems(&t, subsysnqn, ns_instance);
+       if (err) {
+               fprintf(stderr, "Failed to scan namespaces\n");
+               goto free;
+       }
+       nvme_show_subsystem_list(&t, flags);
 free:
+       free_topology(&t);
        if (subsysnqn)
                free(subsysnqn);
 ret:
@@ -1319,7 +1320,7 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
 {
        const char *desc = "Retrieve basic information for all NVMe namespaces";
        const char *verbose = "Increase output verbosity";
-       struct nvme_topology t;
+       struct nvme_topology t = { };
        enum nvme_print_flags flags;
        int err = 0;
 
@@ -1353,7 +1354,7 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
        if (cfg.verbose)
                flags |= VERBOSE;
 
-       err = scan_subsystems(&t);
+       err = scan_subsystems(&t, NULL, 0);
        if (err) {
                fprintf(stderr, "Failed to scan namespaces\n");
                return err;
@@ -1364,81 +1365,6 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
        return 0;
 }
 
-/*
- * Given a controller name, create a ctrl_list_item with its
- * attributes and compare the attributes against the connect args
- * given.
- * Return true/false based on whether it matches
- */
-bool ctrl_matches_connectargs(char *name, struct connect_args *args)
-{
-       struct ctrl_list_item *ctrl;
-       bool found = false;
-
-       ctrl = malloc(sizeof(*ctrl));
-       if (!ctrl) {
-               fprintf(stderr, "Failed to allocate controller list element\n");
-               return false;
-       }
-       memset(ctrl, 0, sizeof(*ctrl));
-
-       if (get_nvme_ctrl_info(name, SYS_NVME, ctrl, NVME_NSID_ALL))
-               goto cleanup_exit;
-
-       if (!strcmp(ctrl->subsysnqn, args->subsysnqn) &&
-           !strcmp(ctrl->transport, args->transport) &&
-           (!strcmp(ctrl->traddr, args->traddr) ||
-            !strcmp(args->traddr, "none")) &&
-           (!strcmp(ctrl->trsvcid, args->trsvcid) ||
-            !strcmp(args->trsvcid, "none")) &&
-           (!strcmp(ctrl->host_traddr, args->host_traddr) ||
-            !strcmp(args->host_traddr, "none")))
-               found = true;
-
-cleanup_exit:
-       free_ctrl_list_item(ctrl);
-       free(ctrl);
-
-       return found;
-}
-
-/*
- * Look through the system to find an existing controller whose
- * attributes match the connect arguments specified
- * If found, a string containing the controller name (ex: "nvme?")
- * is returned.
- * If not found, a NULL is returned.
- */
-char *find_ctrl_with_connectargs(struct connect_args *args)
-{
-       struct dirent **devices;
-       char *devname = NULL;
-       int i, n;
-
-       n = scandir(SYS_NVME, &devices, scan_ctrls_filter, alphasort);
-       if (n < 0) {
-               fprintf(stderr, "no NVMe controller(s) detected.\n");
-               return NULL;
-       }
-
-       for (i = 0; i < n; i++) {
-               if (ctrl_matches_connectargs(devices[i]->d_name, args)) {
-                       devname = strdup(devices[i]->d_name);
-                       if (devname == NULL)
-                               fprintf(stderr, "no memory for ctrl name %s\n",
-                                               devices[i]->d_name);
-                       goto cleanup_devices;
-               }
-       }
-
-cleanup_devices:
-       for (i = 0; i < n; i++)
-               free(devices[i]);
-       free(devices);
-
-       return devname;
-}
-
 int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
                void (*vs)(__u8 *vs, struct json_object *root))
 {
@@ -1545,9 +1471,9 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
                flags = BINARY;
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -1627,9 +1553,9 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
                flags |= VERBOSE;
 
        if (!cfg.namespace_id && S_ISBLK(nvme_stat.st_mode)) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        } else if (!cfg.namespace_id) {
@@ -2823,9 +2749,9 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                 */
                cfg.namespace_id = NVME_NSID_ALL;
        } else if (S_ISBLK(nvme_stat.st_mode)) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3338,9 +3264,9 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
                goto ret;
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3430,9 +3356,9 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
        if (cfg.deac)
                control |= NVME_RW_DEAC;
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3523,9 +3449,9 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
        }
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3581,9 +3507,9 @@ static int flush(int argc, char **argv, struct command *cmd, struct plugin *plug
                goto ret;
 
        if (S_ISBLK(nvme_stat.st_mode)) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3649,9 +3575,9 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
                goto ret;
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3721,9 +3647,9 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
                goto ret;
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3801,9 +3727,9 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
                goto ret;
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -3879,9 +3805,9 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
                flags = BINARY;
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = -ENOTBLK;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
@@ -4261,9 +4187,9 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
                control |= NVME_RW_FUA;
 
        if (!cfg.namespace_id) {
-               cfg.namespace_id = get_nsid(fd);
-               if (cfg.namespace_id == 0) {
-                       err = EINVAL;
+               cfg.namespace_id = nvme_get_nsid(fd);
+               if (cfg.namespace_id < 0) {
+                       err = cfg.namespace_id;
                        goto close_fd;
                }
        }
diff --git a/nvme.h b/nvme.h
index b0b23c7558f006077f86e4a6e3b0ef871101ccd5..f6a94e9757c69a489c9e0814c87466528f54cae6 100644 (file)
--- a/nvme.h
+++ b/nvme.h
@@ -33,7 +33,6 @@ enum nvme_print_flags {
        BINARY  = 1 << 3,       /* binary dump raw bytes */
 };
 
-
 struct nvme_subsystem;
 struct nvme_ctrl;
 
@@ -52,6 +51,10 @@ struct nvme_ctrl {
        char *address;
        char *transport;
        char *state;
+       char *ana_state;
+       char *traddr;
+       char *trsvcid;
+       char *host_traddr;
 
        struct nvme_id_ctrl id;
 
@@ -75,64 +78,18 @@ struct nvme_topology {
        struct nvme_subsystem *subsystems;
 };
 
-struct ctrl_list_item {
-       char *name;
-       char *address;
-       char *transport;
-       char *state;
-       char *ana_state;
-       char *subsysnqn;
-       char *traddr;
-       char *trsvcid;
-       char *host_traddr;
-};
-
-struct subsys_list_item {
-       char *name;
-       char *subsysnqn;
-       int nctrls;
-       struct ctrl_list_item *ctrls;
-};
-
-struct connect_args {
-       char *subsysnqn;
-       char *transport;
-       char *traddr;
-       char *trsvcid;
-       char *host_traddr;
-};
-
-#define SYS_NVME               "/sys/class/nvme"
-
-bool ctrl_matches_connectargs(char *name, struct connect_args *args);
-char *find_ctrl_with_connectargs(struct connect_args *args);
-char *__parse_connect_arg(char *conargs, const char delim, const char *fieldnm);
-
-extern const char *conarg_nqn;
-extern const char *conarg_transport;
-extern const char *conarg_traddr;
-extern const char *conarg_trsvcid;
-extern const char *conarg_host_traddr;
-extern const char *dev;
-extern const char *subsys_dir;
+#define SYS_NVME "/sys/class/nvme"
 
 void register_extension(struct plugin *plugin);
-
 int parse_and_open(int argc, char **argv, const char *desc,
        const struct argconfig_commandline_options *clo);
 
 extern const char *devicename;
 
-int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin, void (*vs)(__u8 *vs, struct json_object *root));
 enum nvme_print_flags validate_output_format(char *format);
-
-int get_nvme_ctrl_info(char *name, char *path, struct ctrl_list_item *ctrl,
-                       __u32 nsid);
-struct subsys_list_item *get_subsys_list(int *subcnt, char *subsysnqn, __u32 nsid);
-void free_subsys_list(struct subsys_list_item *slist, int n);
+int __id_ctrl(int argc, char **argv, struct command *cmd,
+       struct plugin *plugin, void (*vs)(__u8 *vs, struct json_object *root));
 char *nvme_char_from_block(char *block);
-int get_nsid(int fd);
-void free_ctrl_list_item(struct ctrl_list_item *ctrls);
 void *mmap_registers(const char *dev);
 
 extern int current_index;
@@ -142,8 +99,10 @@ int scan_ctrls_filter(const struct dirent *d);
 int scan_subsys_filter(const struct dirent *d);
 int scan_dev_filter(const struct dirent *d);
 
-int scan_subsystems(struct nvme_topology *t);
+int scan_subsystems(struct nvme_topology *t, const char *subsysnqn,
+                   __u32 ns_instance);
 void free_topology(struct nvme_topology *t);
 char *get_nvme_subsnqn(char *path);
+char *nvme_get_ctrl_attr(char *path, const char *attr);
 
 #endif /* _NVME_H */
index d291dab59a129a43400749d29e455f9abb2d2755..c935f47af42fb53140effc16015d94588b22e0e6 100644 (file)
@@ -321,7 +321,7 @@ static int huawei_list(int argc, char **argv, struct command *command,
        if (fmt != JSON && fmt != NORMAL)
                return -EINVAL;
 
-       n = scandir(dev, &devices, scan_namespace_filter, alphasort);
+       n = scandir("/dev", &devices, scan_namespace_filter, alphasort);
        if (n <= 0)
                return n;
 
@@ -332,7 +332,7 @@ static int huawei_list(int argc, char **argv, struct command *command,
        }
 
        for (i = 0; i < n; i++) {
-               snprintf(path, sizeof(path), "%s%s", dev, devices[i]->d_name);
+               snprintf(path, sizeof(path), "/dev/%s", devices[i]->d_name);
                fd = open(path, O_RDONLY);
                ret = huawei_get_nvme_info(fd, &list_items[huawei_num], path);
                if (ret)