984f77
From e5121fbb839a36055e5fdab1b9d92dc42f495f29 Mon Sep 17 00:00:00 2001
984f77
From: Lennart Poettering <lennart@poettering.net>
984f77
Date: Fri, 11 Sep 2020 19:49:33 +0200
984f77
Subject: [PATCH] core: propagate triggered unit in more load states
984f77
984f77
In 4c2ef3276735ad9f7fccf33f5bdcbe7d8751e7ec we enabled propagating
984f77
triggered unit state to the triggering unit for service units in more
984f77
load states, so that we don't accidentally stop tracking state
984f77
correctly.
984f77
984f77
Do the same for our other triggering unit states: automounts, paths, and
984f77
timers.
984f77
984f77
Also, make this an assertion rather than a simple test. After all it
984f77
should never happen that we get called for half-loaded units or units of
984f77
the wrong type. The load routines should already have made this
984f77
impossible.
984f77
984f77
(cherry picked from commit 0377cd2936ae5cac0c9d76a4b58889f121c097c4)
984f77
984f77
Related: #2065322
984f77
---
984f77
 src/core/automount.c   | 4 ++--
984f77
 src/core/path.c        | 7 +++----
984f77
 src/core/socket.c      | 4 ++--
984f77
 src/core/timer.c       | 4 ++--
984f77
 src/core/transaction.c | 2 +-
984f77
 src/core/unit.h        | 4 ++++
984f77
 6 files changed, 14 insertions(+), 11 deletions(-)
984f77
984f77
diff --git a/src/core/automount.c b/src/core/automount.c
984f77
index f212620c8f..c1c513d4a5 100644
984f77
--- a/src/core/automount.c
984f77
+++ b/src/core/automount.c
984f77
@@ -492,8 +492,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) {
984f77
         assert(other);
984f77
 
984f77
         /* Filter out invocations with bogus state */
984f77
-        if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT)
984f77
-                return;
984f77
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
984f77
+        assert(other->type == UNIT_MOUNT);
984f77
 
984f77
         /* Don't propagate state changes from the mount if we are already down */
984f77
         if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING))
984f77
diff --git a/src/core/path.c b/src/core/path.c
984f77
index 58f490589d..a7c2e0b7c1 100644
984f77
--- a/src/core/path.c
984f77
+++ b/src/core/path.c
984f77
@@ -696,11 +696,10 @@ static void path_trigger_notify(Unit *u, Unit *other) {
984f77
         assert(u);
984f77
         assert(other);
984f77
 
984f77
-        /* Invoked whenever the unit we trigger changes state or gains
984f77
-         * or loses a job */
984f77
+        /* Invoked whenever the unit we trigger changes state or gains or loses a job */
984f77
 
984f77
-        if (other->load_state != UNIT_LOADED)
984f77
-                return;
984f77
+        /* Filter out invocations with bogus state */
984f77
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
984f77
 
984f77
         if (p->state == PATH_RUNNING &&
984f77
             UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
984f77
diff --git a/src/core/socket.c b/src/core/socket.c
984f77
index 3589300e68..74c1cc70cb 100644
984f77
--- a/src/core/socket.c
984f77
+++ b/src/core/socket.c
984f77
@@ -3190,8 +3190,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
984f77
         assert(other);
984f77
 
984f77
         /* Filter out invocations with bogus state */
984f77
-        if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
984f77
-                return;
984f77
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
984f77
+        assert(other->type == UNIT_SERVICE);
984f77
 
984f77
         /* Don't propagate state changes from the service if we are already down */
984f77
         if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING))
984f77
diff --git a/src/core/timer.c b/src/core/timer.c
984f77
index 684180bf99..990f05fee4 100644
984f77
--- a/src/core/timer.c
984f77
+++ b/src/core/timer.c
984f77
@@ -745,8 +745,8 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
984f77
         assert(u);
984f77
         assert(other);
984f77
 
984f77
-        if (other->load_state != UNIT_LOADED)
984f77
-                return;
984f77
+        /* Filter out invocations with bogus state */
984f77
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
984f77
 
984f77
         /* Reenable all timers that depend on unit state */
984f77
         LIST_FOREACH(value, v, t->values)
984f77
diff --git a/src/core/transaction.c b/src/core/transaction.c
984f77
index ee5b39fef4..8196aba927 100644
984f77
--- a/src/core/transaction.c
984f77
+++ b/src/core/transaction.c
984f77
@@ -915,7 +915,7 @@ int transaction_add_job_and_dependencies(
984f77
 
984f77
         /* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set
984f77
          * temporarily. */
984f77
-        if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_MASKED))
984f77
+        if (!UNIT_IS_LOAD_COMPLETE(unit->load_state))
984f77
                 return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
984f77
 
984f77
         if (type != JOB_STOP) {
984f77
diff --git a/src/core/unit.h b/src/core/unit.h
984f77
index 0cd259411f..b8b914711f 100644
984f77
--- a/src/core/unit.h
984f77
+++ b/src/core/unit.h
984f77
@@ -47,6 +47,10 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
984f77
         return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED);
984f77
 }
984f77
 
984f77
+static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) {
984f77
+        return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED;
984f77
+}
984f77
+
984f77
 /* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
984f77
  * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
984f77
  * created as a result of multiple "reasons", hence the bitmask. */