]> www.infradead.org Git - users/hch/nvme-cli.git/commitdiff
nvme-cli: Implement list command that doesn't rely on libudev
authorScott Bauer <scott.bauer@intel.com>
Mon, 22 Aug 2016 23:19:24 +0000 (17:19 -0600)
committerScott Bauer <scott.bauer@intel.com>
Tue, 23 Aug 2016 16:22:49 +0000 (10:22 -0600)
The previous list command required libudev. We can accomplish the same
thing with standard functions. Libudev is still required for some code
in fabrics.c, but the depencency has been removed from nvme.c.

Signed-off-by: Scott Bauer <scott.bauer@intel.com>
Documentation/nvme-list.1
Documentation/nvme-list.html
Documentation/nvme-list.txt
README.md
nvme.c

index fb7b09728a6a714a7f64576272c1e2e787c5cfb5..fdf7d5033f5ec8f797b5a0371be8825fa4f28fa8 100644 (file)
@@ -38,7 +38,6 @@ nvme-list \- List all recognized NVMe devices
 .sp
 Scan the sysfs tree for NVM Express devices and return the /dev node for those devices as well as some pertinent information about them\&.
 .sp
-This command requires udev\&.
 .SH "OPTIONS"
 .sp
 No options yet\&.
index c24501a622f2d0d244c2bfd29be20ea438b904fa..cdc4170d6de370f779c03e9fdf971e03654808a9 100644 (file)
@@ -762,7 +762,6 @@ nvme-list(1) Manual Page
 <div class="sectionbody">\r
 <div class="paragraph"><p>Scan the sysfs tree for NVM Express devices and return the /dev node\r
 for those devices as well as some pertinent information about them.</p></div>\r
-<div class="paragraph"><p>This command requires udev.</p></div>\r
 </div>\r
 </div>\r
 <div class="sect1">\r
index 86bb2f98c53fd8921f5bebc52c96586b01715bb9..ae69f8a4aca5b0e4aabf71c91cc1da90a27c7da7 100644 (file)
@@ -15,8 +15,6 @@ DESCRIPTION
 Scan the sysfs tree for NVM Express devices and return the /dev node
 for those devices as well as some pertinent information about them.
 
-This command requires udev.
-
 OPTIONS
 -------
 No options yet.
index b136652e8ee417328c8482932b030a2c33e5dcc8..6c7ea3d0d6fcef253586697273caa847d434914e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -62,13 +62,7 @@ steps:
 nvme-cli is tested on AlpineLinux 3.3.  Install it using:
 
     # akp update && apk add nvme-cli nvme-cli-doc
-    
-    the "list" command will not work unless you installed udev for some reason.
-    ```
-    # nvme list
-    nvme-list: libudev not detected, install and rebuild.
-    ```
-    
+
     if you just use the device you're after, it will work flawless.
     ```
     # nvme smart-log /dev/nvme0
diff --git a/nvme.c b/nvme.c
index acf3de8ea3762e237cd037a6d3624ef0e6bb29b5..3332d8758cdc23356e077d8831ee40b0a6fa1070 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -35,9 +35,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <math.h>
-#ifdef LIBUDEV_EXISTS
-#include <libudev.h>
-#endif
+#include <dirent.h>
 
 #include <linux/fs.h>
 
@@ -704,6 +702,7 @@ static void get_registers(struct nvme_bar **bar)
        *bar = membase;
 }
 
+#define MAX_LIST_ITEMS 256
 struct list_item {
        char                node[1024];
        struct nvme_id_ctrl ctrl;
@@ -713,7 +712,7 @@ struct list_item {
        __le32              ver;
 };
 
-#ifdef LIBUDEV_EXISTS
+
 /* For pre NVMe 1.2 devices we must get the version from the BAR, not the
  * ctrl_id.*/
 static void get_version(struct list_item* list_item)
@@ -771,83 +770,102 @@ static void print_list_items(struct list_item *list_items, unsigned len)
                print_list_item(list_items[i]);
 
 }
-#else
-static int list(int argc, char **argv, struct command *cmd, struct plugin *plugin)
-{
-       fprintf(stderr,"nvme-list: libudev not detected, install and rebuild.\n");
-       return -1;
-}
-#endif
 
-static int get_nsid()
+static int get_nvme_info(int fd, struct list_item *item, const char *node)
 {
-       int nsid = nvme_get_nsid(fd);
+       int err;
 
-       if (nsid <= 0) {
-               fprintf(stderr,
-                       "%s: failed to return namespace id\n",
-                       devicename);
-               exit(errno);
-       }
-       return nsid;
+       err = nvme_identify_ctrl(fd, &item->ctrl);
+       if (err > 0)
+               return err;
+       item->nsid = nvme_get_nsid(fd);
+       err = nvme_identify_ns(fd, item->nsid,
+                              0, &item->ns);
+       if (err > 0)
+               return err;
+       strcpy(item->node, node);
+       item->block = S_ISBLK(nvme_stat.st_mode);
+       get_version(item);
+
+       return 0;
 }
 
-#ifdef LIBUDEV_EXISTS
-#define MAX_LIST_ITEMS 256
+static const char *dev = "/dev/";
 static int list(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       struct udev *udev;
-       struct udev_enumerate *enumerate;
-       struct udev_list_entry *devices, *dev_list_entry;
-       struct udev_device *dev;
-
+       DIR *d;
+       struct dirent entry;
+       struct dirent *r_entry;
+       char path[256] = { 0 };
        struct list_item list_items[MAX_LIST_ITEMS];
-       unsigned count=0;
+       struct stat bd;
+       unsigned int count = 0;
+       int ret;
 
-       udev = udev_new();
-       if (!udev) {
-               perror("nvme-list: Cannot create udev context.");
+       d = opendir(dev);
+       if (!d) {
+               fprintf(stderr,
+                       "Failed to open directory %s with error %s\n",
+                       dev, strerror(errno));
                return errno;
        }
 
-       enumerate = udev_enumerate_new(udev);
-       udev_enumerate_add_match_subsystem(enumerate, "block");
-       udev_enumerate_add_match_property(enumerate, "DEVTYPE", "disk");
-       udev_enumerate_scan_devices(enumerate);
-       devices = udev_enumerate_get_list_entry(enumerate);
-       udev_list_entry_foreach(dev_list_entry, devices) {
-               int err;
-               const char *path, *node;
-               path = udev_list_entry_get_name(dev_list_entry);
-               dev  = udev_device_new_from_syspath(udev, path);
-               node = udev_device_get_devnode(dev);
-               if (strstr(node,"nvme")!=NULL){
-                       open_dev(node);
-                       err = nvme_identify_ctrl(fd, &list_items[count].ctrl);
-                       if (err > 0)
-                               return err;
-                       list_items[count].nsid = nvme_get_nsid(fd);
-                       err = nvme_identify_ns(fd, list_items[count].nsid,
-                                               0, &list_items[count].ns);
-                       if (err > 0)
-                               return err;
-                       strcpy(list_items[count].node, node);
-                       list_items[count].block = S_ISBLK(nvme_stat.st_mode);
-                       get_version(&list_items[count]);
-                       count++;
+       while (1) {
+               if (readdir_r(d, &entry, &r_entry)) {
+                       fprintf(stderr,
+                               "Failed to read contents of %s with error %s\n",
+                               dev, strerror(errno));
+                       closedir(d);
+                       return errno;
+               }
+               /* done reading the directory stream */
+               if (r_entry == NULL)
+                       break;
+               /* lets not walk the entire fs */
+               if (!strcmp(entry.d_name, ".."))
+                       continue;
+
+               if (strstr(entry.d_name, "nvme") != NULL) {
+                       snprintf(path, sizeof(path), "%s%s", dev, entry.d_name);
+                       if (stat(path, &bd)) {
+                               fprintf(stderr,
+                                       "Failed to stat %s with error %s\n",
+                                       path, strerror(errno));
+                               closedir(d);
+                               return errno;
+                       }
+                       if (S_ISBLK(bd.st_mode)) {
+                               open_dev(path);
+                               ret = get_nvme_info(fd, &list_items[count], path);
+                               if (ret > 0) {
+                                       closedir(d);
+                                       return ret;
+                               }
+                               count++;
+                       }
                }
        }
-       udev_enumerate_unref(enumerate);
-       udev_unref(udev);
+       closedir(d);
 
        if (count)
                print_list_items(list_items, count);
        else
                printf("No NVMe devices detected.\n");
-
        return 0;
 }
-#endif
+
+static int get_nsid()
+{
+       int nsid = nvme_get_nsid(fd);
+
+       if (nsid <= 0) {
+               fprintf(stderr,
+                       "%s: failed to return namespace id\n",
+                       devicename);
+               exit(errno);
+       }
+       return nsid;
+}
 
 int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin, void (*vs)(__u8 *vs))
 {