From f257a8fc13b2a617d845132eb61aefde47921198 Mon Sep 17 00:00:00 2001 From: gaoyi Date: Fri, 19 Mar 2021 15:16:56 +0800 Subject: [PATCH] udevd: don't kill worker in manager_kill_workers when it's running If worker is running, kill worker may lead uevent unprocessed. Reference: https://github.com/systemd/systemd/commit/f257a8fc13b2a617d845132eb61aefde47921198 Conflict: adaptation context. --- src/udev/udevd.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 7465a70..8e50cb5 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -136,6 +136,7 @@ enum worker_state { WORKER_RUNNING, WORKER_IDLE, WORKER_KILLED, + WORKER_KILLING, }; struct worker { @@ -691,7 +692,7 @@ static int event_queue_insert(Manager *manager, sd_device *dev) { return 0; } -static void manager_kill_workers(Manager *manager) { +static void manager_kill_workers(Manager *manager, bool force) { struct worker *worker; Iterator i; @@ -701,6 +702,11 @@ static void manager_kill_workers(Manager *manager) { if (worker->state == WORKER_KILLED) continue; + if (worker->state == WORKER_RUNNING && !force) { + worker->state = WORKER_KILLING; + continue; + } + worker->state = WORKER_KILLED; (void) kill(worker->pid, SIGTERM); } @@ -836,7 +842,7 @@ static void manager_exit(Manager *manager) { /* discard queued events and kill workers */ event_queue_cleanup(manager, EVENT_QUEUED); - manager_kill_workers(manager); + manager_kill_workers(manager, true); } /* reload requested, HUP signal received, rules changed, builtin changed */ @@ -848,7 +854,7 @@ static void manager_reload(Manager *manager) { "RELOADING=1\n" "STATUS=Flushing configuration..."); - manager_kill_workers(manager); + manager_kill_workers(manager, false); manager->rules = udev_rules_free(manager->rules); udev_builtin_exit(); @@ -863,7 +869,7 @@ static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userda assert(manager); log_debug("Cleanup idle workers"); - manager_kill_workers(manager); + manager_kill_workers(manager, false); return 1; } @@ -985,7 +991,10 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat continue; } - if (worker->state != WORKER_KILLED) + if (worker->state == WORKER_KILLING) { + worker->state = WORKER_KILLED; + (void) kill(worker->pid, SIGTERM); + } else if (worker->state != WORKER_KILLED) worker->state = WORKER_IDLE; /* worker returned */ @@ -1031,7 +1040,7 @@ static int on_ctrl_msg(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, co log_debug("Received udev control message (SET_LOG_LEVEL), setting log_priority=%i", value->intval); log_set_max_level_realm(LOG_REALM_UDEV, value->intval); log_set_max_level_realm(LOG_REALM_SYSTEMD, value->intval); - manager_kill_workers(manager); + manager_kill_workers(manager, false); break; case UDEV_CTRL_STOP_EXEC_QUEUE: log_debug("Received udev control message (STOP_EXEC_QUEUE)"); @@ -1096,7 +1105,7 @@ static int on_ctrl_msg(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, co } key = val = NULL; - manager_kill_workers(manager); + manager_kill_workers(manager, false); break; } case UDEV_CTRL_SET_CHILDREN_MAX: -- 2.23.0