udev-varlink: introduce io.systemd.Udev.Revert method

It reverts dynamically set configurations.
This commit is contained in:
Yu Watanabe
2025-04-08 04:58:01 +09:00
parent 0a893ef3f3
commit 1043ae3bc2
6 changed files with 68 additions and 10 deletions

View File

@@ -17,6 +17,8 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_FIELD_COMMENT("An array of global udev property assignments. Each string must be in KEY=VALUE style."),
SD_VARLINK_DEFINE_INPUT(assignments, SD_VARLINK_STRING, SD_VARLINK_ARRAY));
static SD_VARLINK_DEFINE_METHOD(Revert);
static SD_VARLINK_DEFINE_METHOD(StartExecQueue);
static SD_VARLINK_DEFINE_METHOD(StopExecQueue);
@@ -34,6 +36,8 @@ SD_VARLINK_DEFINE_INTERFACE(
SD_VARLINK_SYMBOL_COMMENT("Sets the global udev properties."),
&vl_method_SetEnvironment,
SD_VARLINK_SYMBOL_COMMENT("Starts processing of queued events."),
&vl_method_Revert,
SD_VARLINK_SYMBOL_COMMENT("Revert previously set configurations."),
&vl_method_StartExecQueue,
SD_VARLINK_SYMBOL_COMMENT("Stops processing of queued events."),
&vl_method_StopExecQueue,

View File

@@ -463,6 +463,24 @@ int manager_load(Manager *manager, int argc, char *argv[]) {
return 1;
}
static UdevReloadFlags manager_needs_reload(Manager *manager, const UdevConfig *old) {
assert(manager);
assert(old);
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 ||
manager->config.trace != old->trace)
return UDEV_RELOAD_KILL_WORKERS;
return 0;
}
UdevReloadFlags manager_reload_config(Manager *manager) {
assert(manager);
@@ -473,18 +491,25 @@ UdevReloadFlags manager_reload_config(Manager *manager) {
manager_merge_config(manager);
manager_adjust_config(&manager->config);
if (manager->config.resolve_name_timing != old.resolve_name_timing)
return UDEV_RELOAD_RULES | UDEV_RELOAD_KILL_WORKERS;
return manager_needs_reload(manager, &old);
}
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 ||
manager->config.trace != old.trace)
return UDEV_RELOAD_KILL_WORKERS;
UdevReloadFlags manager_revert_config(Manager *manager) {
assert(manager);
return 0;
UdevReloadFlags flags = 0;
if (!hashmap_isempty(manager->properties)) {
flags |= UDEV_RELOAD_KILL_WORKERS;
manager->properties = hashmap_free(manager->properties);
}
UdevConfig old = manager->config;
manager->config_by_control = UDEV_CONFIG_INIT;
manager_merge_config(manager);
manager_adjust_config(&manager->config);
return flags | manager_needs_reload(manager, &old);
}
static usec_t extra_timeout_usec(void) {

View File

@@ -34,5 +34,6 @@ void manager_set_environment(Manager *manager, char * const *v);
int manager_load(Manager *manager, int argc, char *argv[]);
UdevReloadFlags manager_reload_config(Manager *manager);
UdevReloadFlags manager_revert_config(Manager *manager);
usec_t manager_kill_worker_timeout(Manager *manager);

View File

@@ -311,6 +311,17 @@ void manager_reload(Manager *manager, bool force) {
notify_ready(manager);
}
void manager_revert(Manager *manager) {
assert(manager);
UdevReloadFlags flags = manager_revert_config(manager);
if (flags == 0)
return;
assert(flags == UDEV_RELOAD_KILL_WORKERS);
manager_kill_workers(manager, SIGTERM);
}
static int on_sigchld(sd_event_source *s, const siginfo_t *si, void *userdata) {
_cleanup_(worker_freep) Worker *worker = ASSERT_PTR(userdata);
sd_device *dev = worker->event ? ASSERT_PTR(worker->event->dev) : NULL;

View File

@@ -70,6 +70,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
int manager_main(Manager *manager);
void manager_reload(Manager *manager, bool force);
void manager_revert(Manager *manager);
void manager_exit(Manager *manager);
void notify_ready(Manager *manager);

View File

@@ -103,6 +103,21 @@ static int vl_method_set_environment(sd_varlink *link, sd_json_variant *paramete
return sd_varlink_reply(link, NULL);
}
static int vl_method_revert(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
Manager *manager = ASSERT_PTR(userdata);
int r;
assert(link);
r = sd_varlink_dispatch(link, parameters, /* dispatch_table = */ NULL, /* userdata = */ NULL);
if (r != 0)
return r;
log_debug("Received io.systemd.Udev.Revert()");
manager_revert(manager);
return sd_varlink_reply(link, NULL);
}
static int vl_method_start_stop_exec_queue(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
Manager *manager = ASSERT_PTR(userdata);
const char *method;
@@ -183,6 +198,7 @@ int manager_start_varlink_server(Manager *manager) {
"io.systemd.Udev.SetTrace", vl_method_set_trace,
"io.systemd.Udev.SetChildrenMax", vl_method_set_children_max,
"io.systemd.Udev.SetEnvironment", vl_method_set_environment,
"io.systemd.Udev.Revert", vl_method_revert,
"io.systemd.Udev.StartExecQueue", vl_method_start_stop_exec_queue,
"io.systemd.Udev.StopExecQueue", vl_method_start_stop_exec_queue,
"io.systemd.Udev.Exit", vl_method_exit);