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