]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: propagate triggered unit in more load states
authorLennart Poettering <lennart@poettering.net>
Fri, 11 Sep 2020 17:49:33 +0000 (19:49 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 14 Sep 2020 11:05:09 +0000 (13:05 +0200)
In 4c2ef3276735ad9f7fccf33f5bdcbe7d8751e7ec we enabled propagating
triggered unit state to the triggering unit for service units in more
load states, so that we don't accidentally stop tracking state
correctly.

Do the same for our other triggering unit states: automounts, paths, and
timers.

Also, make this an assertion rather than a simple test. After all it
should never happen that we get called for half-loaded units or units of
the wrong type. The load routines should already have made this
impossible.

src/core/automount.c
src/core/path.c
src/core/socket.c
src/core/timer.c
src/core/transaction.c
src/core/unit.h

index 782f7680aa5e4528a3bc9cc2849bad9b491e2d98..4db763f84ecfd88a5a29dc8b68dbcc791f0e3a2f 100644 (file)
@@ -507,8 +507,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) {
         assert(other);
 
         /* Filter out invocations with bogus state */
-        if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT)
-                return;
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
+        assert(other->type == UNIT_MOUNT);
 
         /* Don't propagate state changes from the mount if we are already down */
         if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING))
index 1c3c28e34172c2b5484ded964e723283da82f969..8ffec72edeff01a422d46f89e9dd757883440fff 100644 (file)
@@ -748,11 +748,10 @@ static void path_trigger_notify(Unit *u, Unit *other) {
         assert(u);
         assert(other);
 
-        /* Invoked whenever the unit we trigger changes state or gains
-         * or loses a job */
+        /* Invoked whenever the unit we trigger changes state or gains or loses a job */
 
-        if (other->load_state != UNIT_LOADED)
-                return;
+        /* Filter out invocations with bogus state */
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
 
         if (p->state == PATH_RUNNING &&
             UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
index 02841f0e2469e084f6c9fb0b41dde11b7b03a490..be7d364084dd305e742c20a7da98d10366bbb15f 100644 (file)
@@ -3265,13 +3265,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
         assert(other);
 
         /* Filter out invocations with bogus state */
-        if (!IN_SET(other->load_state,
-                    UNIT_LOADED,
-                    UNIT_NOT_FOUND,
-                    UNIT_BAD_SETTING,
-                    UNIT_ERROR,
-                    UNIT_MASKED) || other->type != UNIT_SERVICE)
-                return;
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
+        assert(other->type == UNIT_SERVICE);
 
         /* Don't propagate state changes from the service if we are already down */
         if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING))
index 03a9c14f766a8e72035de2dcaf8e518a4a55b6e4..94388f0727ffbe4ebd201e2e462b43ed3edbd0b7 100644 (file)
@@ -746,8 +746,8 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
         assert(u);
         assert(other);
 
-        if (other->load_state != UNIT_LOADED)
-                return;
+        /* Filter out invocations with bogus state */
+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
 
         /* Reenable all timers that depend on unit state */
         LIST_FOREACH(value, v, t->values)
index 6cf305f4b50cccd4609f0719a44a4d1dc152530d..f4cdbfe6f5d823573b36842af31704c341827d2b 100644 (file)
@@ -938,7 +938,7 @@ int transaction_add_job_and_dependencies(
 
         /* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set
          * temporarily. */
-        if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_MASKED))
+        if (!UNIT_IS_LOAD_COMPLETE(unit->load_state))
                 return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
 
         if (type != JOB_STOP) {
index 2205b7b1637f4df2e021c5ba169edf2ba85d748d..35873d57bc341c89dbe6bb3ec5db9187cfa2be9a 100644 (file)
@@ -49,6 +49,10 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
         return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED);
 }
 
+static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) {
+        return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED;
+}
+
 /* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
  * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
  * created as a result of multiple "reasons", hence the bitmask. */