From owner-svn-src-stable@FreeBSD.ORG Fri Jul 12 22:14:58 2013 Return-Path: Delivered-To: svn-src-stable@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 66B3DDC0; Fri, 12 Jul 2013 22:14:58 +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 57F0B122A; Fri, 12 Jul 2013 22:14:58 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6CMEwTb069166; Fri, 12 Jul 2013 22:14:58 GMT (envelope-from jimharris@svn.freebsd.org) Received: (from jimharris@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6CMEvQQ069162; Fri, 12 Jul 2013 22:14:57 GMT (envelope-from jimharris@svn.freebsd.org) Message-Id: <201307122214.r6CMEvQQ069162@svn.freebsd.org> From: Jim Harris Date: Fri, 12 Jul 2013 22:14:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r253300 - stable/9/sbin/nvmecontrol X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jul 2013 22:14:58 -0000 Author: jimharris Date: Fri Jul 12 22:14:57 2013 New Revision: 253300 URL: http://svnweb.freebsd.org/changeset/base/253300 Log: MFC r253114: 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. Approved by: re (kib) Modified: stable/9/sbin/nvmecontrol/identify.c stable/9/sbin/nvmecontrol/logpage.c stable/9/sbin/nvmecontrol/nvmecontrol.c stable/9/sbin/nvmecontrol/nvmecontrol.h Directory Properties: stable/9/sbin/nvmecontrol/ (props changed) Modified: stable/9/sbin/nvmecontrol/identify.c ============================================================================== --- stable/9/sbin/nvmecontrol/identify.c Fri Jul 12 22:13:46 2013 (r253299) +++ stable/9/sbin/nvmecontrol/identify.c Fri Jul 12 22:14:57 2013 (r253300) @@ -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: stable/9/sbin/nvmecontrol/logpage.c ============================================================================== --- stable/9/sbin/nvmecontrol/logpage.c Fri Jul 12 22:13:46 2013 (r253299) +++ stable/9/sbin/nvmecontrol/logpage.c Fri Jul 12 22:14:57 2013 (r253300) @@ -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: stable/9/sbin/nvmecontrol/nvmecontrol.c ============================================================================== --- stable/9/sbin/nvmecontrol/nvmecontrol.c Fri Jul 12 22:13:46 2013 (r253299) +++ stable/9/sbin/nvmecontrol/nvmecontrol.c Fri Jul 12 22:14:57 2013 (r253300) @@ -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: stable/9/sbin/nvmecontrol/nvmecontrol.h ============================================================================== --- stable/9/sbin/nvmecontrol/nvmecontrol.h Fri Jul 12 22:13:46 2013 (r253299) +++ stable/9/sbin/nvmecontrol/nvmecontrol.h Fri Jul 12 22:14:57 2013 (r253300) @@ -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);