chiark / gitweb /
remove old symlinks before creating current ones
authorKay Sievers <kay.sievers@suse.de>
Wed, 12 Apr 2006 20:08:05 +0000 (22:08 +0200)
committerKay Sievers <kay.sievers@suse.de>
Wed, 12 Apr 2006 20:08:05 +0000 (22:08 +0200)
This will prevent incorrect symlinks when a filesystem
label is changed and the event is triggered again from
sysfs.

.gitignore
udev.h
udev_device.c
udev_node.c

index b9adf69fc6272f4d9a92dd208d2c1520f7ce33d3..499e9c4d9006adcd212a32b9ff741b7f36e82710 100644 (file)
@@ -5,6 +5,7 @@ udev
 udevd
 udevcontrol
 udevtrigger
+udevsettle
 udevsend
 udevinfo
 udevmonitor
diff --git a/udev.h b/udev.h
index 615253a52f08083f7f2d18e1b4a3fc3aa152ed1a..94d1676c90d4e1def5c17572f7ddae2ebf133f98 100644 (file)
--- a/udev.h
+++ b/udev.h
@@ -119,7 +119,8 @@ extern char *sysfs_attr_get_value(const char *devpath, const char *attr_name);
 
 /* udev_node.c */
 extern int udev_node_mknod(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid);
-extern int udev_node_add(struct udevice *udev);
+extern int udev_node_add(struct udevice *udev, struct udevice *udev_old);
+extern void udev_node_remove_symlinks(struct udevice *udev);
 extern int udev_node_remove(struct udevice *udev);
 
 /* udev_db.c */
index 84d0ab2204e262cd40f27119df3de82d5fe1109d..b356f163a5b6f43a259445486fb67d6a6dd5700a 100644 (file)
@@ -114,7 +114,10 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev)
 
        /* add device node */
        if (major(udev->devt) != 0 && strcmp(udev->action, "add") == 0) {
+               struct udevice *udev_old;
+
                dbg("device node add '%s'", udev->dev->devpath);
+
                udev_rules_get_name(rules, udev);
                if (udev->ignore_device) {
                        info("device event will be ignored");
@@ -124,8 +127,19 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev)
                        info("device node creation supressed");
                        goto exit;
                }
-               /* create node, store in db */
-               retval = udev_node_add(udev);
+
+               /* read current database entry, we may want to cleanup symlinks */
+               udev_old = udev_device_init();
+               if (udev_old != NULL) {
+                       if (udev_db_get_device(udev_old, udev->dev->devpath) == 0) {
+                               info("device '%s' already known, remove possible symlinks", udev->dev->devpath);
+                               udev_node_remove_symlinks(udev_old);
+                       }
+                       udev_device_cleanup(udev_old);
+               }
+
+               /* create node and symlinks, store record in database */
+               retval = udev_node_add(udev, udev_old);
                if (retval == 0)
                        udev_db_add_device(udev);
                goto exit;
index 9d6e89cfa12772c3dd24a8baadb188d7440a43bf..d2889a329e22201a55c6039b8ee0109bf47e6480 100644 (file)
@@ -90,7 +90,7 @@ exit:
        return retval;
 }
 
-int udev_node_add(struct udevice *udev)
+int udev_node_add(struct udevice *udev, struct udevice *udev_old)
 {
        char filename[PATH_SIZE];
        struct name_entry *name_loop;
@@ -226,15 +226,12 @@ exit:
        return retval;
 }
 
-int udev_node_remove(struct udevice *udev)
+void udev_node_remove_symlinks(struct udevice *udev)
 {
        char filename[PATH_SIZE];
-       char partitionname[PATH_SIZE];
        struct name_entry *name_loop;
        struct stat stats;
        int retval;
-       int i;
-       int num;
 
        if (!list_empty(&udev->symlink_list)) {
                char symlinks[512] = "";
@@ -266,6 +263,17 @@ int udev_node_remove(struct udevice *udev)
                if (symlinks[0] != '\0')
                        setenv("DEVLINKS", symlinks, 1);
        }
+}
+
+int udev_node_remove(struct udevice *udev)
+{
+       char filename[PATH_SIZE];
+       char partitionname[PATH_SIZE];
+       struct stat stats;
+       int retval;
+       int num;
+
+       udev_node_remove_symlinks(udev);
 
        snprintf(filename, sizeof(filename), "%s/%s", udev_root, udev->name);
        filename[sizeof(filename)-1] = '\0';
@@ -288,6 +296,8 @@ int udev_node_remove(struct udevice *udev)
 
        num = udev->partitions;
        if (num > 0) {
+               int i;
+
                info("removing all_partitions '%s[1-%i]'", filename, num);
                if (num > 255) {
                        info("garbage from udev database, skip all_partitions removal");