summaryrefslogtreecommitdiffstats
path: root/src/udev/udev-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev/udev-manager.c')
-rw-r--r--src/udev/udev-manager.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c
index 8077e51..bb94478 100644
--- a/src/udev/udev-manager.c
+++ b/src/udev/udev-manager.c
@@ -274,15 +274,9 @@ static void manager_reload(Manager *manager, bool force) {
return;
/* If we eat this up, then tell our service manager to just continue */
- (void) sd_notifyf(/* unset= */ false,
- "RELOADING=1\n"
- "STATUS=Skipping configuration reloading, nothing changed.\n"
- "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC));
+ (void) notify_reloading_full("Skipping configuration reloading, nothing changed.");
} else {
- (void) sd_notifyf(/* unset= */ false,
- "RELOADING=1\n"
- "STATUS=Flushing configuration...\n"
- "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC));
+ (void) notify_reloading();
manager_kill_workers(manager, false);
@@ -332,12 +326,38 @@ 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;
+ usec_t timeout;
+ 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, &timeout);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_UDEV_EXTRA_TIMEOUT_SEC=%s, ignoring: %m", e);
+
+ if (timeout > 5 * USEC_PER_HOUR) /* Add an arbitrary upper bound */
+ log_debug("Parsed $SYSTEMD_UDEV_EXTRA_TIMEOUT_SEC=%s is too large, ignoring.", e);
+ else
+ saved = timeout;
+
+ return saved;
+}
+
static void worker_attach_event(Worker *worker, Event *event) {
- Manager *manager;
- sd_event *e;
+ Manager *manager = ASSERT_PTR(ASSERT_PTR(worker)->manager);
+ sd_event *e = ASSERT_PTR(manager->event);
- assert(worker);
- assert(worker->manager);
assert(event);
assert(!event->worker);
assert(!worker->event);
@@ -347,15 +367,16 @@ static void worker_attach_event(Worker *worker, Event *event) {
event->state = EVENT_RUNNING;
event->worker = worker;
- manager = worker->manager;
- e = manager->event;
-
(void) sd_event_add_time_relative(e, &event->timeout_warning_event, CLOCK_MONOTONIC,
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);
}
@@ -864,7 +885,7 @@ static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrl
switch (type) {
case UDEV_CTRL_SET_LOG_LEVEL:
- if ((value->intval & LOG_PRIMASK) != value->intval) {
+ if (LOG_PRI(value->intval) != value->intval) {
log_debug("Received invalid udev control message (SET_LOG_LEVEL, %i), ignoring.", value->intval);
break;
}
@@ -1194,13 +1215,33 @@ Manager* manager_new(void) {
.worker_watch = EBADF_PAIR,
.log_level = LOG_INFO,
.resolve_name_timing = RESOLVE_NAME_EARLY,
- .timeout_usec = 180 * USEC_PER_SEC,
+ .timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC,
.timeout_signal = SIGKILL,
};
return manager;
}
+void manager_adjust_arguments(Manager *manager) {
+ assert(manager);
+
+ if (manager->timeout_usec < MIN_WORKER_TIMEOUT_USEC) {
+ log_debug("Timeout (%s) for processing event is too small, using the default: %s",
+ FORMAT_TIMESPAN(manager->timeout_usec, 1),
+ FORMAT_TIMESPAN(DEFAULT_WORKER_TIMEOUT_USEC, 1));
+
+ manager->timeout_usec = DEFAULT_WORKER_TIMEOUT_USEC;
+ }
+
+ if (manager->exec_delay_usec >= manager->timeout_usec) {
+ log_debug("Delay (%s) for executing RUN= commands is too large compared with the timeout (%s) for event execution, ignoring the delay.",
+ FORMAT_TIMESPAN(manager->exec_delay_usec, 1),
+ FORMAT_TIMESPAN(manager->timeout_usec, 1));
+
+ manager->exec_delay_usec = 0;
+ }
+}
+
int manager_init(Manager *manager, int fd_ctrl, int fd_uevent) {
_cleanup_free_ char *cgroup = NULL;
int r;
@@ -1260,22 +1301,22 @@ int manager_main(Manager *manager) {
udev_watch_restore(manager->inotify_fd);
- /* block and listen to all signals on signalfd */
- assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, SIGRTMIN+18, -1) >= 0);
+ /* block SIGCHLD for listening child events. */
+ assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD) >= 0);
r = sd_event_default(&manager->event);
if (r < 0)
return log_error_errno(r, "Failed to allocate event loop: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGINT, on_sigterm, manager);
+ r = sd_event_add_signal(manager->event, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGINT event source: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGTERM, on_sigterm, manager);
+ r = sd_event_add_signal(manager->event, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_sigterm, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGTERM event source: %m");
- r = sd_event_add_signal(manager->event, NULL, SIGHUP, on_sighup, manager);
+ r = sd_event_add_signal(manager->event, NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, on_sighup, manager);
if (r < 0)
return log_error_errno(r, "Failed to create SIGHUP event source: %m");
@@ -1325,7 +1366,8 @@ int manager_main(Manager *manager) {
log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || (r == -EHOSTDOWN) ? LOG_DEBUG : LOG_WARNING, r,
"Failed to allocate memory pressure watch, ignoring: %m");
- r = sd_event_add_signal(manager->event, &manager->memory_pressure_event_source, SIGRTMIN+18, sigrtmin18_handler, NULL);
+ r = sd_event_add_signal(manager->event, &manager->memory_pressure_event_source,
+ (SIGRTMIN+18) | SD_EVENT_SIGNAL_PROCMASK, sigrtmin18_handler, NULL);
if (r < 0)
return log_error_errno(r, "Failed to allocate SIGRTMIN+18 event source, ignoring: %m");