mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
245 lines
11 KiB
C
245 lines
11 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include "unit-def.h"
|
|
#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_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_START_FAILURE |
|
|
UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED |
|
|
UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES,
|
|
|
|
[UNIT_REQUISITE_OF] = UNIT_ATOM_PROPAGATE_STOP |
|
|
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_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_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_GRACEFUL,
|
|
|
|
/* 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_PART_OF] = UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE,
|
|
[UNIT_CONSISTS_OF] = UNIT_ATOM_PROPAGATE_STOP,
|
|
[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_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_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;
|
|
|
|
case UNIT_ATOM_RETROACTIVE_STOP_ON_STOP |
|
|
UNIT_ATOM_PROPAGATE_STOP_GRACEFUL:
|
|
case UNIT_ATOM_PROPAGATE_STOP_GRACEFUL:
|
|
return UNIT_PROPAGATES_STOP_TO;
|
|
|
|
/* 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;
|
|
}
|
|
}
|