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