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 <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);

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 <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) {

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 <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 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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to