static void identify_ns(int argc, char *argv[]) { struct nvme_namespace_data nsdata; char path[64]; int ch, fd, hexflag = 0, hexlength, nsid; int verboseflag = 0; while ((ch = getopt(argc, argv, "vx")) != -1) { switch ((char)ch) { case 'v': verboseflag = 1; break; case 'x': hexflag = 1; break; default: identify_usage(); } } /* Check that a namespace was specified. */ if (optind >= argc) identify_usage(); /* * Check if the specified device node exists before continuing. * This is a cleaner check for cases where the correct controller * is specified, but an invalid namespace on that controller. */ open_dev(argv[optind], &fd, 1, 1); close(fd); /* * We send IDENTIFY commands to the controller, not the namespace, * since it is an admin cmd. The namespace ID will be specified in * the IDENTIFY command itself. So parse the namespace's device node * string to get the controller substring and namespace ID. */ parse_ns_str(argv[optind], path, &nsid); open_dev(path, &fd, 1, 1); read_namespace_data(fd, nsid, &nsdata); close(fd); if (hexflag == 1) { if (verboseflag == 1) hexlength = sizeof(struct nvme_namespace_data); else hexlength = offsetof(struct nvme_namespace_data, reserved6); print_hex(&nsdata, hexlength); exit(0); } if (verboseflag == 1) { fprintf(stderr, "-v not currently supported without -x\n"); identify_usage(); } print_namespace(&nsdata); exit(0); }
static void identify_ns(int argc, char *argv[]) { struct nvme_namespace_data nsdata; struct stat devstat; char path[64]; char *nsloc; int ch, fd, hexflag = 0, hexlength, nsid; int verboseflag = 0; while ((ch = getopt(argc, argv, "vx")) != -1) { switch ((char)ch) { case 'v': verboseflag = 1; break; case 'x': hexflag = 1; break; default: usage(); } } /* * Check if the specified device node exists before continuing. * This is a cleaner check for cases where the correct controller * is specified, but an invalid namespace on that controller. */ sprintf(path, "/dev/%s", argv[optind]); if (stat(path, &devstat) < 0) { printf("Invalid device node %s. errno=%d (%s)\n", path, errno, strerror(errno)); exit(EX_IOERR); } nsloc = strstr(argv[optind], "ns"); if (nsloc == NULL) { printf("Invalid namepsace %s.\n", argv[optind]); exit(EX_IOERR); } /* * Pull the namespace id from the string. +2 skips past the "ns" part * of the string. */ nsid = strtol(nsloc + 2, NULL, 10); if (nsid == 0 && errno != 0) { printf("Invalid namespace ID %s.\n", argv[optind]); exit(EX_IOERR); } /* * We send IDENTIFY commands to the controller, not the namespace, * since it is an admin cmd. So the path should only include the * nvmeX part of the nvmeXnsY string. */ sprintf(path, "/dev/"); strncat(path, argv[optind], nsloc - argv[optind]); if (stat(path, &devstat) < 0) { printf("Invalid device node %s. errno=%d (%s)\n", path, errno, strerror(errno)); exit(EX_IOERR); } fd = open(path, O_RDWR); if (fd < 0) { printf("Could not open %s. errno=%d (%s)\n", path, errno, strerror(errno)); exit(EX_NOPERM); } read_namespace_data(fd, nsid, &nsdata); if (hexflag == 1) { if (verboseflag == 1) hexlength = sizeof(struct nvme_namespace_data); else hexlength = offsetof(struct nvme_namespace_data, reserved6); print_namespace_hex(&nsdata, hexlength); exit(EX_OK); } if (verboseflag == 1) { printf("-v not currently supported without -x.\n"); usage(); } print_namespace(&nsdata); exit(EX_OK); }