From d51f05bfecb299a830897106460bf395be440c0a Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 9 Feb 2018 14:18:18 +0100 Subject: [PATCH] lsblk: try device/dev to read devno Now sysfs_devname_to_devno() reads devno from /dev or /sys/block//dev, but it seems that NVME uses /sys/block//device/dev. Reported-by: Potnuri Bharat Teja Signed-off-by: Karel Zak --- lib/sysfs.c | 97 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/lib/sysfs.c b/lib/sysfs.c index e8125e511..b1b67c59f 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -48,10 +48,28 @@ char *sysfs_devno_path(dev_t devno, char *buf, size_t bufsiz) return sysfs_devno_attribute_path(devno, buf, bufsiz, NULL); } +static dev_t read_devno(const char *path) +{ + FILE *f; + int maj = 0, min = 0; + dev_t dev = 0; + + f = fopen(path, "r" UL_CLOEXECSTR); + if (!f) + return 0; + + if (fscanf(f, "%d:%d", &maj, &min) == 2) + dev = makedev(maj, min); + fclose(f); + return dev; +} + dev_t sysfs_devname_to_devno(const char *name, const char *parent) { - char buf[PATH_MAX], *path = NULL; + char buf[PATH_MAX]; + char *_name = NULL; /* name as encoded in sysfs */ dev_t dev = 0; + int len; if (strncmp("/dev/", name, 5) == 0) { /* @@ -59,69 +77,62 @@ dev_t sysfs_devname_to_devno(const char *name, const char *parent) */ struct stat st; - if (stat(name, &st) == 0) + if (stat(name, &st) == 0) { dev = st.st_rdev; - else - name += 5; /* unaccesible, or not node in /dev */ + goto done; + } + name += 5; /* unaccesible, or not node in /dev */ } - if (!dev && parent && strncmp("dm-", name, 3)) { + _name = strdup(name); + if (!_name) + goto done; + sysfs_devname_dev_to_sys(_name); + + if (parent && strncmp("dm-", name, 3)) { /* * Create path to /sys/block///dev */ - char *_name = strdup(name), *_parent = strdup(parent); - int len; + char *_parent = strdup(parent); - if (!_name || !_parent) { - free(_name); + if (!_parent) { free(_parent); - return 0; + goto done; } - sysfs_devname_dev_to_sys(_name); sysfs_devname_dev_to_sys(_parent); len = snprintf(buf, sizeof(buf), _PATH_SYS_BLOCK "/%s/%s/dev", _parent, _name); - free(_name); free(_parent); if (len < 0 || (size_t) len >= sizeof(buf)) - return 0; - path = buf; + goto done; - } else if (!dev) { - /* - * Create path to /sys/block//dev - */ - char *_name = strdup(name); - int len; - - if (!_name) - return 0; - - sysfs_devname_dev_to_sys(_name); - len = snprintf(buf, sizeof(buf), - _PATH_SYS_BLOCK "/%s/dev", _name); - free(_name); - if (len < 0 || (size_t) len >= sizeof(buf)) - return 0; - path = buf; + /* don't try anything else for dm-* */ + dev = read_devno(buf); + goto done; } - if (path) { + /* + * Read from /sys/block//dev + */ + len = snprintf(buf, sizeof(buf), + _PATH_SYS_BLOCK "/%s/dev", _name); + if (len < 0 || (size_t) len >= sizeof(buf)) + goto done; + dev = read_devno(buf); + + if (!dev) { /* - * read devno from sysfs + * Read from /sys/block//device/dev */ - FILE *f; - int maj = 0, min = 0; - - f = fopen(path, "r" UL_CLOEXECSTR); - if (!f) - return 0; - - if (fscanf(f, "%d:%d", &maj, &min) == 2) - dev = makedev(maj, min); - fclose(f); + len = snprintf(buf, sizeof(buf), + _PATH_SYS_BLOCK "/%s/device/dev", _name); + if (len < 0 || (size_t) len >= sizeof(buf)) + goto done; + dev = read_devno(buf); } +done: + free(_name); return dev; } -- 2.16.1