diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:35:18 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:35:18 +0000 |
commit | b750101eb236130cf056c675997decbac904cc49 (patch) | |
tree | a5df1a06754bdd014cb975c051c83b01c9a97532 /src/core/unit-dependency-atom.c | |
parent | Initial commit. (diff) | |
download | systemd-b750101eb236130cf056c675997decbac904cc49.tar.xz systemd-b750101eb236130cf056c675997decbac904cc49.zip |
Adding upstream version 252.22.upstream/252.22
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/core/unit-dependency-atom.c')
-rw-r--r-- | src/core/unit-dependency-atom.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/core/unit-dependency-atom.c b/src/core/unit-dependency-atom.c new file mode 100644 index 0000000..8133352 --- /dev/null +++ b/src/core/unit-dependency-atom.c @@ -0,0 +1,246 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "unit-dependency-atom.h" + +static const UnitDependencyAtom atom_map[_UNIT_DEPENDENCY_MAX] = { + /* A table that maps high-level dependency types to low-level dependency "atoms". The latter actually + * describe specific facets of dependency behaviour. The former combine them into one user-facing + * concept. Atoms are a bit mask, though a bunch of dependency types have only a single bit set. + * + * Typically when the user configures a dependency they go via dependency type, but when we act on + * them we go by atom. + * + * NB: when you add a new dependency type here, make sure to also add one to the (best-effort) + * reverse table in unit_dependency_from_unique_atom() further down. */ + + [UNIT_REQUIRES] = UNIT_ATOM_PULL_IN_START | + UNIT_ATOM_RETROACTIVE_START_REPLACE | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE, + + [UNIT_REQUISITE] = UNIT_ATOM_PULL_IN_VERIFY | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE, + + [UNIT_WANTS] = UNIT_ATOM_PULL_IN_START_IGNORED | + UNIT_ATOM_RETROACTIVE_START_FAIL | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE, + + [UNIT_BINDS_TO] = UNIT_ATOM_PULL_IN_START | + UNIT_ATOM_RETROACTIVE_START_REPLACE | + UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE, + + [UNIT_PART_OF] = UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE, + + [UNIT_UPHOLDS] = UNIT_ATOM_PULL_IN_START_IGNORED | + UNIT_ATOM_RETROACTIVE_START_REPLACE | + UNIT_ATOM_ADD_START_WHEN_UPHELD_QUEUE | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE, + + [UNIT_REQUIRED_BY] = UNIT_ATOM_PROPAGATE_STOP | + UNIT_ATOM_PROPAGATE_RESTART | + UNIT_ATOM_PROPAGATE_START_FAILURE | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED | + UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES, + + [UNIT_REQUISITE_OF] = UNIT_ATOM_PROPAGATE_STOP | + UNIT_ATOM_PROPAGATE_RESTART | + UNIT_ATOM_PROPAGATE_START_FAILURE | + UNIT_ATOM_PROPAGATE_INACTIVE_START_AS_FAILURE | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED | + UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES, + + [UNIT_WANTED_BY] = UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED, + + [UNIT_BOUND_BY] = UNIT_ATOM_RETROACTIVE_STOP_ON_STOP | + UNIT_ATOM_PROPAGATE_STOP | + UNIT_ATOM_PROPAGATE_RESTART | + UNIT_ATOM_PROPAGATE_START_FAILURE | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED | + UNIT_ATOM_ADD_CANNOT_BE_ACTIVE_WITHOUT_QUEUE | + UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES, + + [UNIT_UPHELD_BY] = UNIT_ATOM_START_STEADILY | + UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED, + + [UNIT_CONSISTS_OF] = UNIT_ATOM_PROPAGATE_STOP | + UNIT_ATOM_PROPAGATE_RESTART, + + [UNIT_CONFLICTS] = UNIT_ATOM_PULL_IN_STOP | + UNIT_ATOM_RETROACTIVE_STOP_ON_START, + + [UNIT_CONFLICTED_BY] = UNIT_ATOM_PULL_IN_STOP_IGNORED | + UNIT_ATOM_RETROACTIVE_STOP_ON_START | + UNIT_ATOM_PROPAGATE_STOP_FAILURE, + + [UNIT_PROPAGATES_STOP_TO] = UNIT_ATOM_RETROACTIVE_STOP_ON_STOP | + UNIT_ATOM_PROPAGATE_STOP, + + /* These are simple dependency types: they consist of a single atom only */ + [UNIT_ON_FAILURE] = UNIT_ATOM_ON_FAILURE, + [UNIT_ON_SUCCESS] = UNIT_ATOM_ON_SUCCESS, + [UNIT_ON_FAILURE_OF] = UNIT_ATOM_ON_FAILURE_OF, + [UNIT_ON_SUCCESS_OF] = UNIT_ATOM_ON_SUCCESS_OF, + [UNIT_BEFORE] = UNIT_ATOM_BEFORE, + [UNIT_AFTER] = UNIT_ATOM_AFTER, + [UNIT_TRIGGERS] = UNIT_ATOM_TRIGGERS, + [UNIT_TRIGGERED_BY] = UNIT_ATOM_TRIGGERED_BY, + [UNIT_PROPAGATES_RELOAD_TO] = UNIT_ATOM_PROPAGATES_RELOAD_TO, + [UNIT_JOINS_NAMESPACE_OF] = UNIT_ATOM_JOINS_NAMESPACE_OF, + [UNIT_REFERENCES] = UNIT_ATOM_REFERENCES, + [UNIT_REFERENCED_BY] = UNIT_ATOM_REFERENCED_BY, + [UNIT_IN_SLICE] = UNIT_ATOM_IN_SLICE, + [UNIT_SLICE_OF] = UNIT_ATOM_SLICE_OF, + + /* These are dependency types without effect on our state engine. We maintain them only to make + * things discoverable/debuggable as they are the inverse dependencies to some of the above. As they + * have no effect of their own, they all map to no atoms at all, i.e. the value 0. */ + [UNIT_RELOAD_PROPAGATED_FROM] = 0, + [UNIT_STOP_PROPAGATED_FROM] = 0, +}; + +UnitDependencyAtom unit_dependency_to_atom(UnitDependency d) { + if (d < 0) + return _UNIT_DEPENDENCY_ATOM_INVALID; + + assert(d < _UNIT_DEPENDENCY_MAX); + + return atom_map[d]; +} + +UnitDependency unit_dependency_from_unique_atom(UnitDependencyAtom atom) { + + /* This is a "best-effort" function that maps the specified 'atom' mask to a dependency type that is + * is equal to or has a superset of bits set if that's uniquely possible. The idea is that this + * function is used when iterating through deps that have a specific atom: if there's exactly one + * dependency type of the specific atom we don't need iterate through all deps a unit has, but can + * pinpoint things directly. + * + * This function will return _UNIT_DEPENDENCY_INVALID in case the specified value is not known or not + * uniquely defined, i.e. there are multiple dependencies with the atom or the combination set. */ + + switch ((int64_t) atom) { + + /* Note that we can't list UNIT_REQUIRES here since it's a true subset of UNIT_BINDS_TO, and + * hence its atom bits not uniquely mappable. */ + + case UNIT_ATOM_PULL_IN_VERIFY | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE: + case UNIT_ATOM_PULL_IN_VERIFY: /* a single dep type uses this atom */ + return UNIT_REQUISITE; + + case UNIT_ATOM_PULL_IN_START_IGNORED | + UNIT_ATOM_RETROACTIVE_START_FAIL | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE: + case UNIT_ATOM_RETROACTIVE_START_FAIL: + return UNIT_WANTS; + + case UNIT_ATOM_PULL_IN_START | + UNIT_ATOM_RETROACTIVE_START_REPLACE | + UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE: + case UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT: + return UNIT_BINDS_TO; + + case UNIT_ATOM_PULL_IN_START_IGNORED | + UNIT_ATOM_RETROACTIVE_START_REPLACE | + UNIT_ATOM_ADD_START_WHEN_UPHELD_QUEUE | + UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE | + UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE: + case UNIT_ATOM_ADD_START_WHEN_UPHELD_QUEUE: + return UNIT_UPHOLDS; + + case UNIT_ATOM_PROPAGATE_STOP | + UNIT_ATOM_PROPAGATE_RESTART | + UNIT_ATOM_PROPAGATE_START_FAILURE | + UNIT_ATOM_PROPAGATE_INACTIVE_START_AS_FAILURE | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED | + UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES: + case UNIT_ATOM_PROPAGATE_INACTIVE_START_AS_FAILURE: + return UNIT_REQUISITE_OF; + + case UNIT_ATOM_RETROACTIVE_STOP_ON_STOP | + UNIT_ATOM_PROPAGATE_STOP | + UNIT_ATOM_PROPAGATE_RESTART | + UNIT_ATOM_PROPAGATE_START_FAILURE | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED | + UNIT_ATOM_ADD_CANNOT_BE_ACTIVE_WITHOUT_QUEUE | + UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES: + case UNIT_ATOM_ADD_CANNOT_BE_ACTIVE_WITHOUT_QUEUE: + return UNIT_BOUND_BY; + + case UNIT_ATOM_START_STEADILY | + UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES | + UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED: + case UNIT_ATOM_START_STEADILY: + return UNIT_UPHELD_BY; + + case UNIT_ATOM_PULL_IN_STOP | + UNIT_ATOM_RETROACTIVE_STOP_ON_START: + case UNIT_ATOM_PULL_IN_STOP: + return UNIT_CONFLICTS; + + case UNIT_ATOM_PULL_IN_STOP_IGNORED | + UNIT_ATOM_RETROACTIVE_STOP_ON_START | + UNIT_ATOM_PROPAGATE_STOP_FAILURE: + case UNIT_ATOM_PULL_IN_STOP_IGNORED: + case UNIT_ATOM_PROPAGATE_STOP_FAILURE: + return UNIT_CONFLICTED_BY; + + /* And now, the simple ones */ + + case UNIT_ATOM_ON_FAILURE: + return UNIT_ON_FAILURE; + + case UNIT_ATOM_ON_SUCCESS: + return UNIT_ON_SUCCESS; + + case UNIT_ATOM_ON_SUCCESS_OF: + return UNIT_ON_SUCCESS_OF; + + case UNIT_ATOM_ON_FAILURE_OF: + return UNIT_ON_FAILURE_OF; + + case UNIT_ATOM_BEFORE: + return UNIT_BEFORE; + + case UNIT_ATOM_AFTER: + return UNIT_AFTER; + + case UNIT_ATOM_TRIGGERS: + return UNIT_TRIGGERS; + + case UNIT_ATOM_TRIGGERED_BY: + return UNIT_TRIGGERED_BY; + + case UNIT_ATOM_PROPAGATES_RELOAD_TO: + return UNIT_PROPAGATES_RELOAD_TO; + + case UNIT_ATOM_JOINS_NAMESPACE_OF: + return UNIT_JOINS_NAMESPACE_OF; + + case UNIT_ATOM_REFERENCES: + return UNIT_REFERENCES; + + case UNIT_ATOM_REFERENCED_BY: + return UNIT_REFERENCED_BY; + + case UNIT_ATOM_IN_SLICE: + return UNIT_IN_SLICE; + + case UNIT_ATOM_SLICE_OF: + return UNIT_SLICE_OF; + + default: + return _UNIT_DEPENDENCY_INVALID; + } +} |