summaryrefslogtreecommitdiffstats
path: root/src/udev/udev-manager.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-01-02 20:23:22 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-01-02 20:23:22 +0100
commitb16c6076cb334c9da9602d4bafbf60381d6d630e (patch)
tree0aee1de1ed2feb832b7e1d9e6534b1fbf1d6ba54 /src/udev/udev-manager.c
parentudev-spawn: skip executing RUN= if exec_delay= is too long (diff)
downloadsystemd-b16c6076cb334c9da9602d4bafbf60381d6d630e.tar.xz
systemd-b16c6076cb334c9da9602d4bafbf60381d6d630e.zip
udev: wait for an extra time before the manager kills workers
Otherwise, udev workers cannot detect slow programs invoked by IMPORT{program}=, PROGRAM=, or RUN=, and whole worker process may be killed. Fixes #30436. Co-authored-by: sushmbha <sushmita.bhattacharya@oracle.com>
Diffstat (limited to 'src/udev/udev-manager.c')
-rw-r--r--src/udev/udev-manager.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 1cf215ed46..5bf00bb262 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -332,6 +332,28 @@ static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *use
return 1;
}
+static usec_t extra_timeout_usec(void) {
+ static usec_t saved = 10 * USEC_PER_SEC;
+ static bool parsed = false;
+ const char *e;
+ int r;
+
+ if (parsed)
+ return saved;
+
+ parsed = true;
+
+ e = getenv("SYSTEMD_UDEV_EXTRA_TIMEOUT_SEC");
+ if (!e)
+ return saved;
+
+ r = parse_sec(e, &saved);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_UDEV_EXTRA_TIMEOUT_SEC=%s, ignoring: %m", e);
+
+ return saved;
+}
+
static void worker_attach_event(Worker *worker, Event *event) {
Manager *manager = ASSERT_PTR(ASSERT_PTR(worker)->manager);
sd_event *e = ASSERT_PTR(manager->event);
@@ -349,8 +371,12 @@ static void worker_attach_event(Worker *worker, Event *event) {
udev_warn_timeout(manager->timeout_usec), USEC_PER_SEC,
on_event_timeout_warning, event);
+ /* Manager.timeout_usec is also used as the timeout for running programs specified in
+ * IMPORT{program}=, PROGRAM=, or RUN=. Here, let's add an extra time before the manager
+ * kills a worker, to make it possible that the worker detects timed out of spawned programs,
+ * kills them, and finalizes the event. */
(void) sd_event_add_time_relative(e, &event->timeout_event, CLOCK_MONOTONIC,
- manager->timeout_usec, USEC_PER_SEC,
+ usec_add(manager->timeout_usec, extra_timeout_usec()), USEC_PER_SEC,
on_event_timeout, event);
}