a19bc6
From 77f4e582d0f381391594e6f8a7b6767d572d96f7 Mon Sep 17 00:00:00 2001
b48b43
From: Lennart Poettering <lennart@poettering.net>
b48b43
Date: Tue, 19 May 2015 18:13:22 +0200
b48b43
Subject: [PATCH] core: when propagating restart requests due to deps,
b48b43
 downgrade restart to try-restart
b48b43
b48b43
Previously, if a service A depended on a service B via Requires=, and A
b48b43
was not running and B restarted this would trigger a start of A as well,
b48b43
since the restart was propagated as restart independently of the state
b48b43
of A.
b48b43
b48b43
This patch ensures that a restart of B would be propagated as a
b48b43
try-restart to A, thus not changing its state if it isn't up.
b48b43
b48b43
http://lists.freedesktop.org/archives/systemd-devel/2015-May/032061.html
b48b43
(cherry picked from commit c6497ccb7153af9a1252c48918e380b5134314de)
b48b43
b48b43
Resolves: #1436021
b48b43
---
b48b43
 src/core/job.c         | 28 ++++++++++++++--------------
b48b43
 src/core/job.h         |  2 +-
b48b43
 src/core/manager.c     |  2 +-
b48b43
 src/core/transaction.c | 11 ++++++++---
b48b43
 4 files changed, 24 insertions(+), 19 deletions(-)
b48b43
b48b43
diff --git a/src/core/job.c b/src/core/job.c
c62b8e
index 703286496f..1617e24c03 100644
b48b43
--- a/src/core/job.c
b48b43
+++ b/src/core/job.c
b48b43
@@ -392,38 +392,38 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) {
b48b43
         }
b48b43
 }
b48b43
 
b48b43
-void job_type_collapse(JobType *t, Unit *u) {
b48b43
+JobType job_type_collapse(JobType t, Unit *u) {
b48b43
         UnitActiveState s;
b48b43
 
b48b43
-        switch (*t) {
b48b43
+        switch (t) {
b48b43
 
b48b43
         case JOB_TRY_RESTART:
b48b43
                 s = unit_active_state(u);
b48b43
                 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
b48b43
-                        *t = JOB_NOP;
b48b43
-                else
b48b43
-                        *t = JOB_RESTART;
b48b43
-                break;
b48b43
+                        return JOB_NOP;
b48b43
+
b48b43
+                return JOB_RESTART;
b48b43
 
b48b43
         case JOB_RELOAD_OR_START:
b48b43
                 s = unit_active_state(u);
b48b43
                 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
b48b43
-                        *t = JOB_START;
b48b43
-                else
b48b43
-                        *t = JOB_RELOAD;
b48b43
-                break;
b48b43
+                        return JOB_START;
b48b43
+
b48b43
+                return JOB_RELOAD;
b48b43
 
b48b43
         default:
b48b43
-                ;
b48b43
+                return t;
b48b43
         }
b48b43
 }
b48b43
 
b48b43
 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
b48b43
-        JobType t = job_type_lookup_merge(*a, b);
b48b43
+        JobType t;
b48b43
+
b48b43
+        t = job_type_lookup_merge(*a, b);
b48b43
         if (t < 0)
b48b43
                 return -EEXIST;
b48b43
-        *a = t;
b48b43
-        job_type_collapse(a, u);
b48b43
+
b48b43
+        *a = job_type_collapse(t, u);
b48b43
         return 0;
b48b43
 }
b48b43
 
b48b43
diff --git a/src/core/job.h b/src/core/job.h
c62b8e
index e4191ee775..ce81607de8 100644
b48b43
--- a/src/core/job.h
b48b43
+++ b/src/core/job.h
b48b43
@@ -210,7 +210,7 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) _pure_;
b48b43
 
b48b43
 /* Collapses a state-dependent job type into a simpler type by observing
b48b43
  * the state of the unit which it is going to be applied to. */
b48b43
-void job_type_collapse(JobType *t, Unit *u);
b48b43
+JobType job_type_collapse(JobType t, Unit *u);
b48b43
 
b48b43
 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u);
b48b43
 
b48b43
diff --git a/src/core/manager.c b/src/core/manager.c
c62b8e
index 8bd80e6875..287cf6a741 100644
b48b43
--- a/src/core/manager.c
b48b43
+++ b/src/core/manager.c
b48b43
@@ -1303,7 +1303,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove
b48b43
                        "Trying to enqueue job %s/%s/%s", unit->id,
b48b43
                        job_type_to_string(type), job_mode_to_string(mode));
b48b43
 
b48b43
-        job_type_collapse(&type, unit);
b48b43
+        type = job_type_collapse(type, unit);
b48b43
 
b48b43
         tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
b48b43
         if (!tr)
b48b43
diff --git a/src/core/transaction.c b/src/core/transaction.c
c62b8e
index 428b7671b3..34df15718b 100644
b48b43
--- a/src/core/transaction.c
b48b43
+++ b/src/core/transaction.c
b48b43
@@ -855,8 +855,7 @@ int transaction_add_job_and_dependencies(
b48b43
         /*           by ? job_type_to_string(by->type) : "NA"); */
b48b43
 
b48b43
         if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_MASKED))
b48b43
-                return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
b48b43
-                                         "Unit %s is not loaded properly.", unit->id);
b48b43
+                return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
b48b43
 
b48b43
         if (type != JOB_STOP) {
b48b43
                 r = bus_unit_check_load_state(unit, e);
b48b43
@@ -1014,12 +1013,18 @@ int transaction_add_job_and_dependencies(
b48b43
                                 UNIT_CONSISTS_OF,
b48b43
                         };
b48b43
 
b48b43
+                        JobType ptype;
b48b43
                         unsigned j;
b48b43
 
b48b43
+                        /* We propagate STOP as STOP, but RESTART only
b48b43
+                         * as TRY_RESTART, in order not to start
b48b43
+                         * dependencies that are not around. */
b48b43
+                        ptype = type == JOB_RESTART ? JOB_TRY_RESTART : type;
b48b43
+
b48b43
                         for (j = 0; j < ELEMENTSOF(propagate_deps); j++)
b48b43
                                 SET_FOREACH(dep, ret->unit->dependencies[propagate_deps[j]], i) {
b48b43
 
b48b43
-                                        r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e);
b48b43
+                                        r = transaction_add_job_and_dependencies(tr, job_type_collapse(ptype, dep), dep, ret, true, override, false, false, ignore_order, e);
b48b43
                                         if (r < 0) {
b48b43
                                                 if (r != -EBADR)
b48b43
                                                         goto fail;