diff options
author | jimharris <jimharris@FreeBSD.org> | 2013-06-26 22:50:49 +0000 |
---|---|---|
committer | jimharris <jimharris@FreeBSD.org> | 2013-06-26 22:50:49 +0000 |
commit | 247f8065f6cb2f359273faf17f2082f1db74ea8a (patch) | |
tree | 5102befb890466c82aefff7f37dcf18ce85a046a /sbin/nvmecontrol | |
parent | 02bac7d9704bfc60277b722c5e4f4b5f6d22444e (diff) | |
download | FreeBSD-src-247f8065f6cb2f359273faf17f2082f1db74ea8a.zip FreeBSD-src-247f8065f6cb2f359273faf17f2082f1db74ea8a.tar.gz |
Add an open_dev() helper function to be used in the various places
where nvmecontrol needs to open a handle to a controller or namespace
device node.
Sponsored by: Intel
MFC after: 3 days
Diffstat (limited to 'sbin/nvmecontrol')
-rw-r--r-- | sbin/nvmecontrol/nvmecontrol.c | 166 |
1 files changed, 63 insertions, 103 deletions
diff --git a/sbin/nvmecontrol/nvmecontrol.c b/sbin/nvmecontrol/nvmecontrol.c index fd55b42..9e0b8ec 100644 --- a/sbin/nvmecontrol/nvmecontrol.c +++ b/sbin/nvmecontrol/nvmecontrol.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2012 Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -258,13 +258,42 @@ read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata) } } +static int +open_dev(const char *str, int *fd, int show_error, int exit_on_error) +{ + struct stat devstat; + char full_path[64]; + + snprintf(full_path, sizeof(full_path), "/dev/%s", str); + if (stat(full_path, &devstat) != 0) { + if (show_error) + fprintf(stderr, "error\n"); + if (exit_on_error) + exit(EX_NOINPUT); + else + return (EX_NOINPUT); + } + + *fd = open(full_path, O_RDWR); + if (*fd < 0) { + if (show_error) + printf("Could not open %s. errno=%d (%s)\n", full_path, + errno, strerror(errno)); + if (exit_on_error) + exit(EX_NOPERM); + else + return (EX_NOPERM); + } + + return (EX_OK); +} + static void devlist(int argc, char *argv[]) { struct nvme_controller_data cdata; struct nvme_namespace_data nsdata; - struct stat devstat; - char name[64], path[64]; + char name[64]; uint32_t i; int ch, ctrlr, exit_code, fd, found; @@ -283,21 +312,18 @@ devlist(int argc, char *argv[]) while (1) { ctrlr++; sprintf(name, "nvme%d", ctrlr); - sprintf(path, "/dev/%s", name); - if (stat(path, &devstat) != 0) - break; + exit_code = open_dev(name, &fd, 0, 0); - found++; - - fd = open(path, O_RDWR); - if (fd < 0) { - printf("Could not open %s. errno=%d (%s)\n", path, - errno, strerror(errno)); - exit_code = EX_NOPERM; + if (exit_code == EX_NOINPUT) + break; + else if (exit_code == EX_NOPERM) { + printf("Could not open /dev/%s, errno = %d (%s)\n", + name, errno, strerror(errno)); continue; } + found++; read_controller_data(fd, &cdata); printf("%6s: %s\n", name, cdata.mn); @@ -310,20 +336,20 @@ devlist(int argc, char *argv[]) (long long)ns_get_sector_size(&nsdata) / 1024 / 1024 / 1024); } + + close(fd); } if (found == 0) printf("No NVMe controllers found.\n"); - exit(exit_code); + exit(EX_OK); } static void identify_ctrlr(int argc, char *argv[]) { struct nvme_controller_data cdata; - struct stat devstat; - char path[64]; int ch, fd, hexflag = 0, hexlength; int verboseflag = 0; @@ -340,22 +366,9 @@ identify_ctrlr(int argc, char *argv[]) } } - 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); - } - - fd = open(path, O_RDWR); - if (fd < 0) { - printf("Could not open %s. errno=%d (%s)\n", path, errno, - strerror(errno)); - exit(EX_NOPERM); - } - + open_dev(argv[optind], &fd, 1, 1); read_controller_data(fd, &cdata); + close(fd); if (hexflag == 1) { if (verboseflag == 1) @@ -380,7 +393,6 @@ 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; @@ -404,25 +416,18 @@ identify_ns(int argc, char *argv[]) * 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); - } + open_dev(argv[optind], &fd, 1, 1); + close(fd); /* * Pull the namespace id from the string. +2 skips past the "ns" part - * of the string. + * of the string. Don't search past 10 characters into the string, + * otherwise we know it is malformed. */ - nsid = strtol(nsloc + 2, NULL, 10); - if (nsid == 0 && errno != 0) { + nsloc = strnstr(argv[optind], "ns", 10); + if (nsloc != NULL) + nsid = strtol(nsloc + 2, NULL, 10); + if (nsloc == NULL || (nsid == 0 && errno != 0)) { printf("Invalid namespace ID %s.\n", argv[optind]); exit(EX_IOERR); } @@ -432,22 +437,10 @@ identify_ns(int argc, char *argv[]) * 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); - } - + snprintf(path, nsloc - argv[optind] + 1, "%s", argv[optind]); + open_dev(path, &fd, 1, 1); read_namespace_data(fd, nsid, &nsdata); + close(fd); if (hexflag == 1) { if (verboseflag == 1) @@ -480,12 +473,6 @@ identify(int argc, char *argv[]) target = argv[optind]; - /* Specified device node must have "nvme" in it. */ - if (strstr(argv[optind], "nvme") == NULL) { - printf("Invalid device node '%s'.\n", argv[optind]); - exit(EX_IOERR); - } - optreset = 1; optind = 1; @@ -538,14 +525,11 @@ perftest(int argc, char *argv[]) int fd; char ch; char *p; - const char *name; - char path[64]; u_long ioctl_cmd = NVME_IO_TEST; bool nflag, oflag, sflag, tflag; int perthread = 0; nflag = oflag = sflag = tflag = false; - name = NULL; memset(&io_test, 0, sizeof(io_test)); @@ -623,26 +607,18 @@ perftest(int argc, char *argv[]) } } - name = argv[optind]; - - if (!nflag || !oflag || !sflag || !tflag || name == NULL) + if (!nflag || !oflag || !sflag || !tflag || optind >= argc) perftest_usage(); - sprintf(path, "/dev/%s", name); - - fd = open(path, O_RDWR); - if (fd < 0) { - fprintf(stderr, "%s not valid device. errno=%d (%s)\n", path, - errno, strerror(errno)); - perftest_usage(); - } - + open_dev(argv[optind], &fd, 1, 1); if (ioctl(fd, ioctl_cmd, &io_test) < 0) { fprintf(stderr, "NVME_IO_TEST failed. errno=%d (%s)\n", errno, strerror(errno)); + close(fd); exit(EX_IOERR); } + close(fd); print_perftest(&io_test, perthread); exit(EX_OK); } @@ -650,9 +626,7 @@ perftest(int argc, char *argv[]) static void reset_ctrlr(int argc, char *argv[]) { - struct stat devstat; - char path[64]; - int ch, fd; + int ch, fd; while ((ch = getopt(argc, argv, "")) != -1) { switch ((char)ch) { @@ -661,24 +635,10 @@ reset_ctrlr(int argc, char *argv[]) } } - 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); - } - - fd = open(path, O_RDWR); - if (fd < 0) { - printf("Could not open %s. errno=%d (%s)\n", path, errno, - strerror(errno)); - exit(EX_NOPERM); - } - + open_dev(argv[optind], &fd, 1, 1); if (ioctl(fd, NVME_RESET_CONTROLLER) < 0) { - printf("Reset request to %s failed. errno=%d (%s)\n", path, - errno, strerror(errno)); + printf("Reset request to %s failed. errno=%d (%s)\n", + argv[optind], errno, strerror(errno)); exit(EX_IOERR); } |