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