mdev: fix the case when move rule deletes node with name == device_name
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 21 Jun 2009 23:31:12 +0000 (01:31 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 21 Jun 2009 23:31:12 +0000 (01:31 +0200)
Signed-off-by: Jean Wolter <jw5@os.inf.tu-dresden.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
testsuite/mdev.tests
util-linux/mdev.c

index a175007..912785e 100755 (executable)
@@ -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
 
index 7508930..c68c0a5 100644 (file)
@@ -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.