Print this page
8479 nvmeadm doesn't handle namespaces with EUI64
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

@@ -52,11 +52,12 @@
 
 struct nvme_process_arg {
         int npa_argc;
         char **npa_argv;
         char *npa_name;
-        uint32_t npa_nsid;
+        char *npa_nsid;
+        int npa_found;
         boolean_t npa_isns;
         const nvmeadm_cmd_t *npa_cmd;
         di_node_t npa_node;
         di_minor_t npa_minor;
         char *npa_path;

@@ -119,11 +120,10 @@
 static void usage_secure_erase(const char *);
 static void usage_attach_detach(const char *);
 
 int verbose;
 int debug;
-int found;
 static int exitcode;
 
 static const nvmeadm_cmd_t nvmeadm_cmds[] = {
         {
                 "list",

@@ -311,46 +311,33 @@
         npa.npa_name = strtok_r(argv[optind], ",", &lasts);
         do {
                 if (npa.npa_name != NULL) {
                         tmp = strchr(npa.npa_name, '/');
                         if (tmp != NULL) {
-                                unsigned long nsid;
                                 *tmp++ = '\0';
-                                errno = 0;
-                                nsid = strtoul(tmp, NULL, 10);
-                                if (nsid >= UINT32_MAX || errno != 0) {
-                                        warn("invalid namespace %s", tmp);
-                                        exitcode--;
-                                        continue;
-                                }
-                                if (nsid == 0) {
-                                        warnx("invalid namespace %s", tmp);
-                                        exitcode--;
-                                        continue;
-                                }
-                                npa.npa_nsid = nsid;
+                                npa.npa_nsid = tmp;
                                 npa.npa_isns = B_TRUE;
                         }
                 }
 
                 if ((node = di_init("/", DINFOSUBTREE | DINFOMINOR)) == NULL)
                         err(-1, "failed to initialize libdevinfo");
                 nvme_walk(&npa, node);
                 di_fini(node);
 
-                if (found == 0) {
+                if (npa.npa_found == 0) {
                         if (npa.npa_name != NULL) {
-                                warnx("%s%.*s%.*d: no such controller or "
+                                warnx("%s%.*s%.*s: no such controller or "
                                     "namespace", npa.npa_name,
-                                    npa.npa_nsid > 0 ? -1 : 0, "/",
-                                    npa.npa_nsid > 0 ? -1 : 0, npa.npa_nsid);
+                                    npa.npa_isns ? -1 : 0, "/",
+                                    npa.npa_isns ? -1 : 0, npa.npa_nsid);
                         } else {
                                 warnx("no controllers found");
                         }
                         exitcode--;
                 }
-                found = 0;
+                npa.npa_found = 0;
                 npa.npa_name = strtok_r(NULL, ",", &lasts);
         } while (npa.npa_name != NULL);
 
         exit(exitcode);
 }

@@ -386,11 +373,11 @@
 
 static boolean_t
 nvme_match(nvme_process_arg_t *npa)
 {
         char *name;
-        uint32_t nsid = 0;
+        char *nsid = NULL;
 
         if (npa->npa_name == NULL)
                 return (B_TRUE);
 
         if (asprintf(&name, "%s%d", di_driver_name(npa->npa_node),

@@ -403,17 +390,18 @@
         }
 
         free(name);
 
         if (npa->npa_isns) {
-                if (npa->npa_nsid == 0)
+                if (npa->npa_nsid == NULL)
                         return (B_TRUE);
-                nsid = strtoul(di_minor_name(npa->npa_minor), NULL, 10);
-        }
 
-        if (npa->npa_isns && npa->npa_nsid != nsid)
+                nsid = di_minor_name(npa->npa_minor);
+
+                if (nsid == NULL || strcmp(npa->npa_nsid, nsid) != 0)
                 return (B_FALSE);
+        }
 
         return (B_TRUE);
 }
 
 char *

@@ -473,11 +461,11 @@
                 return (DI_WALK_CONTINUE);
 
         if ((fd = nvme_open(minor)) < 0)
                 return (DI_WALK_CONTINUE);
 
-        found++;
+        npa->npa_found++;
 
         npa->npa_path = di_devfs_path(node);
         if (npa->npa_path == NULL)
                 goto out;
 

@@ -587,11 +575,11 @@
 }
 
 static int
 do_identify(int fd, const nvme_process_arg_t *npa)
 {
-        if (npa->npa_nsid == 0) {
+        if (!npa->npa_isns) {
                 nvme_capabilities_t *cap;
 
                 cap = nvme_capabilities(fd);
                 if (cap == NULL)
                         return (-1);

@@ -625,11 +613,11 @@
 {
         int nlog = npa->npa_idctl->id_elpe + 1;
         size_t bufsize = sizeof (nvme_error_log_entry_t) * nlog;
         nvme_error_log_entry_t *elog;
 
-        if (npa->npa_nsid != 0)
+        if (npa->npa_isns)
                 errx(-1, "Error Log not available on a per-namespace basis");
 
         elog = nvme_get_logpage(fd, NVME_LOGPAGE_ERROR, &bufsize);
 
         if (elog == NULL)

@@ -649,11 +637,11 @@
 do_get_logpage_health(int fd, const nvme_process_arg_t *npa)
 {
         size_t bufsize = sizeof (nvme_health_log_t);
         nvme_health_log_t *hlog;
 
-        if (npa->npa_nsid != 0) {
+        if (npa->npa_isns) {
                 if (npa->npa_idctl->id_lpa.lp_smart == 0)
                         errx(-1, "SMART/Health information not available "
                             "on a per-namespace basis on this controller");
         }
 

@@ -674,11 +662,11 @@
 do_get_logpage_fwslot(int fd, const nvme_process_arg_t *npa)
 {
         size_t bufsize = sizeof (nvme_fwslot_log_t);
         nvme_fwslot_log_t *fwlog;
 
-        if (npa->npa_nsid != 0)
+        if (npa->npa_isns)
                 errx(-1, "Firmware Slot information not available on a "
                     "per-namespace basis");
 
         fwlog = nvme_get_logpage(fd, NVME_LOGPAGE_FWSLOT, &bufsize);
 

@@ -803,13 +791,13 @@
          * No feature list given, print all supported features.
          */
         if (npa->npa_argc == 0) {
                 (void) printf("%s: Get Features\n", npa->npa_name);
                 for (feat = &features[0]; feat->f_feature != 0; feat++) {
-                        if ((npa->npa_nsid != 0 &&
+                        if ((npa->npa_isns &&
                             (feat->f_getflags & NVMEADM_NS) == 0) ||
-                            (npa->npa_nsid == 0 &&
+                            (!npa->npa_isns &&
                             (feat->f_getflags & NVMEADM_CTRL) == 0))
                                 continue;
 
                         (void) feat->f_get(fd, feat, npa->npa_idctl);
                 }

@@ -839,13 +827,13 @@
                 if (feat->f_feature == 0) {
                         warnx("unknown feature %s", f);
                         continue;
                 }
 
-                if ((npa->npa_nsid != 0 &&
+                if ((npa->npa_isns &&
                     (feat->f_getflags & NVMEADM_NS) == 0) ||
-                    (npa->npa_nsid == 0 &&
+                    (!npa->npa_isns &&
                     (feat->f_getflags & NVMEADM_CTRL) == 0)) {
                         warnx("feature %s %s supported for namespaces",
                             feat->f_name, (feat->f_getflags & NVMEADM_NS) != 0 ?
                             "only" : "not");
                         continue;