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