From 2f86ca135069e457bb16ab9e062a10e0775717a6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 22 Jun 2009 01:31:12 +0200 Subject: mdev: fix the case when move rule deletes node with name == device_name Signed-off-by: Jean Wolter Signed-off-by: Denys Vlasenko --- testsuite/mdev.tests | 26 ++++++++++++++++++++++++++ util-linux/mdev.c | 36 +++++++++++++++++------------------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/testsuite/mdev.tests b/testsuite/mdev.tests index a1750076e..912785ece 100755 --- a/testsuite/mdev.tests +++ b/testsuite/mdev.tests @@ -162,6 +162,32 @@ brw-r--r-- 1 0 1 8,0 sda " \ "" "" +# continuing to use directory structure from prev test +rm -rf mdev.testdir/dev/* +mkdir -p mdev.testdir/sys/class/tty/capi +echo "191:0" >mdev.testdir/sys/class/tty/capi/dev +mkdir -p mdev.testdir/sys/class/tty/capi1 +echo "191:1" >mdev.testdir/sys/class/tty/capi1/dev +mkdir -p mdev.testdir/sys/class/tty/capi20 +echo "191:20" >mdev.testdir/sys/class/tty/capi20/dev +echo "capi 0:0 0660 =capi20" >mdev.testdir/etc/mdev.conf +echo "capi([0-9]) 0:0 0660 =capi20.0%1" >>mdev.testdir/etc/mdev.conf +echo "capi([0-9]*) 0:0 0660 =capi20.%1" >>mdev.testdir/etc/mdev.conf +# mdev invocation with DEVPATH=/class/tty/capi20 was deleting /dev/capi20 +testing "move rule does not delete node with name == device_name" \ + "\ + env - PATH=$PATH ACTION=add DEVPATH=/class/tty/capi chroot mdev.testdir /mdev 2>&1; + env - PATH=$PATH ACTION=add DEVPATH=/class/tty/capi1 chroot mdev.testdir /mdev 2>&1; + env - PATH=$PATH ACTION=add DEVPATH=/class/tty/capi20 chroot mdev.testdir /mdev 2>&1; + ls -lnR mdev.testdir/dev | $FILTER_LS" \ +"\ +mdev.testdir/dev: +crw-rw---- 1 0 0 191,0 capi20 +crw-rw---- 1 0 0 191,1 capi20.01 +crw-rw---- 1 0 0 191,20 capi20.20 +" \ + "" "" + # clean up rm -rf mdev.testdir diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 7508930f7..c68c0a5e7 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -319,22 +319,20 @@ static void make_device(char *path, int delete) /* "Execute" the line we found */ if (!delete && major >= 0) { - if (ENABLE_FEATURE_MDEV_RENAME) - unlink(device_name); - if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) - bb_perror_msg_and_die("mknod %s", device_name); + char *node_name = (char *)device_name; + if (ENABLE_FEATURE_MDEV_RENAME && alias) + alias = node_name = build_alias(alias, device_name); + if (mknod(node_name, mode | type, makedev(major, minor)) && errno != EEXIST) + bb_perror_msg_and_die("mknod %s", node_name); if (major == root_major && minor == root_minor) - symlink(device_name, "root"); + symlink(node_name, "root"); if (ENABLE_FEATURE_MDEV_CONF) { - chmod(device_name, mode); - chown(device_name, ugid.uid, ugid.gid); + chmod(node_name, mode); + chown(node_name, ugid.uid, ugid.gid); } if (ENABLE_FEATURE_MDEV_RENAME && alias) { - alias = build_alias(alias, device_name); - /* move the device, and optionally - * make a symlink to moved device node */ - if (rename(device_name, alias) == 0 && aliaslink == '>') - symlink(alias, device_name); + if (aliaslink == '>') + symlink(node_name, device_name); free(alias); } } @@ -355,15 +353,15 @@ static void make_device(char *path, int delete) } if (delete) { - unlink(device_name); - /* At creation time, device might have been moved - * and a symlink might have been created. Undo that. */ - + char *node_name = (char *)device_name; if (ENABLE_FEATURE_MDEV_RENAME && alias) { - alias = build_alias(alias, device_name); - unlink(alias); - free(alias); + alias = node_name = build_alias(alias, device_name); + if (aliaslink == '>') + unlink(device_name); } + unlink(node_name); + if (ENABLE_FEATURE_MDEV_RENAME) + free(alias); } /* We found matching line. -- cgit v1.2.3