diff options
author | Jim Harris <jimharris@FreeBSD.org> | 2013-03-26 19:50:46 +0000 |
---|---|---|
committer | Jim Harris <jimharris@FreeBSD.org> | 2013-03-26 19:50:46 +0000 |
commit | b846efd7ece4a1f007bed1d320e5f6394beb3db9 (patch) | |
tree | 82359dedd1ed281aa3fd524aef64c2d6bb5a5a28 /sbin/nvmecontrol/nvmecontrol.c | |
parent | 3feffbd79665bf3111ec086058bbb6bee17f7f3d (diff) | |
download | src-b846efd7ece4a1f007bed1d320e5f6394beb3db9.tar.gz src-b846efd7ece4a1f007bed1d320e5f6394beb3db9.zip |
Add controller reset capability to nvme(4) and ability to explicitly
invoke it from nvmecontrol(8).
Controller reset will be performed in cases where I/O are repeatedly
timing out, the controller reports an unrecoverable condition, or
when explicitly requested via IOCTL or an nvme consumer. Since the
controller may be in such a state where it cannot even process queue
deletion requests, we will perform a controller reset without trying
to clean up anything on the controller first.
Sponsored by: Intel
Reviewed by: carl
Notes
Notes:
svn path=/head/; revision=248746
Diffstat (limited to 'sbin/nvmecontrol/nvmecontrol.c')
-rw-r--r-- | sbin/nvmecontrol/nvmecontrol.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/sbin/nvmecontrol/nvmecontrol.c b/sbin/nvmecontrol/nvmecontrol.c index 6abd3f5d1d7a..b6b6908ea524 100644 --- a/sbin/nvmecontrol/nvmecontrol.c +++ b/sbin/nvmecontrol/nvmecontrol.c @@ -56,6 +56,9 @@ __FBSDID("$FreeBSD$"); " <-i intr|wait> [-f refthread] [-p]\n" \ " <namespace id>\n" +#define RESET_USAGE \ +" nvmecontrol reset <controller id>\n" + static void perftest_usage(void); static void @@ -64,6 +67,7 @@ usage(void) fprintf(stderr, "usage:\n"); fprintf(stderr, DEVLIST_USAGE); fprintf(stderr, IDENTIFY_USAGE); + fprintf(stderr, RESET_USAGE); fprintf(stderr, PERFTEST_USAGE); exit(EX_USAGE); } @@ -580,6 +584,41 @@ perftest(int argc, char *argv[]) exit(EX_OK); } +static void +reset_ctrlr(int argc, char *argv[]) +{ + struct stat devstat; + char path[64]; + int ch, fd; + + while ((ch = getopt(argc, argv, "")) != -1) { + switch ((char)ch) { + default: + usage(); + } + } + + sprintf(path, "/dev/%s", argv[optind]); + + if (stat(path, &devstat) != 0) { + printf("Invalid device node '%s'.\n", path); + exit(EX_IOERR); + } + + fd = open(path, O_RDWR); + if (fd < 0) { + printf("Could not open %s.\n", path); + exit(EX_NOPERM); + } + + if (ioctl(fd, NVME_RESET_CONTROLLER) == -1) { + printf("ioctl to %s failed.\n", path); + exit(EX_IOERR); + } + + exit(EX_OK); +} + int main(int argc, char *argv[]) { @@ -593,6 +632,8 @@ main(int argc, char *argv[]) identify(argc-1, &argv[1]); else if (strcmp(argv[1], "perftest") == 0) perftest(argc-1, &argv[1]); + else if (strcmp(argv[1], "reset") == 0) + reset_ctrlr(argc-1, &argv[1]); usage(); |