]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsblk: try device/dev to read devno
authorKarel Zak <kzak@redhat.com>
Fri, 9 Feb 2018 13:18:18 +0000 (14:18 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 9 Feb 2018 13:18:18 +0000 (14:18 +0100)
Now sysfs_devname_to_devno() reads devno from /dev or
/sys/block/<name>/dev, but it seems that NVME uses
/sys/block/<name>/device/dev.

Reported-by: Potnuri Bharat Teja <bharat@chelsio.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
lib/sysfs.c

index e8125e511de1f9a67cc0d6f733b85a67fa42da5b..b1b67c59fef88adf86709bc693415f05b772ee3b 100644 (file)
@@ -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/<parent>/<name>/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/<sysname>/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/<sysname>/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/<sysname>/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;
 }