From: Scott Bauer Date: Mon, 22 Aug 2016 23:19:24 +0000 (-0600) Subject: nvme-cli: Implement list command that doesn't rely on libudev X-Git-Tag: v0.9~9^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=91b1896799f8b9bfd7ab59e8bb298712d5b248e0;p=users%2Fsagi%2Fnvme-cli.git nvme-cli: Implement list command that doesn't rely on libudev 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 --- diff --git a/Documentation/nvme-list.1 b/Documentation/nvme-list.1 index fb7b0972..fdf7d503 100644 --- a/Documentation/nvme-list.1 +++ b/Documentation/nvme-list.1 @@ -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\&. diff --git a/Documentation/nvme-list.html b/Documentation/nvme-list.html index c24501a6..cdc4170d 100644 --- a/Documentation/nvme-list.html +++ b/Documentation/nvme-list.html @@ -762,7 +762,6 @@ nvme-list(1) Manual Page

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.

diff --git a/Documentation/nvme-list.txt b/Documentation/nvme-list.txt index 86bb2f98..ae69f8a4 100644 --- a/Documentation/nvme-list.txt +++ b/Documentation/nvme-list.txt @@ -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. diff --git a/README.md b/README.md index b136652e..6c7ea3d0 100644 --- 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 acf3de8e..3332d875 100644 --- a/nvme.c +++ b/nvme.c @@ -35,9 +35,7 @@ #include #include #include -#ifdef LIBUDEV_EXISTS -#include -#endif +#include #include @@ -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)) {