Skip to content

Commit

Permalink
systemd: skip automatic restart when a JOB_STOP job is pending
Browse files Browse the repository at this point in the history
Signed-off-by: Kyle Sessions <[email protected]>
  • Loading branch information
KCSesh committed May 6, 2024
1 parent c7474ce commit a5f5959
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ RUN last_patch=$(awk '/^Patch[0-9]+/ { line = NR } END { print line }' systemd.s
echo 'Patch9501: 9501-cgroup-util-accept-cgroup-hierarchy-base-as-option.patch'; \
echo 'Patch9502: 9502-core-move-initialization-of-.slice-and-init.scope-in.patch'; \
echo 'Patch9503: 9503-core-drop-.slice-from-shipped-units.patch'; \
echo 'Patch9504: 9504-core-skip-restart-when-a-JOB_STOP-job-is-pending.patch'; \
echo ; \
} >>systemd.mod.spec; \
tail -n+$((last_patch + 1)) systemd.spec >>systemd.mod.spec; \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
From c972880640ee19e89ce9265d8eae1b3aae190332 Mon Sep 17 00:00:00 2001
From: Franck Bui <[email protected]>
Date: Fri, 18 Feb 2022 10:06:24 +0100
Subject: [PATCH] core: really skip automatic restart when a JOB_STOP job is
pending

It's not clear why we rescheduled a service auto restart while a stop job for
the unit was pending. The comment claims that the unit shouldn't be restarted
but the code did reschedule an auto restart meanwhile.

In practice that was rarely an issue because the service waited for the next
auto restart to be rescheduled, letting the queued stop job to be proceed and
service_stop() to be called preventing the next restart to complete.

However when RestartSec=0, the timer expired right away making PID1 to
reschedule the unit again, making the timer expired right away... and so
on. This busy loop prevented PID1 to handle any queued jobs (and hence giving
no chance to the start rate limiting to trigger), which made the busy loop last
forever.

This patch breaks this loop by skipping the reschedule of the unit auto restart
and hence not depending on the value of u->restart_usec anymore.

Fixes: #13667

[kssessio: backport to v219]
Signed-off-by: Kyle Sessions <[email protected]>
---
src/core/service.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/core/service.c b/src/core/service.c
index 15e29be..fa2af05 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1622,12 +1622,7 @@ static void service_enter_restart(Service *s) {

if (UNIT(s)->job && UNIT(s)->job->type == JOB_STOP) {
/* Don't restart things if we are going down anyway */
- log_unit_info(UNIT(s)->id, "Stop job pending for unit, delaying automatic restart.");
-
- r = service_arm_timer(s, s->restart_usec);
- if (r < 0)
- goto fail;
-
+ log_unit_info(UNIT(s)->id, "Stop job pending for unit, skipping automatic restart.");
return;
}

--
2.40.1

0 comments on commit a5f5959

Please sign in to comment.