chiark / gitweb /
do not remove static nodes on module unload
authorKay Sievers <kay.sievers@vrfy.org>
Thu, 11 Aug 2011 18:33:17 +0000 (20:33 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Thu, 11 Aug 2011 18:37:49 +0000 (20:37 +0200)
udev/udev-event.c
udev/udev-node.c
udev/udev-rules.c
udev/udev.h
udev/udevd.c

index 823768a..391fce8 100644 (file)
@@ -1030,6 +1030,10 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                                }
                        }
 
+                       /* set sticky bit, so we do not remove the node on module unload */
+                       if (event->static_node)
+                               event->mode |= 01000;
+
                        err = udev_node_add(dev, event->mode, event->uid, event->gid);
                }
 
index dc7d9c3..6fbe250 100644 (file)
@@ -425,6 +425,11 @@ int udev_node_remove(struct udev_device *dev)
                goto out;
        }
 
+       if (stats.st_mode & 01000) {
+               info(udev, "device node '%s' has sticky bit set, skip removal\n", devnode);
+               goto out;
+       }
+
        dev_check = udev_device_new_from_syspath(udev, udev_device_get_syspath(dev));
        if (dev_check != NULL) {
                /* do not remove device node if the same sys-device is re-created in the meantime */
index 742d88b..6bf2726 100644 (file)
@@ -2572,6 +2572,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                             rule->rule.filename_line);
                        break;
                case TK_A_STATIC_NODE:
+                       event->static_node = true;
                        break;
                case TK_A_ENV: {
                        const char *name = &rules->buf[cur->key.attr_off];
@@ -2793,10 +2794,15 @@ void udev_rules_apply_static_dev_perms(struct udev_rules *rules)
                                goto next;
                        if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode))
                                goto next;
-
-                       if (mode == 0 && gid > 0)
-                               mode = 0660;
-                       if (mode != (stats.st_mode & 0777)) {
+                       if (mode == 0) {
+                               if (gid > 0)
+                                       mode = 0660;
+                               else
+                                       mode = 0600;
+                       }
+                       /* set sticky bit, so we do not remove the node on module unload */
+                       mode |= 01000;
+                       if (mode != (stats.st_mode & 01777)) {
                                chmod(filename, mode);
                                info(rules->udev, "chmod '%s' %#o\n", filename, mode);
                        }
index 1f9650f..5aaf117 100644 (file)
@@ -53,6 +53,7 @@ struct udev_event {
        bool owner_final;
        bool mode_set;
        bool mode_final;
+       bool static_node;
        bool name_final;
        bool devlink_final;
        bool run_final;
index 1220dea..f1a31e7 100644 (file)
@@ -889,10 +889,11 @@ static void static_dev_create_from_modules(struct udev *udev)
                if (sscanf(devno, "%c%u:%u", &type, &maj, &min) != 3)
                        continue;
 
+               /* set sticky bit, so we do not remove the node on module unload */
                if (type == 'c')
-                       mode = 0600 | S_IFCHR;
+                       mode = 01600|S_IFCHR;
                else if (type == 'b')
-                       mode = 0600 | S_IFBLK;
+                       mode = 01600|S_IFBLK;
                else
                        continue;