summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Stone <a@stne.dev>2022-08-23 00:03:42 +0200
committerAndrew Stone <a@stne.dev>2022-08-26 01:38:23 +0200
commitdc06321fe3e44915b732248bbf93d01b2bb7819a (patch)
tree9c2ab9533ec4f0a05b138dd643a747a9fd184766 /src
parenttest: Move testsuite-03 units to .units directory (diff)
downloadsystemd-dc06321fe3e44915b732248bbf93d01b2bb7819a.tar.xz
systemd-dc06321fe3e44915b732248bbf93d01b2bb7819a.zip
job: Don't discard propagated restart jobs when unit is activating
When a service unit Requires= a socket, and the socket is restarted while the service is in state=activating, the propagated restart is being discarded. This is contrary to the documentation for Requires=, which states "this unit will be stopped (or restarted) if one of the other units is explicitly stopped (or restarted)".
Diffstat (limited to 'src')
-rw-r--r--src/core/job.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/core/job.c b/src/core/job.c
index 6653dbde84..9a75abb9e9 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -400,8 +400,22 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) {
b == UNIT_RELOADING;
case JOB_RESTART:
- return
- b == UNIT_ACTIVATING;
+ /* Restart jobs must always be kept.
+ *
+ * For ACTIVE/RELOADING units, this is obvious.
+ *
+ * For ACTIVATING units, it's more subtle:
+ *
+ * Generally, if a service Requires= another unit, restarts of
+ * the unit must be propagated to the service. If the service is
+ * ACTIVATING, it must still be restarted since it might have
+ * stale information regarding the other unit.
+ *
+ * For example, consider a service that Requires= a socket: if
+ * the socket is restarted, but the service is still ACTIVATING,
+ * it's necessary to restart the service so that it gets the new
+ * socket. */
+ return false;
case JOB_NOP:
return true;
@@ -417,8 +431,12 @@ JobType job_type_collapse(JobType t, Unit *u) {
switch (t) {
case JOB_TRY_RESTART:
+ /* Be sure to keep the restart job even if the unit is
+ * ACTIVATING.
+ *
+ * See the job_type_is_redundant(JOB_RESTART) for more info */
s = unit_active_state(u);
- if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
+ if (!UNIT_IS_ACTIVE_OR_ACTIVATING(s))
return JOB_NOP;
return JOB_RESTART;