core: propagate triggered unit in more load states

In 4c2ef32767 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.
This commit is contained in:
Lennart Poettering 2020-09-11 19:49:33 +02:00
parent 415f8a5bfe
commit 0377cd2936
6 changed files with 14 additions and 16 deletions

View 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))

View 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))) {

View 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))

View 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)

View 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) {

View 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. */