Blame SOURCES/0208-Change-job-mode-of-manager-triggered-restarts-to-JOB.patch

a3e2b5
From d70e1c2eb596b8144197192e2324abbb45f547a6 Mon Sep 17 00:00:00 2001
a3e2b5
From: Jonathon Kowalski <bl0pbl33p@gmail.com>
a3e2b5
Date: Thu, 17 Jan 2019 17:08:00 +0000
a3e2b5
Subject: [PATCH] Change job mode of manager triggered restarts to JOB_REPLACE
a3e2b5
a3e2b5
Fixes: #11305
a3e2b5
Fixes: #3260
a3e2b5
Related: #11456
a3e2b5
a3e2b5
So, here's what happens in the described scenario in #11305. A unit goes
a3e2b5
down, and that triggeres stop jobs for the other two units as they were
a3e2b5
bound to it. Now, the timer for manager triggered restarts kicks in and
a3e2b5
schedules a restart job with the JOB_FAIL job mode. This means there is
a3e2b5
a stop job installed on those units, and now due to them being bound to
a3e2b5
us they also get a restart job enqueued. This however is a conflicts, as
a3e2b5
neither stop can merge into restart, nor restart into stop. However,
a3e2b5
restart should be able to replace stop in any case. If the stop
a3e2b5
procedure is ongoing, it can cancel the stop job, install itself, and
a3e2b5
then after reaching dead finish and convert itself to a start job.
a3e2b5
However, if we increase the timer, then it can always take those units
a3e2b5
from inactive -> auto-restart.
a3e2b5
a3e2b5
We change the job mode to JOB_REPLACE so the restart job cancels the
a3e2b5
stop job and installs itself.
a3e2b5
a3e2b5
Also, the original bug could be worked around by bumping RestartSec= to
a3e2b5
avoid the conflicting.
a3e2b5
a3e2b5
This doesn't seem to be something that is going to break uses. That is
a3e2b5
because for those who already had it working, there must have never been
a3e2b5
conflicting jobs, as that would result in a desctructive transaction by
a3e2b5
virtue of the job mode used.
a3e2b5
a3e2b5
After this change, the test case is able to work nicely without issues.
a3e2b5
a3e2b5
(cherry picked from commit 03ff2dc71ecb09272d728d458498b44f7f132f51)
a3e2b5
a3e2b5
Resolves: #1712524
a3e2b5
---
a3e2b5
 src/core/service.c | 2 +-
a3e2b5
 1 file changed, 1 insertion(+), 1 deletion(-)
a3e2b5
a3e2b5
diff --git a/src/core/service.c b/src/core/service.c
a3e2b5
index 3eab749362..8342c131c8 100644
a3e2b5
--- a/src/core/service.c
a3e2b5
+++ b/src/core/service.c
a3e2b5
@@ -2133,7 +2133,7 @@ static void service_enter_restart(Service *s) {
a3e2b5
          * restarted. We use JOB_RESTART (instead of the more obvious
a3e2b5
          * JOB_START) here so that those dependency jobs will be added
a3e2b5
          * as well. */
a3e2b5
-        r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_FAIL, &error, NULL);
a3e2b5
+        r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_REPLACE, &error, NULL);
a3e2b5
         if (r < 0)
a3e2b5
                 goto fail;
a3e2b5