]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: reload .rules files and builtins only when necessary
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 3 Dec 2024 19:31:31 +0000 (04:31 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 19 Dec 2024 09:55:18 +0000 (18:55 +0900)
Previously, even if e.g. .rules files are unchanged, all .rules files
are reloaded when other kind of config files like .link files or
.hwdb.bin are changed, vice versa.

src/udev/udev-builtin.c
src/udev/udev-builtin.h
src/udev/udev-def.h
src/udev/udev-manager.c

index 41a39b5cd622ee192b2746776b0aa97aca2b3d39..b47ca37d55bb78b97d7deaeb65c3315aa1b2d75d 100644 (file)
@@ -42,11 +42,28 @@ void udev_builtin_exit(void) {
                         (*b)->exit();
 }
 
-bool udev_builtin_should_reload(void) {
+UdevReloadFlags udev_builtin_should_reload(void) {
+        UdevReloadFlags flags = 0;
+
         for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++)
                 if (builtins[i] && builtins[i]->should_reload && builtins[i]->should_reload())
-                        return true;
-        return false;
+                        flags |= 1u << i;
+
+        if (flags != 0)
+                flags |= UDEV_RELOAD_KILL_WORKERS;
+
+        return flags;
+}
+
+void udev_builtin_reload(UdevReloadFlags flags) {
+        for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++) {
+                if (!FLAGS_SET(flags, 1u << i) || !builtins[i])
+                        continue;
+                if (builtins[i]->exit)
+                        builtins[i]->exit();
+                if (builtins[i]->init)
+                        builtins[i]->init();
+        }
 }
 
 void udev_builtin_list(void) {
index 8c2016e5f0c47a4e1c80cb58da9cef925427018b..3b5f3bd120be619ef583f7838faea42555c0a044 100644 (file)
@@ -59,7 +59,8 @@ const char* udev_builtin_name(UdevBuiltinCommand cmd);
 bool udev_builtin_run_once(UdevBuiltinCommand cmd);
 int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command);
 void udev_builtin_list(void);
-bool udev_builtin_should_reload(void);
+UdevReloadFlags udev_builtin_should_reload(void);
+void udev_builtin_reload(UdevReloadFlags flags);
 int udev_builtin_add_property(UdevEvent *event, const char *key, const char *val);
 int udev_builtin_add_propertyf(UdevEvent *event, const char *key, const char *valf, ...) _printf_(3, 4);
 int udev_builtin_import_property(UdevEvent *event, const char *key);
index 6ff3feacec155ae2949742fe9b7501e4fc773a1f..9d9fc78247dc48706d15aebd1435088fbbdb5d8f 100644 (file)
@@ -55,3 +55,26 @@ typedef enum UdevBuiltinCommand {
         _UDEV_BUILTIN_MAX,
         _UDEV_BUILTIN_INVALID = -EINVAL,
 } UdevBuiltinCommand;
+
+typedef enum UdevReloadFlags {
+#if HAVE_BLKID
+        UDEV_RELOAD_BUILTIN_BLKID    = 1u << UDEV_BUILTIN_BLKID,
+#endif
+        UDEV_RELOAD_BUILTIN_BTRFS    = 1u << UDEV_BUILTIN_BTRFS,
+        UDEV_RELOAD_BUILTIN_HWDB     = 1u << UDEV_BUILTIN_HWDB,
+        UDEV_RELOAD_BUILTIN_INPUT_ID = 1u << UDEV_BUILTIN_INPUT_ID,
+        UDEV_RELOAD_BUILTIN_KEYBOARD = 1u << UDEV_BUILTIN_KEYBOARD,
+#if HAVE_KMOD
+        UDEV_RELOAD_BUILTIN_KMOD     = 1u << UDEV_BUILTIN_KMOD,
+#endif
+        UDEV_RELOAD_BUILTIN_DRIVER   = 1u << UDEV_BUILTIN_NET_DRIVER,
+        UDEV_RELOAD_BUILTIN_NET_ID   = 1u << UDEV_BUILTIN_NET_ID,
+        UDEV_RELOAD_BUILTIN_NET_LINK = 1u << UDEV_BUILTIN_NET_LINK,
+        UDEV_RELOAD_BUILTIN_PATH_ID  = 1u << UDEV_BUILTIN_PATH_ID,
+        UDEV_RELOAD_BUILTIN_USB_ID   = 1u << UDEV_BUILTIN_USB_ID,
+#if HAVE_ACL
+        UDEV_RELOAD_BUILTIN_UACCESS  = 1u << UDEV_BUILTIN_UACCESS,
+#endif
+        UDEV_RELOAD_KILL_WORKERS     = 1u << (_UDEV_BUILTIN_MAX + 0),
+        UDEV_RELOAD_RULES            = 1u << (_UDEV_BUILTIN_MAX + 1),
+} UdevReloadFlags;
index 7f7079bcd2c870bb0a03fa3abcc7b298ab9bb4b0..c691b8ebed690ba4fddeeebb02bdfc3f96fafcdb 100644 (file)
@@ -262,22 +262,25 @@ static void manager_reload(Manager *manager, bool force) {
         /* Reload SELinux label database, to make the child inherit the up-to-date database. */
         mac_selinux_maybe_reload();
 
-        /* Nothing changed. It is not necessary to reload. */
-        if (!udev_rules_should_reload(manager->rules) && !udev_builtin_should_reload()) {
-
+        UdevReloadFlags flags = udev_builtin_should_reload();
+        if (udev_rules_should_reload(manager->rules))
+                flags |= UDEV_RELOAD_RULES | UDEV_RELOAD_KILL_WORKERS;
+        if (flags == 0) {
+                /* Nothing changed. It is not necessary to reload. */
                 if (!force)
                         return;
 
                 /* If we eat this up, then tell our service manager to just continue */
                 (void) notify_reloading_full("Skipping configuration reloading, nothing changed.");
-        } else {
+        } else
                 (void) notify_reloading();
 
+        if (FLAGS_SET(flags, UDEV_RELOAD_KILL_WORKERS))
                 manager_kill_workers(manager, false);
 
-                udev_builtin_exit();
-                udev_builtin_init();
+        udev_builtin_reload(flags);
 
+        if (FLAGS_SET(flags, UDEV_RELOAD_RULES)) {
                 r = udev_rules_load(&rules, manager->config.resolve_name_timing);
                 if (r < 0)
                         log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m");