mirror of
https://github.com/systemd/systemd.git
synced 2025-01-05 13:18:06 +03:00
udev: support reloading udev.conf (#35458)
This makes systemd-udevd reload udev.conf when explicitly requested by e.g. `udevadm control --reload`.
This commit is contained in:
commit
3b9010b170
@ -42,11 +42,28 @@ void udev_builtin_exit(void) {
|
|||||||
(*b)->exit();
|
(*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++)
|
for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++)
|
||||||
if (builtins[i] && builtins[i]->should_reload && builtins[i]->should_reload())
|
if (builtins[i] && builtins[i]->should_reload && builtins[i]->should_reload())
|
||||||
return true;
|
flags |= 1u << i;
|
||||||
return false;
|
|
||||||
|
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) {
|
void udev_builtin_list(void) {
|
||||||
|
@ -59,7 +59,8 @@ const char* udev_builtin_name(UdevBuiltinCommand cmd);
|
|||||||
bool udev_builtin_run_once(UdevBuiltinCommand cmd);
|
bool udev_builtin_run_once(UdevBuiltinCommand cmd);
|
||||||
int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command);
|
int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command);
|
||||||
void udev_builtin_list(void);
|
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_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_add_propertyf(UdevEvent *event, const char *key, const char *valf, ...) _printf_(3, 4);
|
||||||
int udev_builtin_import_property(UdevEvent *event, const char *key);
|
int udev_builtin_import_property(UdevEvent *event, const char *key);
|
||||||
|
@ -339,3 +339,27 @@ int manager_load(Manager *manager, int argc, char *argv[]) {
|
|||||||
manager_adjust_config(&manager->config);
|
manager_adjust_config(&manager->config);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UdevReloadFlags manager_reload_config(Manager *manager) {
|
||||||
|
assert(manager);
|
||||||
|
|
||||||
|
UdevConfig old = manager->config;
|
||||||
|
|
||||||
|
manager->config_by_udev_conf = UDEV_CONFIG_INIT;
|
||||||
|
manager_parse_udev_config(&manager->config_by_udev_conf);
|
||||||
|
manager_merge_config(manager);
|
||||||
|
log_set_max_level(manager->config.log_level);
|
||||||
|
manager_adjust_config(&manager->config);
|
||||||
|
|
||||||
|
if (manager->config.resolve_name_timing != old.resolve_name_timing)
|
||||||
|
return UDEV_RELOAD_RULES | UDEV_RELOAD_KILL_WORKERS;
|
||||||
|
|
||||||
|
if (manager->config.log_level != old.log_level ||
|
||||||
|
manager->config.exec_delay_usec != old.exec_delay_usec ||
|
||||||
|
manager->config.timeout_usec != old.timeout_usec ||
|
||||||
|
manager->config.timeout_signal != old.timeout_signal ||
|
||||||
|
manager->config.blockdev_read_only != old.blockdev_read_only)
|
||||||
|
return UDEV_RELOAD_KILL_WORKERS;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -27,4 +27,5 @@ typedef struct UdevConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int manager_load(Manager *manager, int argc, char *argv[]);
|
int manager_load(Manager *manager, int argc, char *argv[]);
|
||||||
|
UdevReloadFlags manager_reload_config(Manager *manager);
|
||||||
void udev_config_set_default_children_max(UdevConfig *c);
|
void udev_config_set_default_children_max(UdevConfig *c);
|
||||||
|
@ -55,3 +55,26 @@ typedef enum UdevBuiltinCommand {
|
|||||||
_UDEV_BUILTIN_MAX,
|
_UDEV_BUILTIN_MAX,
|
||||||
_UDEV_BUILTIN_INVALID = -EINVAL,
|
_UDEV_BUILTIN_INVALID = -EINVAL,
|
||||||
} UdevBuiltinCommand;
|
} 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;
|
||||||
|
@ -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. */
|
/* Reload SELinux label database, to make the child inherit the up-to-date database. */
|
||||||
mac_selinux_maybe_reload();
|
mac_selinux_maybe_reload();
|
||||||
|
|
||||||
/* Nothing changed. It is not necessary to reload. */
|
UdevReloadFlags flags = udev_builtin_should_reload();
|
||||||
if (!udev_rules_should_reload(manager->rules) && !udev_builtin_should_reload()) {
|
if (udev_rules_should_reload(manager->rules))
|
||||||
|
flags |= UDEV_RELOAD_RULES | UDEV_RELOAD_KILL_WORKERS;
|
||||||
if (!force)
|
if (flags == 0 && !force)
|
||||||
|
/* Neither .rules files nor config files for builtins e.g. .link files changed. It is not
|
||||||
|
* necessary to reload configs. Note, udev.conf is not checked in the above, hence reloaded
|
||||||
|
* when explicitly requested or at least one .rules file or friend is updated. */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If we eat this up, then tell our service manager to just continue */
|
|
||||||
(void) notify_reloading_full("Skipping configuration reloading, nothing changed.");
|
|
||||||
} else {
|
|
||||||
(void) notify_reloading();
|
(void) notify_reloading();
|
||||||
|
|
||||||
|
flags |= manager_reload_config(manager);
|
||||||
|
|
||||||
|
if (FLAGS_SET(flags, UDEV_RELOAD_KILL_WORKERS))
|
||||||
manager_kill_workers(manager, false);
|
manager_kill_workers(manager, false);
|
||||||
|
|
||||||
udev_builtin_exit();
|
udev_builtin_reload(flags);
|
||||||
udev_builtin_init();
|
|
||||||
|
|
||||||
|
if (FLAGS_SET(flags, UDEV_RELOAD_RULES)) {
|
||||||
r = udev_rules_load(&rules, manager->config.resolve_name_timing);
|
r = udev_rules_load(&rules, manager->config.resolve_name_timing);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m");
|
log_warning_errno(r, "Failed to read udev rules, using the previously loaded rules, ignoring: %m");
|
||||||
|
@ -27,7 +27,7 @@ event_timeout=10
|
|||||||
timeout_signal=SIGABRT
|
timeout_signal=SIGABRT
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl restart systemd-udevd.service
|
systemctl reload systemd-udevd.service
|
||||||
}
|
}
|
||||||
|
|
||||||
# shellcheck disable=SC2317
|
# shellcheck disable=SC2317
|
||||||
@ -40,7 +40,7 @@ teardown() {
|
|||||||
|
|
||||||
rm -rf "$TMPDIR"
|
rm -rf "$TMPDIR"
|
||||||
rm -f "$TEST_RULE" "$TEST_CONF"
|
rm -f "$TEST_RULE" "$TEST_CONF"
|
||||||
systemctl restart systemd-udevd.service
|
systemctl reload systemd-udevd.service
|
||||||
}
|
}
|
||||||
|
|
||||||
run_test_timeout() {
|
run_test_timeout() {
|
||||||
|
@ -18,7 +18,7 @@ at_exit() {
|
|||||||
# Forcibly kills sleep command invoked by the udev rule before restarting,
|
# Forcibly kills sleep command invoked by the udev rule before restarting,
|
||||||
# otherwise systemctl restart below will takes longer.
|
# otherwise systemctl restart below will takes longer.
|
||||||
killall -KILL sleep
|
killall -KILL sleep
|
||||||
systemctl restart systemd-udevd.service
|
udevadm control --reload
|
||||||
ip link del "$IFNAME"
|
ip link del "$IFNAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ cat >/run/udev/rules.d/99-testsuite.rules <<EOF
|
|||||||
SUBSYSTEM=="net", ACTION=="change", KERNEL=="${IFNAME}", OPTIONS="log_level=debug", RUN+="/usr/bin/sleep 1000"
|
SUBSYSTEM=="net", ACTION=="change", KERNEL=="${IFNAME}", OPTIONS="log_level=debug", RUN+="/usr/bin/sleep 1000"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl restart systemd-udevd.service
|
udevadm control --reload
|
||||||
|
|
||||||
ip link add "$IFNAME" type dummy
|
ip link add "$IFNAME" type dummy
|
||||||
IFINDEX=$(ip -json link show "$IFNAME" | jq '.[].ifindex')
|
IFINDEX=$(ip -json link show "$IFNAME" | jq '.[].ifindex')
|
||||||
|
Loading…
Reference in New Issue
Block a user