b9a53a
From cb084637ba1c8558f1538ce300c5520a6764dc76 Mon Sep 17 00:00:00 2001
4b8c80
From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
4b8c80
Date: Mon, 28 Oct 2019 19:35:24 +0900
4b8c80
Subject: [PATCH] core, job: fix breakage of ordering dependencies by systemctl
4b8c80
 reload command
4b8c80
4b8c80
Currently, systemctl reload command breaks ordering dependencies if it's
4b8c80
executed when its target service unit is in activating state.
4b8c80
4b8c80
For example, prepare A.service, B.service and C.target as follows:
4b8c80
4b8c80
    # systemctl cat A.service B.service C.target
4b8c80
    # /etc/systemd/system/A.service
4b8c80
    [Unit]
4b8c80
    Description=A
4b8c80
4b8c80
    [Service]
4b8c80
    Type=oneshot
4b8c80
    ExecStart=/usr/bin/echo A1
4b8c80
    ExecStart=/usr/bin/sleep 60
4b8c80
    ExecStart=/usr/bin/echo A2
4b8c80
    ExecReload=/usr/bin/echo A reloaded
4b8c80
    RemainAfterExit=yes
4b8c80
4b8c80
    # /etc/systemd/system/B.service
4b8c80
    [Unit]
4b8c80
    Description=B
4b8c80
    After=A.service
4b8c80
4b8c80
    [Service]
4b8c80
    Type=oneshot
4b8c80
    ExecStart=/usr/bin/echo B
4b8c80
    RemainAfterExit=yes
4b8c80
4b8c80
    # /etc/systemd/system/C.target
4b8c80
    [Unit]
4b8c80
    Description=C
4b8c80
    Wants=A.service B.service
4b8c80
4b8c80
Start them.
4b8c80
4b8c80
    # systemctl daemon-reload
4b8c80
    # systemctl start C.target
4b8c80
4b8c80
Then, we have:
4b8c80
4b8c80
    # LANG=C journalctl --no-pager -u A.service -u B.service -u C.target -b
4b8c80
    -- Logs begin at Mon 2019-09-09 00:25:06 EDT, end at Thu 2019-10-24 22:28:47 EDT. --
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[1]: Starting A...
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Child 967 belongs to A.service.
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/sleep 60
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/sleep as 968
4b8c80
    Oct 24 22:27:47 localhost.localdomain systemd[968]: A.service: Executing: /usr/bin/sleep 60
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Trying to enqueue job A.service/reload/replace
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Merged into running job, re-running: A.service/reload as 1288
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Enqueued job A.service/reload as 1288
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Unit cannot be reloaded because it is inactive.
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Job 1288 A.service/reload finished, result=invalid
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Passing 0 fds to service
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: About to execute: /usr/bin/echo B
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Forked /usr/bin/echo as 970
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[970]: B.service: Executing: /usr/bin/echo B
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Failed to send unit change signal for B.service: Connection reset by peer
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed dead -> start
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: Starting B...
4b8c80
    Oct 24 22:27:52 localhost.localdomain echo[970]: B
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Child 970 belongs to B.service.
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Main process exited, code=exited, status=0/SUCCESS
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed start -> exited
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Job 1371 B.service/start finished, result=done
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: Started B.
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Job 1287 C.target/start finished, result=done
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: Reached target C.
4b8c80
    Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Failed to send unit change signal for C.target: Connection reset by peer
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 968 belongs to A.service.
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/echo A2
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/echo as 972
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[972]: A.service: Executing: /usr/bin/echo A2
4b8c80
    Oct 24 22:28:47 localhost.localdomain echo[972]: A2
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 972 belongs to A.service.
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
4b8c80
    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Changed start -> exited
4b8c80
4b8c80
The issue occurs not only in reload command, i.e.:
4b8c80
4b8c80
  - reload
4b8c80
  - try-restart
4b8c80
  - reload-or-restart
4b8c80
  - reload-or-try-restart commands
4b8c80
4b8c80
The cause of this issue is that job_type_collapse() doesn't take care of the
4b8c80
activating state.
4b8c80
4b8c80
Fixes: #10464
4b8c80
(cherry picked from commit d1559793df555212271e490a4a72f55826caf5b4)
b9a53a
b9a53a
Resolves: #1766417
4b8c80
---
4b8c80
 src/core/job.c | 6 +++---
4b8c80
 1 file changed, 3 insertions(+), 3 deletions(-)
4b8c80
4b8c80
diff --git a/src/core/job.c b/src/core/job.c
4b8c80
index 8552ffb704..769ed6d603 100644
4b8c80
--- a/src/core/job.c
4b8c80
+++ b/src/core/job.c
4b8c80
@@ -403,21 +403,21 @@ JobType job_type_collapse(JobType t, Unit *u) {
4b8c80
 
4b8c80
         case JOB_TRY_RESTART:
4b8c80
                 s = unit_active_state(u);
4b8c80
-                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
4b8c80
+                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
4b8c80
                         return JOB_NOP;
4b8c80
 
4b8c80
                 return JOB_RESTART;
4b8c80
 
4b8c80
         case JOB_TRY_RELOAD:
4b8c80
                 s = unit_active_state(u);
4b8c80
-                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
4b8c80
+                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
4b8c80
                         return JOB_NOP;
4b8c80
 
4b8c80
                 return JOB_RELOAD;
4b8c80
 
4b8c80
         case JOB_RELOAD_OR_START:
4b8c80
                 s = unit_active_state(u);
4b8c80
-                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
4b8c80
+                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
4b8c80
                         return JOB_START;
4b8c80
 
4b8c80
                 return JOB_RELOAD;