[PATCH] Fix /sys to /dev node name translation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



linux/drivers/base/core.c: device_get_devnode() defines a translation of
'!' in sysfs nodes to '/' in /dev nodes. The same translation has to be
done to properly support device nodes with slash (e. g. device nodes of
cciss driver and several other drivers).

Replace '!' by '/' in sysfs_devno_to_devpath() exactly like kernel does.

The problem is spread across more places of the code.

One of the chunks fixes lsblk -f, other chunks fixes code that apparently
assumes that /sys/block and /dev node names are the same, however I do
not have any reproducer for them. I fixed all places I found, but it is
possible that there are even more occurrences.

Signed-off-by: Stanislav Brabec <sbrabec@xxxxxxx>
---
 lib/sysfs.c          | 14 ++++++++++++--
 libblkid/src/devno.c |  7 ++++++-
 misc-utils/lsblk.c   |  7 +++++++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/lib/sysfs.c b/lib/sysfs.c
index 759d97b..ffdc8a1 100644
--- a/lib/sysfs.c
+++ b/lib/sysfs.c
@@ -112,7 +112,7 @@ dev_t sysfs_devname_to_devno(const char *name, const char *parent)
 char *sysfs_devno_to_devpath(dev_t devno, char *buf, size_t bufsiz)
 {
 	struct sysfs_cxt cxt;
-	char *name;
+	char *name, *s;
 	size_t sz;
 	struct stat st;
 
@@ -130,6 +130,11 @@ char *sysfs_devno_to_devpath(dev_t devno, char *buf, size_t bufsiz)
 	if (sz + sizeof("/dev/") > bufsiz)
 		return NULL;
 
+	/* replace '!' in the name with '/', see
+	 * linux/drivers/base/core.c: device_get_devnode() */
+	while ((s = strchr(name, '!')))
+		s[0] = '/';
+
 	/* create the final "/dev/<name>" string */
 	memmove(buf + 5, name, sz + 1);
 	memcpy(buf, "/dev/", 5);
@@ -776,7 +781,7 @@ int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
          *  - basename ../../block/sda      = sda
          */
         char linkpath[PATH_MAX];
-        char *name;
+        char *name, *s;
 	ssize_t	linklen;
 
 	linklen = sysfs_readlink(&cxt, NULL, linkpath, sizeof(linkpath) - 1);
@@ -789,6 +794,11 @@ int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
         if (!name)
             goto err;
 
+	/* replace '!' in the name with '/', see
+	 * linux/drivers/base/core.c: device_get_devnode() */
+	while ((s = strchr(name, '!')))
+		s[0] = '/';
+
         if (diskname && len) {
             strncpy(diskname, name, len);
             diskname[len - 1] = '\0';
diff --git a/libblkid/src/devno.c b/libblkid/src/devno.c
index f4a36e4..cedd2db 100644
--- a/libblkid/src/devno.c
+++ b/libblkid/src/devno.c
@@ -179,7 +179,7 @@ static const char *devdirs[] = { "/devices", "/devfs", "/dev", NULL };
 static char *scandev_devno_to_devpath(dev_t devno)
 {
 	struct dir_list *list = NULL, *new_list = NULL;
-	char *devname = NULL;
+	char *devname = NULL, *s;
 	const char **dir;
 
 	/*
@@ -208,6 +208,11 @@ static char *scandev_devno_to_devpath(dev_t devno)
 			new_list = NULL;
 		}
 	}
+	/* replace '!' in the name with '/', see
+	 * linux/drivers/base/core.c: device_get_devnode() */
+	if (devname)
+		while ((s = strchr(devname, '!')))
+			s[0] = '/';
 	free_dirlist(&list);
 	free_dirlist(&new_list);
 
diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c
index 1b4ffc1..5cdae7d 100644
--- a/misc-utils/lsblk.c
+++ b/misc-utils/lsblk.c
@@ -413,6 +413,7 @@ static struct dirent *xreaddir(DIR *dp)
 static char *get_device_path(struct blkdev_cxt *cxt)
 {
 	char path[PATH_MAX];
+	char *s;
 
 	assert(cxt);
 	assert(cxt->name);
@@ -421,6 +422,12 @@ static char *get_device_path(struct blkdev_cxt *cxt)
 		return canonicalize_dm_name(cxt->name);
 
 	snprintf(path, sizeof(path), "/dev/%s", cxt->name);
+
+	/* replace '!' in the name with '/', see
+	 * linux/drivers/base/core.c: device_get_devnode() */
+	while ((s = strchr(path, '!')))
+		s[0] = '/';
+
 	return xstrdup(path);
 }
 
-- 
2.4.1

-- 
Best Regards / S pozdravem,

Stanislav Brabec
software developer
---------------------------------------------------------------------
SUSE LINUX, s. r. o.                          e-mail: sbrabec@xxxxxxx
Lihovarská 1060/12                            tel: +49 911 7405384547
190 00 Praha 9                                 fax:  +420 284 084 001
Czech Republic                                    http://www.suse.cz/
PGP: 830B 40D5 9E05 35D8 5E27 6FA3 717C 209F A04F CD76
--
To unsubscribe from this list: send the line "unsubscribe util-linux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux