1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "unit-dependency-atom.h"
5 static const UnitDependencyAtom atom_map
[_UNIT_DEPENDENCY_MAX
] = {
6 /* A table that maps high-level dependency types to low-level dependency "atoms". The latter actually
7 * describe specific facets of dependency behaviour. The former combine them into one user-facing
8 * concept. Atoms are a bit mask, though a bunch of dependency types have only a single bit set.
10 * Typically when the user configures a dependency they go via dependency type, but when we act on
13 * NB: when you add a new dependency type here, make sure to also add one to the (best-effort)
14 * reverse table in unit_dependency_from_unique_atom() further down. */
16 [UNIT_REQUIRES
] = UNIT_ATOM_PULL_IN_START
|
17 UNIT_ATOM_RETROACTIVE_START_REPLACE
|
18 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
19 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
,
21 [UNIT_REQUISITE
] = UNIT_ATOM_PULL_IN_VERIFY
|
22 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
23 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
,
25 [UNIT_WANTS
] = UNIT_ATOM_PULL_IN_START_IGNORED
|
26 UNIT_ATOM_RETROACTIVE_START_FAIL
|
27 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
28 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
,
30 [UNIT_BINDS_TO
] = UNIT_ATOM_PULL_IN_START
|
31 UNIT_ATOM_RETROACTIVE_START_REPLACE
|
32 UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT
|
33 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
34 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
,
36 [UNIT_PART_OF
] = UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
,
38 [UNIT_UPHOLDS
] = UNIT_ATOM_PULL_IN_START_IGNORED
|
39 UNIT_ATOM_RETROACTIVE_START_REPLACE
|
40 UNIT_ATOM_ADD_START_WHEN_UPHELD_QUEUE
|
41 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
42 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
,
44 [UNIT_REQUIRED_BY
] = UNIT_ATOM_PROPAGATE_STOP
|
45 UNIT_ATOM_PROPAGATE_RESTART
|
46 UNIT_ATOM_PROPAGATE_START_FAILURE
|
47 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
|
48 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
,
50 [UNIT_REQUISITE_OF
] = UNIT_ATOM_PROPAGATE_STOP
|
51 UNIT_ATOM_PROPAGATE_RESTART
|
52 UNIT_ATOM_PROPAGATE_START_FAILURE
|
53 UNIT_ATOM_PROPAGATE_INACTIVE_START_AS_FAILURE
|
54 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
|
55 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
,
57 [UNIT_WANTED_BY
] = UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
|
58 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
,
60 [UNIT_BOUND_BY
] = UNIT_ATOM_RETROACTIVE_STOP_ON_STOP
|
61 UNIT_ATOM_PROPAGATE_STOP
|
62 UNIT_ATOM_PROPAGATE_RESTART
|
63 UNIT_ATOM_PROPAGATE_START_FAILURE
|
64 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
|
65 UNIT_ATOM_ADD_CANNOT_BE_ACTIVE_WITHOUT_QUEUE
|
66 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
,
68 [UNIT_UPHELD_BY
] = UNIT_ATOM_START_STEADILY
|
69 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
|
70 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
,
72 [UNIT_CONSISTS_OF
] = UNIT_ATOM_PROPAGATE_STOP
|
73 UNIT_ATOM_PROPAGATE_RESTART
,
75 [UNIT_CONFLICTS
] = UNIT_ATOM_PULL_IN_STOP
|
76 UNIT_ATOM_RETROACTIVE_STOP_ON_START
,
78 [UNIT_CONFLICTED_BY
] = UNIT_ATOM_PULL_IN_STOP_IGNORED
|
79 UNIT_ATOM_RETROACTIVE_STOP_ON_START
|
80 UNIT_ATOM_PROPAGATE_STOP_FAILURE
,
82 [UNIT_PROPAGATES_STOP_TO
] = UNIT_ATOM_RETROACTIVE_STOP_ON_STOP
|
83 UNIT_ATOM_PROPAGATE_STOP_GRACEFUL
,
85 /* These are simple dependency types: they consist of a single atom only */
86 [UNIT_ON_FAILURE
] = UNIT_ATOM_ON_FAILURE
,
87 [UNIT_ON_SUCCESS
] = UNIT_ATOM_ON_SUCCESS
,
88 [UNIT_ON_FAILURE_OF
] = UNIT_ATOM_ON_FAILURE_OF
,
89 [UNIT_ON_SUCCESS_OF
] = UNIT_ATOM_ON_SUCCESS_OF
,
90 [UNIT_BEFORE
] = UNIT_ATOM_BEFORE
,
91 [UNIT_AFTER
] = UNIT_ATOM_AFTER
,
92 [UNIT_TRIGGERS
] = UNIT_ATOM_TRIGGERS
,
93 [UNIT_TRIGGERED_BY
] = UNIT_ATOM_TRIGGERED_BY
,
94 [UNIT_PROPAGATES_RELOAD_TO
] = UNIT_ATOM_PROPAGATES_RELOAD_TO
,
95 [UNIT_JOINS_NAMESPACE_OF
] = UNIT_ATOM_JOINS_NAMESPACE_OF
,
96 [UNIT_REFERENCES
] = UNIT_ATOM_REFERENCES
,
97 [UNIT_REFERENCED_BY
] = UNIT_ATOM_REFERENCED_BY
,
98 [UNIT_IN_SLICE
] = UNIT_ATOM_IN_SLICE
,
99 [UNIT_SLICE_OF
] = UNIT_ATOM_SLICE_OF
,
101 /* These are dependency types without effect on our state engine. We maintain them only to make
102 * things discoverable/debuggable as they are the inverse dependencies to some of the above. As they
103 * have no effect of their own, they all map to no atoms at all, i.e. the value 0. */
104 [UNIT_RELOAD_PROPAGATED_FROM
] = 0,
105 [UNIT_STOP_PROPAGATED_FROM
] = 0,
108 UnitDependencyAtom
unit_dependency_to_atom(UnitDependency d
) {
110 return _UNIT_DEPENDENCY_ATOM_INVALID
;
112 assert(d
< _UNIT_DEPENDENCY_MAX
);
117 UnitDependency
unit_dependency_from_unique_atom(UnitDependencyAtom atom
) {
119 /* This is a "best-effort" function that maps the specified 'atom' mask to a dependency type that is
120 * is equal to or has a superset of bits set if that's uniquely possible. The idea is that this
121 * function is used when iterating through deps that have a specific atom: if there's exactly one
122 * dependency type of the specific atom we don't need iterate through all deps a unit has, but can
123 * pinpoint things directly.
125 * This function will return _UNIT_DEPENDENCY_INVALID in case the specified value is not known or not
126 * uniquely defined, i.e. there are multiple dependencies with the atom or the combination set. */
128 switch ((int64_t) atom
) {
130 /* Note that we can't list UNIT_REQUIRES here since it's a true subset of UNIT_BINDS_TO, and
131 * hence its atom bits not uniquely mappable. */
133 case UNIT_ATOM_PULL_IN_VERIFY
|
134 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
135 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
:
136 case UNIT_ATOM_PULL_IN_VERIFY
: /* a single dep type uses this atom */
137 return UNIT_REQUISITE
;
139 case UNIT_ATOM_PULL_IN_START_IGNORED
|
140 UNIT_ATOM_RETROACTIVE_START_FAIL
|
141 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
142 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
:
143 case UNIT_ATOM_RETROACTIVE_START_FAIL
:
146 case UNIT_ATOM_PULL_IN_START
|
147 UNIT_ATOM_RETROACTIVE_START_REPLACE
|
148 UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT
|
149 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
150 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
:
151 case UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT
:
152 return UNIT_BINDS_TO
;
154 case UNIT_ATOM_PULL_IN_START_IGNORED
|
155 UNIT_ATOM_RETROACTIVE_START_REPLACE
|
156 UNIT_ATOM_ADD_START_WHEN_UPHELD_QUEUE
|
157 UNIT_ATOM_ADD_STOP_WHEN_UNNEEDED_QUEUE
|
158 UNIT_ATOM_ADD_DEFAULT_TARGET_DEPENDENCY_QUEUE
:
159 case UNIT_ATOM_ADD_START_WHEN_UPHELD_QUEUE
:
162 case UNIT_ATOM_PROPAGATE_STOP
|
163 UNIT_ATOM_PROPAGATE_RESTART
|
164 UNIT_ATOM_PROPAGATE_START_FAILURE
|
165 UNIT_ATOM_PROPAGATE_INACTIVE_START_AS_FAILURE
|
166 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
|
167 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
:
168 case UNIT_ATOM_PROPAGATE_INACTIVE_START_AS_FAILURE
:
169 return UNIT_REQUISITE_OF
;
171 case UNIT_ATOM_RETROACTIVE_STOP_ON_STOP
|
172 UNIT_ATOM_PROPAGATE_STOP
|
173 UNIT_ATOM_PROPAGATE_RESTART
|
174 UNIT_ATOM_PROPAGATE_START_FAILURE
|
175 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
|
176 UNIT_ATOM_ADD_CANNOT_BE_ACTIVE_WITHOUT_QUEUE
|
177 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
:
178 case UNIT_ATOM_ADD_CANNOT_BE_ACTIVE_WITHOUT_QUEUE
:
179 return UNIT_BOUND_BY
;
181 case UNIT_ATOM_START_STEADILY
|
182 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES
|
183 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED
:
184 case UNIT_ATOM_START_STEADILY
:
185 return UNIT_UPHELD_BY
;
187 case UNIT_ATOM_PULL_IN_STOP
|
188 UNIT_ATOM_RETROACTIVE_STOP_ON_START
:
189 case UNIT_ATOM_PULL_IN_STOP
:
190 return UNIT_CONFLICTS
;
192 case UNIT_ATOM_PULL_IN_STOP_IGNORED
|
193 UNIT_ATOM_RETROACTIVE_STOP_ON_START
|
194 UNIT_ATOM_PROPAGATE_STOP_FAILURE
:
195 case UNIT_ATOM_PULL_IN_STOP_IGNORED
:
196 case UNIT_ATOM_PROPAGATE_STOP_FAILURE
:
197 return UNIT_CONFLICTED_BY
;
199 case UNIT_ATOM_RETROACTIVE_STOP_ON_STOP
|
200 UNIT_ATOM_PROPAGATE_STOP_GRACEFUL
:
201 case UNIT_ATOM_PROPAGATE_STOP_GRACEFUL
:
202 return UNIT_PROPAGATES_STOP_TO
;
204 /* And now, the simple ones */
206 case UNIT_ATOM_ON_FAILURE
:
207 return UNIT_ON_FAILURE
;
209 case UNIT_ATOM_ON_SUCCESS
:
210 return UNIT_ON_SUCCESS
;
212 case UNIT_ATOM_ON_SUCCESS_OF
:
213 return UNIT_ON_SUCCESS_OF
;
215 case UNIT_ATOM_ON_FAILURE_OF
:
216 return UNIT_ON_FAILURE_OF
;
218 case UNIT_ATOM_BEFORE
:
221 case UNIT_ATOM_AFTER
:
224 case UNIT_ATOM_TRIGGERS
:
225 return UNIT_TRIGGERS
;
227 case UNIT_ATOM_TRIGGERED_BY
:
228 return UNIT_TRIGGERED_BY
;
230 case UNIT_ATOM_PROPAGATES_RELOAD_TO
:
231 return UNIT_PROPAGATES_RELOAD_TO
;
233 case UNIT_ATOM_JOINS_NAMESPACE_OF
:
234 return UNIT_JOINS_NAMESPACE_OF
;
236 case UNIT_ATOM_REFERENCES
:
237 return UNIT_REFERENCES
;
239 case UNIT_ATOM_REFERENCED_BY
:
240 return UNIT_REFERENCED_BY
;
242 case UNIT_ATOM_IN_SLICE
:
243 return UNIT_IN_SLICE
;
245 case UNIT_ATOM_SLICE_OF
:
246 return UNIT_SLICE_OF
;
249 return _UNIT_DEPENDENCY_INVALID
;