diff options
author | jimharris <jimharris@FreeBSD.org> | 2013-07-09 21:31:21 +0000 |
---|---|---|
committer | jimharris <jimharris@FreeBSD.org> | 2013-07-09 21:31:21 +0000 |
commit | e9bddbcfa54c66d580d0e618ff4212c3a548837a (patch) | |
tree | d5f163d9caa466ceafbf43d39ff55ebfb5091c4b /sbin/nvmecontrol | |
parent | 6a4189c5fdf3d1448e04e1e52f11439d89305424 (diff) | |
download | FreeBSD-src-e9bddbcfa54c66d580d0e618ff4212c3a548837a.zip FreeBSD-src-e9bddbcfa54c66d580d0e618ff4212c3a548837a.tar.gz |
Send per-namespace logpage commands to the controller devnode, so they
are processed as admin commands, not I/O commands.
As part of this change, pull out the code for parsing a namespace node
string into a separate function, since it is used for both identify and
logpage commands.
Sponsored by: Intel
MFC after: 3 days
Diffstat (limited to 'sbin/nvmecontrol')
-rw-r--r-- | sbin/nvmecontrol/identify.c | 20 | ||||
-rw-r--r-- | sbin/nvmecontrol/logpage.c | 65 | ||||
-rw-r--r-- | sbin/nvmecontrol/nvmecontrol.c | 24 | ||||
-rw-r--r-- | sbin/nvmecontrol/nvmecontrol.h | 1 |
4 files changed, 53 insertions, 57 deletions
diff --git a/sbin/nvmecontrol/identify.c b/sbin/nvmecontrol/identify.c index 1fe2a34..189f164 100644 --- a/sbin/nvmecontrol/identify.c +++ b/sbin/nvmecontrol/identify.c @@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$"); #include <ctype.h> #include <err.h> -#include <errno.h> #include <fcntl.h> #include <stddef.h> #include <stdio.h> @@ -194,7 +193,6 @@ identify_ns(int argc, char *argv[]) { struct nvme_namespace_data nsdata; char path[64]; - char *nsloc; int ch, fd, hexflag = 0, hexlength, nsid; int verboseflag = 0; @@ -224,22 +222,12 @@ identify_ns(int argc, char *argv[]) close(fd); /* - * Pull the namespace id from the string. +2 skips past the "ns" part - * of the string. Don't search past 10 characters into the string, - * otherwise we know it is malformed. - */ - nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10); - if (nsloc != NULL) - nsid = strtol(nsloc + 2, NULL, 10); - if (nsloc == NULL || (nsid == 0 && errno != 0)) - errx(1, "invalid namespace ID '%s'", argv[optind]); - - /* * 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. + * 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. */ - snprintf(path, nsloc - argv[optind] + 1, "%s", argv[optind]); + parse_ns_str(argv[optind], path, &nsid); open_dev(path, &fd, 1, 1); read_namespace_data(fd, nsid, &nsdata); close(fd); diff --git a/sbin/nvmecontrol/logpage.c b/sbin/nvmecontrol/logpage.c index a26ce04..e330988 100644 --- a/sbin/nvmecontrol/logpage.c +++ b/sbin/nvmecontrol/logpage.c @@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$"); #include <ctype.h> #include <err.h> -#include <errno.h> #include <fcntl.h> #include <stdbool.h> #include <stddef.h> @@ -242,12 +241,11 @@ logpage_usage(void) void logpage(int argc, char *argv[]) { - int fd, nsid, len; + int fd, nsid; int log_page = 0, pageflag = false; - int hexflag = false; - int allow_ns = false; - char ch, *p, *nsloc = NULL; - char *cname = NULL; + int hexflag = false, ns_specified; + char ch, *p; + char cname[64]; uint32_t size; void *buf; struct logpage_function *f; @@ -290,46 +288,31 @@ logpage(int argc, char *argv[]) if (optind >= argc) logpage_usage(); + if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) { + ns_specified = true; + parse_ns_str(argv[optind], cname, &nsid); + open_dev(cname, &fd, 1, 1); + } else { + ns_specified = false; + nsid = NVME_GLOBAL_NAMESPACE_TAG; + open_dev(argv[optind], &fd, 1, 1); + } + /* * The log page attribtues indicate whether or not the controller * supports the SMART/Health information log page on a per * namespace basis. */ - cname = malloc(strlen(NVME_CTRLR_PREFIX) + 2); - len = strlen(NVME_CTRLR_PREFIX) + 1; - cname = strncpy(cname, argv[optind], len); - open_dev(cname, &fd, 1, 1); - read_controller_data(fd, &cdata); - - if (log_page == NVME_LOG_HEALTH_INFORMATION && cdata.lpa.ns_smart != 0) - allow_ns = true; - - /* If a namespace id was specified, validate it's use */ - if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) { - if (!allow_ns) { - if (log_page != NVME_LOG_HEALTH_INFORMATION) - errx(1, - "log page %d valid only at controller level", - log_page); - else if (cdata.lpa.ns_smart == 0) - errx(1, - "controller does not support per " - "namespace smart/health information"); - } - nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10); - if (nsloc != NULL) - nsid = strtol(nsloc + 2, NULL, 10); - if (nsloc == NULL || (nsid == 0 && errno != 0)) - errx(1, "invalid namespace id '%s'", argv[optind]); - - /* - * User is asking for per namespace log page information - * so close the controller and open up the namespace. - */ - close(fd); - open_dev(argv[optind], &fd, 1, 1); - } else - nsid = NVME_GLOBAL_NAMESPACE_TAG; + if (ns_specified) { + if (log_page != NVME_LOG_HEALTH_INFORMATION) + errx(1, "log page %d valid only at controller level", + log_page); + read_controller_data(fd, &cdata); + if (cdata.lpa.ns_smart == 0) + errx(1, + "controller does not support per namespace " + "smart/health information"); + } print_fn = print_hex; if (!hexflag) { diff --git a/sbin/nvmecontrol/nvmecontrol.c b/sbin/nvmecontrol/nvmecontrol.c index c566bb3..63cec3c 100644 --- a/sbin/nvmecontrol/nvmecontrol.c +++ b/sbin/nvmecontrol/nvmecontrol.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <ctype.h> #include <err.h> +#include <errno.h> #include <fcntl.h> #include <stdbool.h> #include <stddef.h> @@ -198,6 +199,29 @@ open_dev(const char *str, int *fd, int show_error, int exit_on_error) return (0); } +void +parse_ns_str(const char *ns_str, char *ctrlr_str, int *nsid) +{ + char *nsloc; + + /* + * Pull the namespace id from the string. +2 skips past the "ns" part + * of the string. Don't search past 10 characters into the string, + * otherwise we know it is malformed. + */ + nsloc = strnstr(ns_str, NVME_NS_PREFIX, 10); + if (nsloc != NULL) + *nsid = strtol(nsloc + 2, NULL, 10); + if (nsloc == NULL || (*nsid == 0 && errno != 0)) + errx(1, "invalid namespace ID '%s'", ns_str); + + /* + * The controller string will include only the nvmX part of the + * nvmeXnsY string. + */ + snprintf(ctrlr_str, nsloc - ns_str + 1, "%s", ns_str); +} + int main(int argc, char *argv[]) { diff --git a/sbin/nvmecontrol/nvmecontrol.h b/sbin/nvmecontrol/nvmecontrol.h index f7a35b4..99075f6 100644 --- a/sbin/nvmecontrol/nvmecontrol.h +++ b/sbin/nvmecontrol/nvmecontrol.h @@ -63,6 +63,7 @@ void logpage(int argc, char *argv[]); void firmware(int argc, char *argv[]); int open_dev(const char *str, int *fd, int show_error, int exit_on_error); +void parse_ns_str(const char *ns_str, char *ctrlr_str, int *nsid); void read_controller_data(int fd, struct nvme_controller_data *cdata); void read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata); void print_hex(void *data, uint32_t length); |