From 79449642ebcb6170adb8d6391518e328a07d9552 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 11 Aug 2011 20:33:17 +0200 Subject: [PATCH] do not remove static nodes on module unload --- udev/udev-event.c | 4 ++++ udev/udev-node.c | 5 +++++ udev/udev-rules.c | 14 ++++++++++---- udev/udev.h | 1 + udev/udevd.c | 5 +++-- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/udev/udev-event.c b/udev/udev-event.c index 823768a3..391fce81 100644 --- a/udev/udev-event.c +++ b/udev/udev-event.c @@ -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); } diff --git a/udev/udev-node.c b/udev/udev-node.c index dc7d9c36..6fbe250b 100644 --- a/udev/udev-node.c +++ b/udev/udev-node.c @@ -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 */ diff --git a/udev/udev-rules.c b/udev/udev-rules.c index 742d88b3..6bf2726e 100644 --- a/udev/udev-rules.c +++ b/udev/udev-rules.c @@ -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); } diff --git a/udev/udev.h b/udev/udev.h index 1f9650fc..5aaf117a 100644 --- a/udev/udev.h +++ b/udev/udev.h @@ -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; diff --git a/udev/udevd.c b/udev/udevd.c index 1220deaa..f1a31e7a 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -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; -- 2.39.5