diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index 41a39b5cd62..b47ca37d55b 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -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) { diff --git a/src/udev/udev-builtin.h b/src/udev/udev-builtin.h index 8c2016e5f0c..3b5f3bd120b 100644 --- a/src/udev/udev-builtin.h +++ b/src/udev/udev-builtin.h @@ -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); diff --git a/src/udev/udev-def.h b/src/udev/udev-def.h index 6ff3feacec1..9d9fc78247d 100644 --- a/src/udev/udev-def.h +++ b/src/udev/udev-def.h @@ -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; diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index 7f7079bcd2c..c691b8ebed6 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -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");