]>
Commit | Line | Data |
---|---|---|
663996b3 MS |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
3 | #pragma once | |
4 | ||
5 | /*** | |
6 | This file is part of systemd. | |
7 | ||
8 | Copyright 2010 Lennart Poettering | |
9 | ||
10 | systemd is free software; you can redistribute it and/or modify it | |
11 | under the terms of the GNU Lesser General Public License as published by | |
12 | the Free Software Foundation; either version 2.1 of the License, or | |
13 | (at your option) any later version. | |
14 | ||
15 | systemd is distributed in the hope that it will be useful, but | |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 | Lesser General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU Lesser General Public License | |
21 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
22 | ***/ | |
23 | ||
24 | #include <stdbool.h> | |
25 | #include <stdlib.h> | |
26 | #include <unistd.h> | |
27 | ||
28 | typedef struct Unit Unit; | |
29 | typedef struct UnitVTable UnitVTable; | |
30 | typedef enum UnitActiveState UnitActiveState; | |
31 | typedef enum UnitDependency UnitDependency; | |
32 | typedef struct UnitRef UnitRef; | |
33 | typedef struct UnitStatusMessageFormats UnitStatusMessageFormats; | |
34 | ||
35 | #include "set.h" | |
36 | #include "util.h" | |
37 | #include "list.h" | |
38 | #include "socket-util.h" | |
39 | #include "execute.h" | |
14228c0d | 40 | #include "cgroup.h" |
663996b3 MS |
41 | #include "condition.h" |
42 | #include "install.h" | |
43 | #include "unit-name.h" | |
663996b3 MS |
44 | |
45 | enum UnitActiveState { | |
46 | UNIT_ACTIVE, | |
47 | UNIT_RELOADING, | |
48 | UNIT_INACTIVE, | |
49 | UNIT_FAILED, | |
50 | UNIT_ACTIVATING, | |
51 | UNIT_DEACTIVATING, | |
52 | _UNIT_ACTIVE_STATE_MAX, | |
53 | _UNIT_ACTIVE_STATE_INVALID = -1 | |
54 | }; | |
55 | ||
56 | static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) { | |
57 | return t == UNIT_ACTIVE || t == UNIT_RELOADING; | |
58 | } | |
59 | ||
60 | static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) { | |
61 | return t == UNIT_ACTIVE || t == UNIT_ACTIVATING || t == UNIT_RELOADING; | |
62 | } | |
63 | ||
64 | static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) { | |
65 | return t == UNIT_INACTIVE || t == UNIT_FAILED || t == UNIT_DEACTIVATING; | |
66 | } | |
67 | ||
68 | static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) { | |
69 | return t == UNIT_INACTIVE || t == UNIT_FAILED; | |
70 | } | |
71 | ||
72 | enum UnitDependency { | |
73 | /* Positive dependencies */ | |
74 | UNIT_REQUIRES, | |
75 | UNIT_REQUIRES_OVERRIDABLE, | |
76 | UNIT_REQUISITE, | |
77 | UNIT_REQUISITE_OVERRIDABLE, | |
78 | UNIT_WANTS, | |
79 | UNIT_BINDS_TO, | |
80 | UNIT_PART_OF, | |
81 | ||
82 | /* Inverse of the above */ | |
83 | UNIT_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */ | |
84 | UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */ | |
85 | UNIT_WANTED_BY, /* inverse of 'wants' */ | |
86 | UNIT_BOUND_BY, /* inverse of 'binds_to' */ | |
87 | UNIT_CONSISTS_OF, /* inverse of 'part_of' */ | |
88 | ||
89 | /* Negative dependencies */ | |
90 | UNIT_CONFLICTS, /* inverse of 'conflicts' is 'conflicted_by' */ | |
91 | UNIT_CONFLICTED_BY, | |
92 | ||
93 | /* Order */ | |
94 | UNIT_BEFORE, /* inverse of 'before' is 'after' and vice versa */ | |
95 | UNIT_AFTER, | |
96 | ||
97 | /* On Failure */ | |
98 | UNIT_ON_FAILURE, | |
99 | ||
100 | /* Triggers (i.e. a socket triggers a service) */ | |
101 | UNIT_TRIGGERS, | |
102 | UNIT_TRIGGERED_BY, | |
103 | ||
104 | /* Propagate reloads */ | |
105 | UNIT_PROPAGATES_RELOAD_TO, | |
106 | UNIT_RELOAD_PROPAGATED_FROM, | |
107 | ||
108 | /* Reference information for GC logic */ | |
109 | UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */ | |
110 | UNIT_REFERENCED_BY, | |
111 | ||
112 | _UNIT_DEPENDENCY_MAX, | |
113 | _UNIT_DEPENDENCY_INVALID = -1 | |
114 | }; | |
115 | ||
116 | #include "manager.h" | |
117 | #include "job.h" | |
14228c0d MB |
118 | |
119 | struct UnitRef { | |
120 | /* Keeps tracks of references to a unit. This is useful so | |
121 | * that we can merge two units if necessary and correct all | |
122 | * references to them */ | |
123 | ||
124 | Unit* unit; | |
125 | LIST_FIELDS(UnitRef, refs); | |
126 | }; | |
663996b3 MS |
127 | |
128 | struct Unit { | |
129 | Manager *manager; | |
130 | ||
131 | UnitType type; | |
132 | UnitLoadState load_state; | |
133 | Unit *merged_into; | |
134 | ||
135 | char *id; /* One name is special because we use it for identification. Points to an entry in the names set */ | |
136 | char *instance; | |
137 | ||
138 | Set *names; | |
139 | Set *dependencies[_UNIT_DEPENDENCY_MAX]; | |
140 | ||
141 | char **requires_mounts_for; | |
142 | ||
143 | char *description; | |
144 | char **documentation; | |
145 | ||
146 | char *fragment_path; /* if loaded from a config file this is the primary path to it */ | |
147 | char *source_path; /* if converted, the source file */ | |
148 | char **dropin_paths; | |
149 | usec_t fragment_mtime; | |
150 | usec_t source_mtime; | |
151 | usec_t dropin_mtime; | |
152 | ||
153 | /* If there is something to do with this unit, then this is the installed job for it */ | |
154 | Job *job; | |
155 | ||
156 | /* JOB_NOP jobs are special and can be installed without disturbing the real job. */ | |
157 | Job *nop_job; | |
158 | ||
159 | usec_t job_timeout; | |
160 | ||
161 | /* References to this */ | |
162 | LIST_HEAD(UnitRef, refs); | |
163 | ||
164 | /* Conditions to check */ | |
165 | LIST_HEAD(Condition, conditions); | |
166 | ||
167 | dual_timestamp condition_timestamp; | |
168 | ||
169 | dual_timestamp inactive_exit_timestamp; | |
170 | dual_timestamp active_enter_timestamp; | |
171 | dual_timestamp active_exit_timestamp; | |
172 | dual_timestamp inactive_enter_timestamp; | |
173 | ||
174 | /* Counterparts in the cgroup filesystem */ | |
14228c0d MB |
175 | char *cgroup_path; |
176 | CGroupControllerMask cgroup_mask; | |
177 | ||
178 | UnitRef slice; | |
663996b3 MS |
179 | |
180 | /* Per type list */ | |
181 | LIST_FIELDS(Unit, units_by_type); | |
182 | ||
183 | /* All units which have requires_mounts_for set */ | |
184 | LIST_FIELDS(Unit, has_requires_mounts_for); | |
185 | ||
186 | /* Load queue */ | |
187 | LIST_FIELDS(Unit, load_queue); | |
188 | ||
189 | /* D-Bus queue */ | |
190 | LIST_FIELDS(Unit, dbus_queue); | |
191 | ||
192 | /* Cleanup queue */ | |
193 | LIST_FIELDS(Unit, cleanup_queue); | |
194 | ||
195 | /* GC queue */ | |
196 | LIST_FIELDS(Unit, gc_queue); | |
197 | ||
14228c0d MB |
198 | /* CGroup realize members queue */ |
199 | LIST_FIELDS(Unit, cgroup_queue); | |
200 | ||
663996b3 MS |
201 | /* Used during GC sweeps */ |
202 | unsigned gc_marker; | |
203 | ||
204 | /* When deserializing, temporarily store the job type for this | |
205 | * unit here, if there was a job scheduled. | |
206 | * Only for deserializing from a legacy version. New style uses full | |
207 | * serialized jobs. */ | |
208 | int deserialized_job; /* This is actually of type JobType */ | |
209 | ||
210 | /* Error code when we didn't manage to load the unit (negative) */ | |
211 | int load_error; | |
212 | ||
213 | /* Cached unit file state */ | |
214 | UnitFileState unit_file_state; | |
215 | ||
216 | /* Garbage collect us we nobody wants or requires us anymore */ | |
217 | bool stop_when_unneeded; | |
218 | ||
219 | /* Create default dependencies */ | |
220 | bool default_dependencies; | |
221 | ||
222 | /* Refuse manual starting, allow starting only indirectly via dependency. */ | |
223 | bool refuse_manual_start; | |
224 | ||
225 | /* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */ | |
226 | bool refuse_manual_stop; | |
227 | ||
228 | /* Allow isolation requests */ | |
229 | bool allow_isolate; | |
230 | ||
231 | /* Isolate OnFailure unit */ | |
232 | bool on_failure_isolate; | |
233 | ||
234 | /* Ignore this unit when isolating */ | |
235 | bool ignore_on_isolate; | |
236 | ||
237 | /* Ignore this unit when snapshotting */ | |
238 | bool ignore_on_snapshot; | |
239 | ||
240 | /* Did the last condition check succeed? */ | |
241 | bool condition_result; | |
242 | ||
14228c0d MB |
243 | /* Is this a transient unit? */ |
244 | bool transient; | |
245 | ||
663996b3 MS |
246 | bool in_load_queue:1; |
247 | bool in_dbus_queue:1; | |
248 | bool in_cleanup_queue:1; | |
249 | bool in_gc_queue:1; | |
14228c0d | 250 | bool in_cgroup_queue:1; |
663996b3 MS |
251 | |
252 | bool sent_dbus_new_signal:1; | |
253 | ||
254 | bool no_gc:1; | |
255 | ||
256 | bool in_audit:1; | |
663996b3 | 257 | |
14228c0d | 258 | bool cgroup_realized:1; |
663996b3 MS |
259 | }; |
260 | ||
261 | struct UnitStatusMessageFormats { | |
262 | const char *starting_stopping[2]; | |
263 | const char *finished_start_job[_JOB_RESULT_MAX]; | |
264 | const char *finished_stop_job[_JOB_RESULT_MAX]; | |
265 | }; | |
266 | ||
14228c0d MB |
267 | typedef enum UnitSetPropertiesMode { |
268 | UNIT_CHECK = 0, | |
269 | UNIT_RUNTIME = 1, | |
270 | UNIT_PERSISTENT = 2, | |
271 | } UnitSetPropertiesMode; | |
272 | ||
663996b3 MS |
273 | #include "service.h" |
274 | #include "timer.h" | |
275 | #include "socket.h" | |
276 | #include "target.h" | |
277 | #include "device.h" | |
278 | #include "mount.h" | |
279 | #include "automount.h" | |
280 | #include "snapshot.h" | |
281 | #include "swap.h" | |
282 | #include "path.h" | |
14228c0d MB |
283 | #include "slice.h" |
284 | #include "scope.h" | |
663996b3 MS |
285 | |
286 | struct UnitVTable { | |
287 | /* How much memory does an object of this unit type need */ | |
288 | size_t object_size; | |
289 | ||
290 | /* If greater than 0, the offset into the object where | |
291 | * ExecContext is found, if the unit type has that */ | |
292 | size_t exec_context_offset; | |
293 | ||
14228c0d MB |
294 | /* If greater than 0, the offset into the object where |
295 | * CGroupContext is found, if the unit type has that */ | |
296 | size_t cgroup_context_offset; | |
297 | ||
298 | /* The name of the configuration file section with the private settings of this unit*/ | |
299 | const char *private_section; | |
663996b3 MS |
300 | |
301 | /* Config file sections this unit type understands, separated | |
302 | * by NUL chars */ | |
303 | const char *sections; | |
304 | ||
305 | /* This should reset all type-specific variables. This should | |
306 | * not allocate memory, and is called with zero-initialized | |
307 | * data. It should hence only initialize variables that need | |
308 | * to be set != 0. */ | |
309 | void (*init)(Unit *u); | |
310 | ||
311 | /* This should free all type-specific variables. It should be | |
312 | * idempotent. */ | |
313 | void (*done)(Unit *u); | |
314 | ||
315 | /* Actually load data from disk. This may fail, and should set | |
316 | * load_state to UNIT_LOADED, UNIT_MERGED or leave it at | |
317 | * UNIT_STUB if no configuration could be found. */ | |
318 | int (*load)(Unit *u); | |
319 | ||
320 | /* If a lot of units got created via enumerate(), this is | |
321 | * where to actually set the state and call unit_notify(). */ | |
322 | int (*coldplug)(Unit *u); | |
323 | ||
324 | void (*dump)(Unit *u, FILE *f, const char *prefix); | |
325 | ||
326 | int (*start)(Unit *u); | |
327 | int (*stop)(Unit *u); | |
328 | int (*reload)(Unit *u); | |
329 | ||
330 | int (*kill)(Unit *u, KillWho w, int signo, DBusError *error); | |
331 | ||
332 | bool (*can_reload)(Unit *u); | |
333 | ||
334 | /* Write all data that cannot be restored from other sources | |
335 | * away using unit_serialize_item() */ | |
336 | int (*serialize)(Unit *u, FILE *f, FDSet *fds); | |
337 | ||
338 | /* Restore one item from the serialization */ | |
339 | int (*deserialize_item)(Unit *u, const char *key, const char *data, FDSet *fds); | |
340 | ||
341 | /* Try to match up fds with what we need for this unit */ | |
342 | int (*distribute_fds)(Unit *u, FDSet *fds); | |
343 | ||
344 | /* Boils down the more complex internal state of this unit to | |
345 | * a simpler one that the engine can understand */ | |
346 | UnitActiveState (*active_state)(Unit *u); | |
347 | ||
348 | /* Returns the substate specific to this unit type as | |
349 | * string. This is purely information so that we can give the | |
350 | * user a more fine grained explanation in which actual state a | |
351 | * unit is in. */ | |
352 | const char* (*sub_state_to_string)(Unit *u); | |
353 | ||
354 | /* Return true when there is reason to keep this entry around | |
355 | * even nothing references it and it isn't active in any | |
356 | * way */ | |
357 | bool (*check_gc)(Unit *u); | |
358 | ||
359 | /* Return true when this unit is suitable for snapshotting */ | |
360 | bool (*check_snapshot)(Unit *u); | |
361 | ||
362 | void (*fd_event)(Unit *u, int fd, uint32_t events, Watch *w); | |
363 | void (*sigchld_event)(Unit *u, pid_t pid, int code, int status); | |
364 | void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w); | |
365 | ||
366 | /* Reset failed state if we are in failed state */ | |
367 | void (*reset_failed)(Unit *u); | |
368 | ||
369 | /* Called whenever any of the cgroups this unit watches for | |
370 | * ran empty */ | |
14228c0d | 371 | void (*notify_cgroup_empty)(Unit *u); |
663996b3 MS |
372 | |
373 | /* Called whenever a process of this unit sends us a message */ | |
374 | void (*notify_message)(Unit *u, pid_t pid, char **tags); | |
375 | ||
376 | /* Called whenever a name this Unit registered for comes or | |
377 | * goes away. */ | |
378 | void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner); | |
379 | ||
380 | /* Called whenever a bus PID lookup finishes */ | |
381 | void (*bus_query_pid_done)(Unit *u, const char *name, pid_t pid); | |
382 | ||
383 | /* Called for each message received on the bus */ | |
384 | DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message); | |
385 | ||
14228c0d MB |
386 | /* Called for each property that is being set */ |
387 | int (*bus_set_property)(Unit *u, const char *name, DBusMessageIter *i, UnitSetPropertiesMode mode, DBusError *error); | |
388 | ||
389 | /* Called after at least one property got changed to apply the necessary change */ | |
390 | int (*bus_commit_properties)(Unit *u); | |
391 | ||
663996b3 MS |
392 | /* Return the unit this unit is following */ |
393 | Unit *(*following)(Unit *u); | |
394 | ||
395 | /* Return the set of units that are following each other */ | |
396 | int (*following_set)(Unit *u, Set **s); | |
397 | ||
398 | /* Invoked each time a unit this unit is triggering changes | |
399 | * state or gains/loses a job */ | |
400 | void (*trigger_notify)(Unit *u, Unit *trigger); | |
401 | ||
402 | /* Called whenever CLOCK_REALTIME made a jump */ | |
403 | void (*time_change)(Unit *u); | |
404 | ||
405 | /* This is called for each unit type and should be used to | |
406 | * enumerate existing devices and load them. However, | |
407 | * everything that is loaded here should still stay in | |
408 | * inactive state. It is the job of the coldplug() call above | |
409 | * to put the units into the initial state. */ | |
410 | int (*enumerate)(Manager *m); | |
411 | ||
412 | /* Type specific cleanups. */ | |
413 | void (*shutdown)(Manager *m); | |
414 | ||
415 | /* When sending out PropertiesChanged signal, which properties | |
416 | * shall be invalidated? This is a NUL separated list of | |
417 | * strings, to minimize relocations a little. */ | |
418 | const char *bus_invalidating_properties; | |
419 | ||
420 | /* The interface name */ | |
421 | const char *bus_interface; | |
422 | ||
423 | UnitStatusMessageFormats status_message_formats; | |
424 | ||
425 | /* Can units of this type have multiple names? */ | |
426 | bool no_alias:1; | |
427 | ||
428 | /* Instances make no sense for this type */ | |
429 | bool no_instances:1; | |
430 | ||
431 | /* Exclude from automatic gc */ | |
432 | bool no_gc:1; | |
14228c0d MB |
433 | |
434 | /* True if transient units of this type are OK */ | |
435 | bool can_transient:1; | |
663996b3 MS |
436 | }; |
437 | ||
438 | extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; | |
439 | ||
440 | #define UNIT_VTABLE(u) unit_vtable[(u)->type] | |
441 | ||
442 | /* For casting a unit into the various unit types */ | |
443 | #define DEFINE_CAST(UPPERCASE, MixedCase) \ | |
444 | static inline MixedCase* UPPERCASE(Unit *u) { \ | |
445 | if (_unlikely_(!u || u->type != UNIT_##UPPERCASE)) \ | |
446 | return NULL; \ | |
447 | \ | |
448 | return (MixedCase*) u; \ | |
449 | } | |
450 | ||
451 | /* For casting the various unit types into a unit */ | |
452 | #define UNIT(u) (&(u)->meta) | |
453 | ||
454 | #define UNIT_TRIGGER(u) ((Unit*) set_first((u)->dependencies[UNIT_TRIGGERS])) | |
455 | ||
456 | DEFINE_CAST(SOCKET, Socket); | |
457 | DEFINE_CAST(TIMER, Timer); | |
458 | DEFINE_CAST(SERVICE, Service); | |
459 | DEFINE_CAST(TARGET, Target); | |
460 | DEFINE_CAST(DEVICE, Device); | |
461 | DEFINE_CAST(MOUNT, Mount); | |
462 | DEFINE_CAST(AUTOMOUNT, Automount); | |
463 | DEFINE_CAST(SNAPSHOT, Snapshot); | |
464 | DEFINE_CAST(SWAP, Swap); | |
465 | DEFINE_CAST(PATH, Path); | |
14228c0d MB |
466 | DEFINE_CAST(SLICE, Slice); |
467 | DEFINE_CAST(SCOPE, Scope); | |
663996b3 MS |
468 | |
469 | Unit *unit_new(Manager *m, size_t size); | |
470 | void unit_free(Unit *u); | |
471 | ||
472 | int unit_add_name(Unit *u, const char *name); | |
473 | ||
474 | int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference); | |
475 | int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference); | |
476 | ||
477 | int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference); | |
478 | int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference); | |
479 | ||
480 | int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference); | |
481 | int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference); | |
482 | ||
483 | int unit_add_exec_dependencies(Unit *u, ExecContext *c); | |
484 | ||
663996b3 MS |
485 | int unit_choose_id(Unit *u, const char *name); |
486 | int unit_set_description(Unit *u, const char *description); | |
487 | ||
488 | bool unit_check_gc(Unit *u); | |
489 | ||
490 | void unit_add_to_load_queue(Unit *u); | |
491 | void unit_add_to_dbus_queue(Unit *u); | |
492 | void unit_add_to_cleanup_queue(Unit *u); | |
493 | void unit_add_to_gc_queue(Unit *u); | |
494 | ||
495 | int unit_merge(Unit *u, Unit *other); | |
496 | int unit_merge_by_name(Unit *u, const char *other); | |
497 | ||
498 | Unit *unit_follow_merge(Unit *u) _pure_; | |
499 | ||
500 | int unit_load_fragment_and_dropin(Unit *u); | |
501 | int unit_load_fragment_and_dropin_optional(Unit *u); | |
502 | int unit_load(Unit *unit); | |
503 | ||
14228c0d MB |
504 | int unit_add_default_slice(Unit *u); |
505 | ||
663996b3 MS |
506 | const char *unit_description(Unit *u) _pure_; |
507 | ||
508 | bool unit_has_name(Unit *u, const char *name); | |
509 | ||
510 | UnitActiveState unit_active_state(Unit *u); | |
511 | ||
512 | const char* unit_sub_state_to_string(Unit *u); | |
513 | ||
514 | void unit_dump(Unit *u, FILE *f, const char *prefix); | |
515 | ||
516 | bool unit_can_reload(Unit *u) _pure_; | |
517 | bool unit_can_start(Unit *u) _pure_; | |
518 | bool unit_can_isolate(Unit *u) _pure_; | |
519 | ||
520 | int unit_start(Unit *u); | |
521 | int unit_stop(Unit *u); | |
522 | int unit_reload(Unit *u); | |
523 | ||
524 | int unit_kill(Unit *u, KillWho w, int signo, DBusError *error); | |
525 | int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t control_pid, DBusError *error); | |
526 | ||
527 | void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success); | |
528 | ||
529 | int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w); | |
530 | void unit_unwatch_fd(Unit *u, Watch *w); | |
531 | ||
532 | int unit_watch_pid(Unit *u, pid_t pid); | |
533 | void unit_unwatch_pid(Unit *u, pid_t pid); | |
534 | ||
535 | int unit_watch_timer(Unit *u, clockid_t, bool relative, usec_t usec, Watch *w); | |
536 | void unit_unwatch_timer(Unit *u, Watch *w); | |
537 | ||
538 | int unit_watch_bus_name(Unit *u, const char *name); | |
539 | void unit_unwatch_bus_name(Unit *u, const char *name); | |
540 | ||
541 | bool unit_job_is_applicable(Unit *u, JobType j); | |
542 | ||
543 | int set_unit_path(const char *p); | |
544 | ||
545 | char *unit_dbus_path(Unit *u); | |
546 | ||
547 | int unit_load_related_unit(Unit *u, const char *type, Unit **_found); | |
548 | int unit_get_related_unit(Unit *u, const char *type, Unit **_found); | |
549 | ||
550 | bool unit_can_serialize(Unit *u) _pure_; | |
551 | int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs); | |
552 | void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr_(4,5); | |
553 | void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value); | |
554 | int unit_deserialize(Unit *u, FILE *f, FDSet *fds); | |
555 | ||
556 | int unit_add_node_link(Unit *u, const char *what, bool wants); | |
557 | ||
558 | int unit_coldplug(Unit *u); | |
559 | ||
560 | void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_attr_(3, 0); | |
561 | ||
562 | bool unit_need_daemon_reload(Unit *u); | |
563 | ||
564 | void unit_reset_failed(Unit *u); | |
565 | ||
566 | Unit *unit_following(Unit *u); | |
567 | ||
14228c0d MB |
568 | const char *unit_slice_name(Unit *u); |
569 | ||
663996b3 MS |
570 | bool unit_stop_pending(Unit *u) _pure_; |
571 | bool unit_inactive_or_pending(Unit *u) _pure_; | |
572 | bool unit_active_or_pending(Unit *u); | |
573 | ||
574 | int unit_add_default_target_dependency(Unit *u, Unit *target); | |
575 | ||
576 | char *unit_default_cgroup_path(Unit *u); | |
577 | ||
578 | int unit_following_set(Unit *u, Set **s); | |
579 | ||
580 | void unit_start_on_failure(Unit *u); | |
581 | void unit_trigger_notify(Unit *u); | |
582 | ||
583 | bool unit_condition_test(Unit *u); | |
584 | ||
585 | UnitFileState unit_get_unit_file_state(Unit *u); | |
586 | ||
587 | Unit* unit_ref_set(UnitRef *ref, Unit *u); | |
588 | void unit_ref_unset(UnitRef *ref); | |
589 | ||
590 | #define UNIT_DEREF(ref) ((ref).unit) | |
14228c0d | 591 | #define UNIT_ISSET(ref) (!!(ref).unit) |
663996b3 | 592 | |
663996b3 MS |
593 | int unit_add_mount_links(Unit *u); |
594 | ||
595 | int unit_exec_context_defaults(Unit *u, ExecContext *c); | |
596 | ||
597 | ExecContext *unit_get_exec_context(Unit *u) _pure_; | |
14228c0d | 598 | CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; |
663996b3 | 599 | |
14228c0d MB |
600 | int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); |
601 | int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_attr_(4,5); | |
602 | ||
603 | int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); | |
604 | int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_attr_(4,5); | |
605 | ||
606 | int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name); | |
663996b3 MS |
607 | |
608 | int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid_t control_pid, bool main_pid_alien); | |
609 | ||
14228c0d MB |
610 | int unit_make_transient(Unit *u); |
611 | ||
612 | int unit_require_mounts_for(Unit *u, const char *path); | |
613 | ||
663996b3 MS |
614 | const char *unit_active_state_to_string(UnitActiveState i) _const_; |
615 | UnitActiveState unit_active_state_from_string(const char *s) _pure_; | |
616 | ||
617 | const char *unit_dependency_to_string(UnitDependency i) _const_; | |
618 | UnitDependency unit_dependency_from_string(const char *s) _pure_; | |
619 | ||
620 | /* Macros which append UNIT= or USER_UNIT= to the message */ | |
621 | ||
622 | #define log_full_unit(level, unit, ...) log_meta_object(level, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__) | |
623 | #define log_debug_unit(unit, ...) log_full_unit(LOG_DEBUG, unit, __VA_ARGS__) | |
624 | #define log_info_unit(unit, ...) log_full_unit(LOG_INFO, unit, __VA_ARGS__) | |
625 | #define log_notice_unit(unit, ...) log_full_unit(LOG_NOTICE, unit, __VA_ARGS__) | |
626 | #define log_warning_unit(unit, ...) log_full_unit(LOG_WARNING, unit, __VA_ARGS__) | |
627 | #define log_error_unit(unit, ...) log_full_unit(LOG_ERR, unit, __VA_ARGS__) | |
628 | ||
629 | #define log_struct_unit(level, unit, ...) log_struct(level, getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit, __VA_ARGS__) |