summaryrefslogtreecommitdiff
path: root/delay-to-restart-when-a-service-can-not-be-auto-restarted.patch
blob: d0883d746135c28c5b66ae5958308306fc9c8f35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
From 9315c29e4fdfa19c90bb483a364b017881f5cef7 Mon Sep 17 00:00:00 2001
From: huangkaibin <huangkaibin@huawei.com>
Date: Sat, 21 Apr 2018 17:18:19 +0800
Subject: [PATCH] systemd-core: Delay to restart when a service can not be
 auto-restarted when there is one STOP_JOB for the service

When a service current has a STOP job has not scheduled yet,
and also if the service is already scheduled with an auto-restart
with restart-second configured as 0, the service will not be restarted successfully,
and systemd will go into an endless loop to restart the service.
This is because restart-second is 0 and timer task has higher priority than IO tasks when there priority
is same(both with 0), so the STOP job has no chance to be scheduled, and systemd will go into the endless loop
to handle the time task.
This patch fix this problem by delaying 1 second to restart the service to cause STOP job to be scheduled.
---
 src/core/service.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/core/service.c b/src/core/service.c
index b9eb40c..47e9d63 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2507,13 +2507,20 @@ fail:
 static void service_enter_restart(Service *s) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         int r;
+        int restart_usec;
 
         assert(s);
 
         if (unit_has_job_type(UNIT(s), JOB_STOP)) {
                 /* Don't restart things if we are going down anyway */
                 log_unit_info(UNIT(s), "Stop job pending for unit, skipping automatic restart.");
-                return;
+                restart_usec = (s->restart_usec == 0) ? 1*USEC_PER_SEC : s->restart_usec;
+                r = service_arm_timer(s, /* relative= */ false, usec_add(now(CLOCK_MONOTONIC), restart_usec));
+                if (r < 0) {
+                        log_unit_warning(UNIT(s), "Failed to schedule restart job: %s", bus_error_message(&error, r));
+                        service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ false);
+                        return;
+                }
         }
 
         /* Any units that are bound to this service must also be restarted. We use JOB_START for ourselves
-- 
2.33.0