From owner-svn-src-head@FreeBSD.ORG Tue Jul 9 21:31:23 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 06B2BE05; Tue, 9 Jul 2013 21:31:23 +0000 (UTC) (envelope-from jimharris@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id ECB4D1E05; Tue, 9 Jul 2013 21:31:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r69LVMVj051015; Tue, 9 Jul 2013 21:31:22 GMT (envelope-from jimharris@svn.freebsd.org) Received: (from jimharris@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r69LVM1i051009; Tue, 9 Jul 2013 21:31:22 GMT (envelope-from jimharris@svn.freebsd.org) Message-Id: <201307092131.r69LVM1i051009@svn.freebsd.org> From: Jim Harris Date: Tue, 9 Jul 2013 21:31:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r253114 - head/sbin/nvmecontrol X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Jul 2013 21:31:23 -0000 Author: jimharris Date: Tue Jul 9 21:31:21 2013 New Revision: 253114 URL: http://svnweb.freebsd.org/changeset/base/253114 Log: 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 Modified: head/sbin/nvmecontrol/identify.c head/sbin/nvmecontrol/logpage.c head/sbin/nvmecontrol/nvmecontrol.c head/sbin/nvmecontrol/nvmecontrol.h Modified: head/sbin/nvmecontrol/identify.c ============================================================================== --- head/sbin/nvmecontrol/identify.c Tue Jul 9 21:24:19 2013 (r253113) +++ head/sbin/nvmecontrol/identify.c Tue Jul 9 21:31:21 2013 (r253114) @@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include @@ -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); Modified: head/sbin/nvmecontrol/logpage.c ============================================================================== --- head/sbin/nvmecontrol/logpage.c Tue Jul 9 21:24:19 2013 (r253113) +++ head/sbin/nvmecontrol/logpage.c Tue Jul 9 21:31:21 2013 (r253114) @@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include @@ -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) { Modified: head/sbin/nvmecontrol/nvmecontrol.c ============================================================================== --- head/sbin/nvmecontrol/nvmecontrol.c Tue Jul 9 21:24:19 2013 (r253113) +++ head/sbin/nvmecontrol/nvmecontrol.c Tue Jul 9 21:31:21 2013 (r253114) @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -198,6 +199,29 @@ open_dev(const char *str, int *fd, int s 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[]) { Modified: head/sbin/nvmecontrol/nvmecontrol.h ============================================================================== --- head/sbin/nvmecontrol/nvmecontrol.h Tue Jul 9 21:24:19 2013 (r253113) +++ head/sbin/nvmecontrol/nvmecontrol.h Tue Jul 9 21:31:21 2013 (r253114) @@ -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);