aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolaus Voss <n.voss@weinmann.de>2013-05-13 03:55:11 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-05-13 03:55:11 +0200
commitc3cf1e30a3022453311a7e9fe11d94c7a381640e (patch)
tree0c451c05fd19f50a0b24368201a65e69500d6e8a
parentff463a885d7dbcea5493074cae498d58a5459539 (diff)
downloadbusybox-w32-c3cf1e30a3022453311a7e9fe11d94c7a381640e.tar.gz
busybox-w32-c3cf1e30a3022453311a7e9fe11d94c7a381640e.tar.bz2
busybox-w32-c3cf1e30a3022453311a7e9fe11d94c7a381640e.zip
mdev: use $DEVNAME in uevent sysfs file for device node name
516530c932bd17d87c9eb4347a490be051e495f4 uses $DEVNAME variable for device node name. This is fine, but only works for hotplugging, "mdev -s" will behave differently when DEVNAME and basename(path) differ. This patch extracts the DEVNAME from the uevent sysfs file in make_device(), thus works for hot- and coldplugging; so using the environment DEVNAME on hotplug events is no longer necessary. Signed-off-by: Nikolaus Voss <n.voss@weinmann.de> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--util-linux/mdev.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 1d741367e..e80b58f2e 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -295,8 +295,8 @@ struct globals {
295/* Prevent infinite loops in /sys symlinks */ 295/* Prevent infinite loops in /sys symlinks */
296#define MAX_SYSFS_DEPTH 3 296#define MAX_SYSFS_DEPTH 3
297 297
298/* We use additional 64+ bytes in make_device() */ 298/* We use additional bytes in make_device() */
299#define SCRATCH_SIZE 80 299#define SCRATCH_SIZE 128
300 300
301#if ENABLE_FEATURE_MDEV_CONF 301#if ENABLE_FEATURE_MDEV_CONF
302 302
@@ -541,7 +541,7 @@ static char *build_alias(char *alias, const char *device_name)
541 541
542/* mknod in /dev based on a path like "/sys/block/hda/hda1" 542/* mknod in /dev based on a path like "/sys/block/hda/hda1"
543 * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes 543 * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes
544 * after NUL, but we promise to not mangle (IOW: to restore if needed) 544 * after NUL, but we promise to not mangle (IOW: to restore NUL if needed)
545 * path string. 545 * path string.
546 * NB2: "mdev -s" may call us many times, do not leak memory/fds! 546 * NB2: "mdev -s" may call us many times, do not leak memory/fds!
547 * 547 *
@@ -551,6 +551,7 @@ static char *build_alias(char *alias, const char *device_name)
551static void make_device(char *device_name, char *path, int operation) 551static void make_device(char *device_name, char *path, int operation)
552{ 552{
553 int major, minor, type, len; 553 int major, minor, type, len;
554 char *path_end = path + strlen(path);
554 555
555 /* Try to read major/minor string. Note that the kernel puts \n after 556 /* Try to read major/minor string. Note that the kernel puts \n after
556 * the data, so we don't need to worry about null terminating the string 557 * the data, so we don't need to worry about null terminating the string
@@ -559,17 +560,15 @@ static void make_device(char *device_name, char *path, int operation)
559 */ 560 */
560 major = -1; 561 major = -1;
561 if (operation == OP_add) { 562 if (operation == OP_add) {
562 char *dev_maj_min = path + strlen(path); 563 strcpy(path_end, "/dev");
563 564 len = open_read_close(path, path_end + 1, SCRATCH_SIZE - 1);
564 strcpy(dev_maj_min, "/dev"); 565 *path_end = '\0';
565 len = open_read_close(path, dev_maj_min + 1, 64);
566 *dev_maj_min = '\0';
567 if (len < 1) { 566 if (len < 1) {
568 if (!ENABLE_FEATURE_MDEV_EXEC) 567 if (!ENABLE_FEATURE_MDEV_EXEC)
569 return; 568 return;
570 /* no "dev" file, but we can still run scripts 569 /* no "dev" file, but we can still run scripts
571 * based on device name */ 570 * based on device name */
572 } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) == 2) { 571 } else if (sscanf(path_end + 1, "%u:%u", &major, &minor) == 2) {
573 dbg1("dev %u,%u", major, minor); 572 dbg1("dev %u,%u", major, minor);
574 } else { 573 } else {
575 major = -1; 574 major = -1;
@@ -577,9 +576,33 @@ static void make_device(char *device_name, char *path, int operation)
577 } 576 }
578 /* else: for delete, -1 still deletes the node, but < -1 suppresses that */ 577 /* else: for delete, -1 still deletes the node, but < -1 suppresses that */
579 578
580 /* Determine device name, type, major and minor */ 579 /* Determine device name */
581 if (!device_name) 580 if (!device_name) {
582 device_name = (char*) bb_basename(path); 581 /*
582 * There was no $DEVNAME envvar (for example, mdev -s never has).
583 * But it is very useful: it contains the *path*, not only basename,
584 * Thankfully, uevent file has it.
585 * Example of .../sound/card0/controlC0/uevent file on Linux-3.7.7:
586 * MAJOR=116
587 * MINOR=7
588 * DEVNAME=snd/controlC0
589 */
590 strcpy(path_end, "/uevent");
591 len = open_read_close(path, path_end + 1, SCRATCH_SIZE - 1);
592 if (len < 0)
593 len = 0;
594 *path_end = '\0';
595 path_end[1 + len] = '\0';
596 device_name = strstr(path_end + 1, "\nDEVNAME=");
597 if (device_name) {
598 device_name += sizeof("\nDEVNAME=")-1;
599 strchrnul(device_name, '\n')[0] = '\0';
600 } else {
601 /* Fall back to just basename */
602 device_name = (char*) bb_basename(path);
603 }
604 }
605 /* Determine device type */
583 /* 606 /*
584 * http://kernel.org/doc/pending/hotplug.txt says that only 607 * http://kernel.org/doc/pending/hotplug.txt says that only
585 * "/sys/block/..." is for block devices. "/sys/bus" etc is not. 608 * "/sys/block/..." is for block devices. "/sys/bus" etc is not.