summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorKarel Zak2018-02-09 14:18:18 +0100
committerKarel Zak2018-02-09 14:18:18 +0100
commitd51f05bfecb299a830897106460bf395be440c0a (patch)
tree5a35c8efdedfc35aade35715a281b0d86b264b8f /lib
parentdocs: update TODO (diff)
downloadkernel-qcow2-util-linux-d51f05bfecb299a830897106460bf395be440c0a.tar.gz
kernel-qcow2-util-linux-d51f05bfecb299a830897106460bf395be440c0a.tar.xz
kernel-qcow2-util-linux-d51f05bfecb299a830897106460bf395be440c0a.zip
lsblk: try device/dev to read devno
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/sysfs.c97
1 files 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/<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;
}