Merge pull request #31016 from poettering/pid1-priority-rework

pid1 event source priorities rework
This commit is contained in:
Lennart Poettering 2024-01-20 00:13:39 +01:00 committed by GitHub
commit 3cdfd6acf1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 54 additions and 22 deletions

View file

@ -3858,7 +3858,7 @@ static void unit_add_to_cgroup_oom_queue(Unit *u) {
return;
}
r = sd_event_source_set_priority(s, SD_EVENT_PRIORITY_NORMAL-8);
r = sd_event_source_set_priority(s, EVENT_PRIORITY_CGROUP_OOM);
if (r < 0) {
log_error_errno(r, "Failed to set priority of cgroup oom event source: %m");
return;
@ -4064,7 +4064,7 @@ int manager_setup_cgroup(Manager *m) {
/* Schedule cgroup empty checks early, but after having processed service notification messages or
* SIGCHLD signals, so that a cgroup running empty is always just the last safety net of
* notification, and we collected the metadata the notification and SIGCHLD stuff offers first. */
r = sd_event_source_set_priority(m->cgroup_empty_event_source, SD_EVENT_PRIORITY_NORMAL-5);
r = sd_event_source_set_priority(m->cgroup_empty_event_source, EVENT_PRIORITY_CGROUP_EMPTY);
if (r < 0)
return log_error_errno(r, "Failed to set priority of cgroup empty event source: %m");
@ -4093,7 +4093,7 @@ int manager_setup_cgroup(Manager *m) {
/* Process cgroup empty notifications early. Note that when this event is dispatched it'll
* just add the unit to a cgroup empty queue, hence let's run earlier than that. Also see
* handling of cgroup agent notifications, for the classic cgroup hierarchy support. */
r = sd_event_source_set_priority(m->cgroup_inotify_event_source, SD_EVENT_PRIORITY_NORMAL-9);
r = sd_event_source_set_priority(m->cgroup_inotify_event_source, EVENT_PRIORITY_CGROUP_INOTIFY);
if (r < 0)
return log_error_errno(r, "Failed to set priority of inotify event source: %m");

View file

@ -527,7 +527,7 @@ static int manager_varlink_init_system(Manager *m) {
}
}
r = varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
r = varlink_server_attach_event(s, m->event, EVENT_PRIORITY_IPC);
if (r < 0)
return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
@ -585,7 +585,7 @@ static int manager_varlink_init_user(Manager *m) {
if (r < 0)
return r;
r = varlink_attach_event(link, m->event, SD_EVENT_PRIORITY_NORMAL);
r = varlink_attach_event(link, m->event, EVENT_PRIORITY_IPC);
if (r < 0)
return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");

View file

@ -739,7 +739,7 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
log_debug("Accepting direct incoming connection from " PID_FMT " (%s) [%s]", pid, strna(comm), strna(description));
}
r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
r = sd_bus_attach_event(bus, m->event, EVENT_PRIORITY_IPC);
if (r < 0) {
log_warning_errno(r, "Failed to attach new connection bus to event loop: %m");
return 0;
@ -847,7 +847,7 @@ int bus_init_api(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to connect to API bus: %m");
r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
r = sd_bus_attach_event(bus, m->event, EVENT_PRIORITY_IPC);
if (r < 0)
return log_error_errno(r, "Failed to attach API bus to event loop: %m");
@ -904,7 +904,7 @@ int bus_init_system(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m");
r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
r = sd_bus_attach_event(bus, m->event, EVENT_PRIORITY_IPC);
if (r < 0)
return log_error_errno(r, "Failed to attach system bus to event loop: %m");

View file

@ -397,7 +397,7 @@ static int manager_setup_time_change(Manager *m) {
return log_error_errno(r, "Failed to create time change event source: %m");
/* Schedule this slightly earlier than the .timer event sources */
r = sd_event_source_set_priority(m->time_change_event_source, SD_EVENT_PRIORITY_NORMAL-1);
r = sd_event_source_set_priority(m->time_change_event_source, EVENT_PRIORITY_TIME_CHANGE);
if (r < 0)
return log_error_errno(r, "Failed to set priority of time change event sources: %m");
@ -464,7 +464,7 @@ static int manager_setup_timezone_change(Manager *m) {
return log_error_errno(r, "Failed to create timezone change event source: %m");
/* Schedule this slightly earlier than the .timer event sources */
r = sd_event_source_set_priority(new_event, SD_EVENT_PRIORITY_NORMAL-1);
r = sd_event_source_set_priority(new_event, EVENT_PRIORITY_TIME_ZONE);
if (r < 0)
return log_error_errno(r, "Failed to set priority of timezone change event sources: %m");
@ -592,7 +592,7 @@ static int manager_setup_signals(Manager *m) {
* notify processing can still figure out to which process/service a message belongs, before we reap the
* process. Also, process this before handling cgroup notifications, so that we always collect child exit
* status information before detecting that there's no process in a cgroup. */
r = sd_event_source_set_priority(m->signal_event_source, SD_EVENT_PRIORITY_NORMAL-6);
r = sd_event_source_set_priority(m->signal_event_source, EVENT_PRIORITY_SIGNALS);
if (r < 0)
return r;
@ -736,7 +736,7 @@ static int manager_setup_run_queue(Manager *m) {
if (r < 0)
return r;
r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
r = sd_event_source_set_priority(m->run_queue_event_source, EVENT_PRIORITY_RUN_QUEUE);
if (r < 0)
return r;
@ -759,7 +759,7 @@ static int manager_setup_sigchld_event_source(Manager *m) {
if (r < 0)
return r;
r = sd_event_source_set_priority(m->sigchld_event_source, SD_EVENT_PRIORITY_NORMAL-7);
r = sd_event_source_set_priority(m->sigchld_event_source, EVENT_PRIORITY_SIGCHLD);
if (r < 0)
return r;
@ -1113,7 +1113,7 @@ static int manager_setup_notify(Manager *m) {
/* Process notification messages a bit earlier than SIGCHLD, so that we can still identify to which
* service an exit message belongs. */
r = sd_event_source_set_priority(m->notify_event_source, SD_EVENT_PRIORITY_NORMAL-8);
r = sd_event_source_set_priority(m->notify_event_source, EVENT_PRIORITY_NOTIFY);
if (r < 0)
return log_error_errno(r, "Failed to set priority of notify event source: %m");
@ -1187,7 +1187,7 @@ static int manager_setup_cgroups_agent(Manager *m) {
/* Process cgroups notifications early. Note that when the agent notification is received
* we'll just enqueue the unit in the cgroup empty queue, hence pick a high priority than
* that. Also see handling of cgroup inotify for the unified cgroup stuff. */
r = sd_event_source_set_priority(m->cgroups_agent_event_source, SD_EVENT_PRIORITY_NORMAL-9);
r = sd_event_source_set_priority(m->cgroups_agent_event_source, EVENT_PRIORITY_CGROUP_AGENT);
if (r < 0)
return log_error_errno(r, "Failed to set priority of cgroups agent event source: %m");
@ -1240,7 +1240,7 @@ static int manager_setup_user_lookup_fd(Manager *m) {
/* Process even earlier than the notify event source, so that we always know first about valid UID/GID
* resolutions */
r = sd_event_source_set_priority(m->user_lookup_event_source, SD_EVENT_PRIORITY_NORMAL-11);
r = sd_event_source_set_priority(m->user_lookup_event_source, EVENT_PRIORITY_USER_LOOKUP);
if (r < 0)
return log_error_errno(errno, "Failed to set priority of user lookup event source: %m");

View file

@ -644,3 +644,25 @@ OOMPolicy oom_policy_from_string(const char *s) _pure_;
void unit_defaults_init(UnitDefaults *defaults, RuntimeScope scope);
void unit_defaults_done(UnitDefaults *defaults);
enum {
/* most important … */
EVENT_PRIORITY_USER_LOOKUP = SD_EVENT_PRIORITY_NORMAL-10,
EVENT_PRIORITY_MOUNT_TABLE = SD_EVENT_PRIORITY_NORMAL-9,
EVENT_PRIORITY_SWAP_TABLE = SD_EVENT_PRIORITY_NORMAL-9,
EVENT_PRIORITY_CGROUP_AGENT = SD_EVENT_PRIORITY_NORMAL-8, /* cgroupv1 */
EVENT_PRIORITY_CGROUP_INOTIFY = SD_EVENT_PRIORITY_NORMAL-8, /* cgroupv2 */
EVENT_PRIORITY_CGROUP_OOM = SD_EVENT_PRIORITY_NORMAL-7,
EVENT_PRIORITY_EXEC_FD = SD_EVENT_PRIORITY_NORMAL-6,
EVENT_PRIORITY_NOTIFY = SD_EVENT_PRIORITY_NORMAL-5,
EVENT_PRIORITY_SIGCHLD = SD_EVENT_PRIORITY_NORMAL-4,
EVENT_PRIORITY_SIGNALS = SD_EVENT_PRIORITY_NORMAL-3,
EVENT_PRIORITY_CGROUP_EMPTY = SD_EVENT_PRIORITY_NORMAL-2,
EVENT_PRIORITY_TIME_CHANGE = SD_EVENT_PRIORITY_NORMAL-1,
EVENT_PRIORITY_TIME_ZONE = SD_EVENT_PRIORITY_NORMAL-1,
EVENT_PRIORITY_IPC = SD_EVENT_PRIORITY_NORMAL,
EVENT_PRIORITY_REWATCH_PIDS = SD_EVENT_PRIORITY_IDLE,
EVENT_PRIORITY_SERVICE_WATCHDOG = SD_EVENT_PRIORITY_IDLE+1,
EVENT_PRIORITY_RUN_QUEUE = SD_EVENT_PRIORITY_IDLE+2,
/* … to least important */
};

View file

@ -2090,7 +2090,7 @@ static void mount_enumerate(Manager *m) {
goto fail;
}
r = sd_event_source_set_priority(m->mount_event_source, SD_EVENT_PRIORITY_NORMAL-10);
r = sd_event_source_set_priority(m->mount_event_source, EVENT_PRIORITY_MOUNT_TABLE);
if (r < 0) {
log_error_errno(r, "Failed to adjust mount watch priority: %m");
goto fail;

View file

@ -291,7 +291,7 @@ static void service_start_watchdog(Service *s) {
/* Let's process everything else which might be a sign
* of living before we consider a service died. */
r = sd_event_source_set_priority(s->watchdog_event_source, SD_EVENT_PRIORITY_IDLE);
r = sd_event_source_set_priority(s->watchdog_event_source, EVENT_PRIORITY_SERVICE_WATCHDOG);
}
if (r < 0)
log_unit_warning_errno(UNIT(s), r, "Failed to install watchdog timer: %m");
@ -1512,9 +1512,10 @@ static int service_allocate_exec_fd_event_source(
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to allocate exec_fd event source: %m");
/* This is a bit lower priority than SIGCHLD, as that carries a lot more interesting failure information */
/* This is a bit higher priority than SIGCHLD, to make sure we don't confuse the case "failed to
* start" from the case "succeeded to start, but failed immediately after". */
r = sd_event_source_set_priority(source, SD_EVENT_PRIORITY_NORMAL-3);
r = sd_event_source_set_priority(source, EVENT_PRIORITY_EXEC_FD);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to adjust priority of exec_fd event source: %m");

View file

@ -1358,7 +1358,7 @@ static void swap_enumerate(Manager *m) {
/* Dispatch this before we dispatch SIGCHLD, so that
* we always get the events from /proc/swaps before
* the SIGCHLD of /sbin/swapon. */
r = sd_event_source_set_priority(m->swap_event_source, SD_EVENT_PRIORITY_NORMAL-10);
r = sd_event_source_set_priority(m->swap_event_source, EVENT_PRIORITY_SWAP_TABLE);
if (r < 0) {
log_error_errno(r, "Failed to change /proc/swaps priority: %m");
goto fail;

View file

@ -2992,7 +2992,7 @@ int unit_enqueue_rewatch_pids(Unit *u) {
if (r < 0)
return log_error_errno(r, "Failed to allocate event source for tidying watched PIDs: %m");
r = sd_event_source_set_priority(s, SD_EVENT_PRIORITY_IDLE);
r = sd_event_source_set_priority(s, EVENT_PRIORITY_REWATCH_PIDS);
if (r < 0)
return log_error_errno(r, "Failed to adjust priority of event source for tidying watched PIDs: %m");

View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
# Make sure that we never mistake a process starting but failing quickly for a process failing to start, with Type=exec.
# See https://github.com/systemd/systemd/pull/30799
seq 25 | xargs -n 1 -P 0 systemd-run -p Type=exec /bin/false