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