diff --git a/src/udev/udev-manager-ctrl.c b/src/udev/udev-manager-ctrl.c index 397ed03410..d9cc44bc5c 100644 --- a/src/udev/udev-manager-ctrl.c +++ b/src/udev/udev-manager-ctrl.c @@ -29,6 +29,7 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl case UDEV_CTRL_STOP_EXEC_QUEUE: log_debug("Received udev control message (STOP_EXEC_QUEUE)"); manager->stop_exec_queue = true; + (void) manager_reset_kill_workers_timer(manager); break; case UDEV_CTRL_START_EXEC_QUEUE: log_debug("Received udev control message (START_EXEC_QUEUE)"); diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index dc684d4b95..2ad47258f7 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -201,7 +201,7 @@ static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userda return 0; } -static int manager_reset_kill_workers_timer(Manager *manager) { +int manager_reset_kill_workers_timer(Manager *manager) { int r; assert(manager); diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h index 4f6d116857..4a2225d1c2 100644 --- a/src/udev/udev-manager.h +++ b/src/udev/udev-manager.h @@ -93,6 +93,7 @@ void manager_exit(Manager *manager); void notify_ready(Manager *manager); void manager_kill_workers(Manager *manager, int signo); +int manager_reset_kill_workers_timer(Manager *manager); bool devpath_conflict(const char *a, const char *b); diff --git a/src/udev/udev-varlink.c b/src/udev/udev-varlink.c index d087a33b5d..5c0a97be3d 100644 --- a/src/udev/udev-varlink.c +++ b/src/udev/udev-varlink.c @@ -136,6 +136,14 @@ static int vl_method_start_stop_exec_queue(sd_varlink *link, sd_json_variant *pa log_debug("Received %s()", method); manager->stop_exec_queue = streq(method, "io.systemd.Udev.StopExecQueue"); + + /* In case that processing queued events will be stopped for a while, regardless if there exist + * queued events, enable the kill workers timer here unless it is already enabled. Note, it is not + * necessary to disable the timer when processing is restarted, as it will be anyway disabled in + * on_post() -> event_queue_start(). */ + if (manager->stop_exec_queue) + (void) manager_reset_kill_workers_timer(manager); + return sd_varlink_reply(link, NULL); } diff --git a/test/units/TEST-17-UDEV.sanity-check.sh b/test/units/TEST-17-UDEV.sanity-check.sh index 125a5946f7..a655a4d775 100755 --- a/test/units/TEST-17-UDEV.sanity-check.sh +++ b/test/units/TEST-17-UDEV.sanity-check.sh @@ -9,7 +9,7 @@ set -o pipefail # Coverage test for udevadm # shellcheck disable=SC2317 -cleanup_17_10() { +cleanup() { set +e losetup -d "$loopdev" @@ -19,9 +19,9 @@ cleanup_17_10() { } # Set up some test devices -trap cleanup_17_10 EXIT +trap cleanup EXIT -netdev=dummy17.10 +netdev=hoge ip link add $netdev type dummy blk="$(mktemp)" @@ -55,8 +55,18 @@ udevadm control -l notice udevadm control --log-level info udevadm control --log-level debug (! udevadm control -l hello) -udevadm control -s -udevadm control -S + +# Check if processing queued events has been stopped. +udevadm control --stop-exec-queue +ip link add foobar type dummy +(! udevadm info --wait-for-initialization=3 /sys/class/net/foobar) +(! udevadm settle --timeout=0) +# Check if processing queued events has been restarted. +udevadm control --start-exec-queue +udevadm settle --timeout=30 +udevadm info --wait-for-initialization=0 /sys/class/net/foobar +ip link del foobar + udevadm control -R udevadm control -p HELLO=world udevadm control -m 42