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