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>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/nvmeadm/nvmeadm.c
          +++ new/usr/src/cmd/nvmeadm/nvmeadm.c
↓ open down ↓ 46 lines elided ↑ open up ↑
  47   47  #include "nvmeadm.h"
  48   48  
  49   49  typedef struct nvme_process_arg nvme_process_arg_t;
  50   50  typedef struct nvme_feature nvme_feature_t;
  51   51  typedef struct nvmeadm_cmd nvmeadm_cmd_t;
  52   52  
  53   53  struct nvme_process_arg {
  54   54          int npa_argc;
  55   55          char **npa_argv;
  56   56          char *npa_name;
  57      -        uint32_t npa_nsid;
       57 +        char *npa_nsid;
       58 +        int npa_found;
  58   59          boolean_t npa_isns;
  59   60          const nvmeadm_cmd_t *npa_cmd;
  60   61          di_node_t npa_node;
  61   62          di_minor_t npa_minor;
  62   63          char *npa_path;
  63   64          char *npa_dsk;
  64   65          nvme_identify_ctrl_t *npa_idctl;
  65   66          nvme_identify_nsid_t *npa_idns;
  66   67          nvme_version_t *npa_version;
  67   68  };
↓ open down ↓ 46 lines elided ↑ open up ↑
 114  115  static void usage_list(const char *);
 115  116  static void usage_identify(const char *);
 116  117  static void usage_get_logpage(const char *);
 117  118  static void usage_get_features(const char *);
 118  119  static void usage_format(const char *);
 119  120  static void usage_secure_erase(const char *);
 120  121  static void usage_attach_detach(const char *);
 121  122  
 122  123  int verbose;
 123  124  int debug;
 124      -int found;
 125  125  static int exitcode;
 126  126  
 127  127  static const nvmeadm_cmd_t nvmeadm_cmds[] = {
 128  128          {
 129  129                  "list",
 130  130                  "list controllers and namespaces",
 131  131                  NULL,
 132  132                  do_list, usage_list, B_TRUE
 133  133          },
 134  134          {
↓ open down ↓ 171 lines elided ↑ open up ↑
 306  306          }
 307  307  
 308  308          /*
 309  309           * Get controller/namespace arguments and run command.
 310  310           */
 311  311          npa.npa_name = strtok_r(argv[optind], ",", &lasts);
 312  312          do {
 313  313                  if (npa.npa_name != NULL) {
 314  314                          tmp = strchr(npa.npa_name, '/');
 315  315                          if (tmp != NULL) {
 316      -                                unsigned long nsid;
 317  316                                  *tmp++ = '\0';
 318      -                                errno = 0;
 319      -                                nsid = strtoul(tmp, NULL, 10);
 320      -                                if (nsid >= UINT32_MAX || errno != 0) {
 321      -                                        warn("invalid namespace %s", tmp);
 322      -                                        exitcode--;
 323      -                                        continue;
 324      -                                }
 325      -                                if (nsid == 0) {
 326      -                                        warnx("invalid namespace %s", tmp);
 327      -                                        exitcode--;
 328      -                                        continue;
 329      -                                }
 330      -                                npa.npa_nsid = nsid;
      317 +                                npa.npa_nsid = tmp;
 331  318                                  npa.npa_isns = B_TRUE;
 332  319                          }
 333  320                  }
 334  321  
 335  322                  if ((node = di_init("/", DINFOSUBTREE | DINFOMINOR)) == NULL)
 336  323                          err(-1, "failed to initialize libdevinfo");
 337  324                  nvme_walk(&npa, node);
 338  325                  di_fini(node);
 339  326  
 340      -                if (found == 0) {
      327 +                if (npa.npa_found == 0) {
 341  328                          if (npa.npa_name != NULL) {
 342      -                                warnx("%s%.*s%.*d: no such controller or "
      329 +                                warnx("%s%.*s%.*s: no such controller or "
 343  330                                      "namespace", npa.npa_name,
 344      -                                    npa.npa_nsid > 0 ? -1 : 0, "/",
 345      -                                    npa.npa_nsid > 0 ? -1 : 0, npa.npa_nsid);
      331 +                                    npa.npa_isns ? -1 : 0, "/",
      332 +                                    npa.npa_isns ? -1 : 0, npa.npa_nsid);
 346  333                          } else {
 347  334                                  warnx("no controllers found");
 348  335                          }
 349  336                          exitcode--;
 350  337                  }
 351      -                found = 0;
      338 +                npa.npa_found = 0;
 352  339                  npa.npa_name = strtok_r(NULL, ",", &lasts);
 353  340          } while (npa.npa_name != NULL);
 354  341  
 355  342          exit(exitcode);
 356  343  }
 357  344  
 358  345  static void
 359  346  usage(const nvmeadm_cmd_t *cmd)
 360  347  {
 361  348          (void) fprintf(stderr, "usage:\n");
↓ open down ↓ 19 lines elided ↑ open up ↑
 381  368              "  -d  print information useful for debugging %s\n"
 382  369              "  -v  print verbose information\n", getprogname());
 383  370          if (cmd != NULL && cmd->c_flagdesc != NULL)
 384  371                  (void) fprintf(stderr, "%s\n", cmd->c_flagdesc);
 385  372  }
 386  373  
 387  374  static boolean_t
 388  375  nvme_match(nvme_process_arg_t *npa)
 389  376  {
 390  377          char *name;
 391      -        uint32_t nsid = 0;
      378 +        char *nsid = NULL;
 392  379  
 393  380          if (npa->npa_name == NULL)
 394  381                  return (B_TRUE);
 395  382  
 396  383          if (asprintf(&name, "%s%d", di_driver_name(npa->npa_node),
 397  384              di_instance(npa->npa_node)) < 0)
 398  385                  err(-1, "nvme_match()");
 399  386  
 400  387          if (strcmp(name, npa->npa_name) != 0) {
 401  388                  free(name);
 402  389                  return (B_FALSE);
 403  390          }
 404  391  
 405  392          free(name);
 406  393  
 407  394          if (npa->npa_isns) {
 408      -                if (npa->npa_nsid == 0)
      395 +                if (npa->npa_nsid == NULL)
 409  396                          return (B_TRUE);
 410      -                nsid = strtoul(di_minor_name(npa->npa_minor), NULL, 10);
 411      -        }
 412  397  
 413      -        if (npa->npa_isns && npa->npa_nsid != nsid)
 414      -                return (B_FALSE);
      398 +                nsid = di_minor_name(npa->npa_minor);
 415  399  
      400 +                if (nsid == NULL || strcmp(npa->npa_nsid, nsid) != 0)
      401 +                        return (B_FALSE);
      402 +        }
      403 +
 416  404          return (B_TRUE);
 417  405  }
 418  406  
 419  407  char *
 420  408  nvme_dskname(const nvme_process_arg_t *npa)
 421  409  {
 422  410          char *path = NULL;
 423  411          di_node_t child;
 424  412          di_dim_t dim;
 425  413          char *addr;
↓ open down ↓ 42 lines elided ↑ open up ↑
 468  456  
 469  457          npa->npa_node = node;
 470  458          npa->npa_minor = minor;
 471  459  
 472  460          if (!nvme_match(npa))
 473  461                  return (DI_WALK_CONTINUE);
 474  462  
 475  463          if ((fd = nvme_open(minor)) < 0)
 476  464                  return (DI_WALK_CONTINUE);
 477  465  
 478      -        found++;
      466 +        npa->npa_found++;
 479  467  
 480  468          npa->npa_path = di_devfs_path(node);
 481  469          if (npa->npa_path == NULL)
 482  470                  goto out;
 483  471  
 484  472          npa->npa_version = nvme_version(fd);
 485  473          if (npa->npa_version == NULL)
 486  474                  goto out;
 487  475  
 488  476          npa->npa_idctl = nvme_identify_ctrl(fd);
↓ open down ↓ 93 lines elided ↑ open up ↑
 582  570  usage_identify(const char *c_name)
 583  571  {
 584  572          (void) fprintf(stderr, "%s <ctl>[/<ns>][,...]\n\n"
 585  573              "  Print detailed information about the specified NVMe "
 586  574              "controllers and/or name-\n  spaces.\n", c_name);
 587  575  }
 588  576  
 589  577  static int
 590  578  do_identify(int fd, const nvme_process_arg_t *npa)
 591  579  {
 592      -        if (npa->npa_nsid == 0) {
      580 +        if (!npa->npa_isns) {
 593  581                  nvme_capabilities_t *cap;
 594  582  
 595  583                  cap = nvme_capabilities(fd);
 596  584                  if (cap == NULL)
 597  585                          return (-1);
 598  586  
 599  587                  (void) printf("%s: ", npa->npa_name);
 600  588                  nvme_print_identify_ctrl(npa->npa_idctl, cap,
 601  589                      npa->npa_version);
 602  590  
↓ open down ↓ 17 lines elided ↑ open up ↑
 620  608              "are error, health, and firmware.\n", c_name);
 621  609  }
 622  610  
 623  611  static int
 624  612  do_get_logpage_error(int fd, const nvme_process_arg_t *npa)
 625  613  {
 626  614          int nlog = npa->npa_idctl->id_elpe + 1;
 627  615          size_t bufsize = sizeof (nvme_error_log_entry_t) * nlog;
 628  616          nvme_error_log_entry_t *elog;
 629  617  
 630      -        if (npa->npa_nsid != 0)
      618 +        if (npa->npa_isns)
 631  619                  errx(-1, "Error Log not available on a per-namespace basis");
 632  620  
 633  621          elog = nvme_get_logpage(fd, NVME_LOGPAGE_ERROR, &bufsize);
 634  622  
 635  623          if (elog == NULL)
 636  624                  return (-1);
 637  625  
 638  626          nlog = bufsize / sizeof (nvme_error_log_entry_t);
 639  627  
 640  628          (void) printf("%s: ", npa->npa_name);
↓ open down ↓ 3 lines elided ↑ open up ↑
 644  632  
 645  633          return (0);
 646  634  }
 647  635  
 648  636  static int
 649  637  do_get_logpage_health(int fd, const nvme_process_arg_t *npa)
 650  638  {
 651  639          size_t bufsize = sizeof (nvme_health_log_t);
 652  640          nvme_health_log_t *hlog;
 653  641  
 654      -        if (npa->npa_nsid != 0) {
      642 +        if (npa->npa_isns) {
 655  643                  if (npa->npa_idctl->id_lpa.lp_smart == 0)
 656  644                          errx(-1, "SMART/Health information not available "
 657  645                              "on a per-namespace basis on this controller");
 658  646          }
 659  647  
 660  648          hlog = nvme_get_logpage(fd, NVME_LOGPAGE_HEALTH, &bufsize);
 661  649  
 662  650          if (hlog == NULL)
 663  651                  return (-1);
 664  652  
↓ open down ↓ 4 lines elided ↑ open up ↑
 669  657  
 670  658          return (0);
 671  659  }
 672  660  
 673  661  static int
 674  662  do_get_logpage_fwslot(int fd, const nvme_process_arg_t *npa)
 675  663  {
 676  664          size_t bufsize = sizeof (nvme_fwslot_log_t);
 677  665          nvme_fwslot_log_t *fwlog;
 678  666  
 679      -        if (npa->npa_nsid != 0)
      667 +        if (npa->npa_isns)
 680  668                  errx(-1, "Firmware Slot information not available on a "
 681  669                      "per-namespace basis");
 682  670  
 683  671          fwlog = nvme_get_logpage(fd, NVME_LOGPAGE_FWSLOT, &bufsize);
 684  672  
 685  673          if (fwlog == NULL)
 686  674                  return (-1);
 687  675  
 688  676          (void) printf("%s: ", npa->npa_name);
 689  677          nvme_print_fwslot_log(fwlog);
↓ open down ↓ 108 lines elided ↑ open up ↑
 798  786  
 799  787          if (npa->npa_argc > 1)
 800  788                  errx(-1, "unexpected arguments");
 801  789  
 802  790          /*
 803  791           * No feature list given, print all supported features.
 804  792           */
 805  793          if (npa->npa_argc == 0) {
 806  794                  (void) printf("%s: Get Features\n", npa->npa_name);
 807  795                  for (feat = &features[0]; feat->f_feature != 0; feat++) {
 808      -                        if ((npa->npa_nsid != 0 &&
      796 +                        if ((npa->npa_isns &&
 809  797                              (feat->f_getflags & NVMEADM_NS) == 0) ||
 810      -                            (npa->npa_nsid == 0 &&
      798 +                            (!npa->npa_isns &&
 811  799                              (feat->f_getflags & NVMEADM_CTRL) == 0))
 812  800                                  continue;
 813  801  
 814  802                          (void) feat->f_get(fd, feat, npa->npa_idctl);
 815  803                  }
 816  804  
 817  805                  return (0);
 818  806          }
 819  807  
 820  808          /*
↓ open down ↓ 13 lines elided ↑ open up ↑
 834  822                          if (strncasecmp(feat->f_name, f, strlen(f)) == 0 ||
 835  823                              strncasecmp(feat->f_short, f, strlen(f)) == 0)
 836  824                                  break;
 837  825                  }
 838  826  
 839  827                  if (feat->f_feature == 0) {
 840  828                          warnx("unknown feature %s", f);
 841  829                          continue;
 842  830                  }
 843  831  
 844      -                if ((npa->npa_nsid != 0 &&
      832 +                if ((npa->npa_isns &&
 845  833                      (feat->f_getflags & NVMEADM_NS) == 0) ||
 846      -                    (npa->npa_nsid == 0 &&
      834 +                    (!npa->npa_isns &&
 847  835                      (feat->f_getflags & NVMEADM_CTRL) == 0)) {
 848  836                          warnx("feature %s %s supported for namespaces",
 849  837                              feat->f_name, (feat->f_getflags & NVMEADM_NS) != 0 ?
 850  838                              "only" : "not");
 851  839                          continue;
 852  840                  }
 853  841  
 854  842                  if (!header_printed) {
 855  843                          (void) printf("%s: Get Features\n", npa->npa_name);
 856  844                          header_printed = B_TRUE;
↓ open down ↓ 149 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX