]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.h
shared: FORMAT_TIMESTAMP_MAX -- include space for unicode weekdays
[thirdparty/systemd.git] / src / core / unit.h
CommitLineData
03467c88 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87f0e418 2
c2f1db8f 3#pragma once
87f0e418 4
a7334b09
LP
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
5430f7f2
LP
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
a7334b09
LP
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
5430f7f2 18 Lesser General Public License for more details.
a7334b09 19
5430f7f2 20 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22***/
23
87f0e418
LP
24#include <stdbool.h>
25#include <stdlib.h>
26
ac155bb8 27typedef struct Unit Unit;
87f0e418 28typedef struct UnitVTable UnitVTable;
87f0e418
LP
29typedef enum UnitActiveState UnitActiveState;
30typedef enum UnitDependency UnitDependency;
57020a3a 31typedef struct UnitRef UnitRef;
c6918296 32typedef struct UnitStatusMessageFormats UnitStatusMessageFormats;
87f0e418 33
87f0e418
LP
34#include "set.h"
35#include "util.h"
36#include "list.h"
37#include "socket-util.h"
38#include "execute.h"
52661efd 39#include "condition.h"
a4375746 40#include "install.h"
0a9f8ed0 41#include "unit-name.h"
87f0e418 42
87f0e418
LP
43enum UnitActiveState {
44 UNIT_ACTIVE,
032ff4af 45 UNIT_RELOADING,
87f0e418 46 UNIT_INACTIVE,
fdf20a31 47 UNIT_FAILED,
87f0e418
LP
48 UNIT_ACTIVATING,
49 UNIT_DEACTIVATING,
94f04347
LP
50 _UNIT_ACTIVE_STATE_MAX,
51 _UNIT_ACTIVE_STATE_INVALID = -1
87f0e418
LP
52};
53
54static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) {
032ff4af 55 return t == UNIT_ACTIVE || t == UNIT_RELOADING;
87f0e418
LP
56}
57
58static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) {
032ff4af 59 return t == UNIT_ACTIVE || t == UNIT_ACTIVATING || t == UNIT_RELOADING;
87f0e418
LP
60}
61
62static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) {
fdf20a31 63 return t == UNIT_INACTIVE || t == UNIT_FAILED || t == UNIT_DEACTIVATING;
6124958c
LP
64}
65
fdf20a31
MM
66static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
67 return t == UNIT_INACTIVE || t == UNIT_FAILED;
87f0e418
LP
68}
69
70enum UnitDependency {
71 /* Positive dependencies */
72 UNIT_REQUIRES,
9e2f7c11 73 UNIT_REQUIRES_OVERRIDABLE,
87f0e418 74 UNIT_REQUISITE,
9e2f7c11
LP
75 UNIT_REQUISITE_OVERRIDABLE,
76 UNIT_WANTS,
7f2cddae 77 UNIT_BINDS_TO,
85e9a101 78 UNIT_PART_OF,
87f0e418
LP
79
80 /* Inverse of the above */
9e2f7c11 81 UNIT_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */
f14e15f8 82 UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */
9e2f7c11 83 UNIT_WANTED_BY, /* inverse of 'wants' */
7f2cddae 84 UNIT_BOUND_BY, /* inverse of 'binds_to' */
85e9a101 85 UNIT_CONSISTS_OF, /* inverse of 'part_of' */
87f0e418
LP
86
87 /* Negative dependencies */
69dd2852
LP
88 UNIT_CONFLICTS, /* inverse of 'conflicts' is 'conflicted_by' */
89 UNIT_CONFLICTED_BY,
87f0e418
LP
90
91 /* Order */
701cc384 92 UNIT_BEFORE, /* inverse of 'before' is 'after' and vice versa */
87f0e418
LP
93 UNIT_AFTER,
94
5de9682c
LP
95 /* On Failure */
96 UNIT_ON_FAILURE,
97
57020a3a
LP
98 /* Triggers (i.e. a socket triggers a service) */
99 UNIT_TRIGGERS,
100 UNIT_TRIGGERED_BY,
101
4dcc1cb4 102 /* Propagate reloads */
7f2cddae
LP
103 UNIT_PROPAGATES_RELOAD_TO,
104 UNIT_RELOAD_PROPAGATED_FROM,
4dcc1cb4 105
701cc384
LP
106 /* Reference information for GC logic */
107 UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */
108 UNIT_REFERENCED_BY,
109
87f0e418
LP
110 _UNIT_DEPENDENCY_MAX,
111 _UNIT_DEPENDENCY_INVALID = -1
112};
113
ef734fd6
LP
114#include "manager.h"
115#include "job.h"
8e274523 116#include "cgroup.h"
ab1f0633 117#include "cgroup-attr.h"
ef734fd6 118
ac155bb8 119struct Unit {
87f0e418 120 Manager *manager;
23a177ef 121
87f0e418
LP
122 UnitType type;
123 UnitLoadState load_state;
23a177ef 124 Unit *merged_into;
87f0e418
LP
125
126 char *id; /* One name is special because we use it for identification. Points to an entry in the names set */
9e2f7c11 127 char *instance;
87f0e418
LP
128
129 Set *names;
130 Set *dependencies[_UNIT_DEPENDENCY_MAX];
131
7c8fa05c
LP
132 char **requires_mounts_for;
133
87f0e418 134 char *description;
49dbfa7b 135 char **documentation;
faf919f1 136
6be1e7d5 137 char *fragment_path; /* if loaded from a config file this is the primary path to it */
1b64d026 138 char *source_path; /* if converted, the source file */
45fb0699 139 usec_t fragment_mtime;
1b64d026 140 usec_t source_mtime;
87f0e418 141
e0209d83 142 /* If there is something to do with this unit, then this is the installed job for it */
87f0e418
LP
143 Job *job;
144
e0209d83
MS
145 /* JOB_NOP jobs are special and can be installed without disturbing the real job. */
146 Job *nop_job;
147
faf919f1
LP
148 usec_t job_timeout;
149
57020a3a
LP
150 /* References to this */
151 LIST_HEAD(UnitRef, refs);
152
52661efd
LP
153 /* Conditions to check */
154 LIST_HEAD(Condition, conditions);
155
90bbc946
LP
156 dual_timestamp condition_timestamp;
157
63983207
LP
158 dual_timestamp inactive_exit_timestamp;
159 dual_timestamp active_enter_timestamp;
160 dual_timestamp active_exit_timestamp;
161 dual_timestamp inactive_enter_timestamp;
87f0e418 162
8e274523
LP
163 /* Counterparts in the cgroup filesystem */
164 CGroupBonding *cgroup_bondings;
ab1f0633 165 CGroupAttribute *cgroup_attributes;
8e274523 166
ef734fd6 167 /* Per type list */
ac155bb8 168 LIST_FIELDS(Unit, units_by_type);
c1e1601e 169
7c8fa05c
LP
170 /* All units which have requires_mounts_for set */
171 LIST_FIELDS(Unit, has_requires_mounts_for);
172
701cc384 173 /* Load queue */
ac155bb8 174 LIST_FIELDS(Unit, load_queue);
701cc384 175
c1e1601e 176 /* D-Bus queue */
ac155bb8 177 LIST_FIELDS(Unit, dbus_queue);
23a177ef
LP
178
179 /* Cleanup queue */
ac155bb8 180 LIST_FIELDS(Unit, cleanup_queue);
9d58f1db 181
701cc384 182 /* GC queue */
ac155bb8 183 LIST_FIELDS(Unit, gc_queue);
701cc384
LP
184
185 /* Used during GC sweeps */
eced69b3 186 unsigned gc_marker;
701cc384 187
7fab9d01 188 /* When deserializing, temporarily store the job type for this
39a18c60
MS
189 * unit here, if there was a job scheduled.
190 * Only for deserializing from a legacy version. New style uses full
191 * serialized jobs. */
7fab9d01
LP
192 int deserialized_job; /* This is actually of type JobType */
193
8821a00f
LP
194 /* Error code when we didn't manage to load the unit (negative) */
195 int load_error;
196
a4375746
LP
197 /* Cached unit file state */
198 UnitFileState unit_file_state;
199
9d58f1db
LP
200 /* Garbage collect us we nobody wants or requires us anymore */
201 bool stop_when_unneeded;
202
35b8ca3a 203 /* Create default dependencies */
a40eb732
LP
204 bool default_dependencies;
205
b5e9dba8
LP
206 /* Refuse manual starting, allow starting only indirectly via dependency. */
207 bool refuse_manual_start;
208
209 /* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */
210 bool refuse_manual_stop;
211
2528a7a6
LP
212 /* Allow isolation requests */
213 bool allow_isolate;
214
222ae6a8
LP
215 /* Isolate OnFailure unit */
216 bool on_failure_isolate;
217
c8f4d764
LP
218 /* Ignore this unit when isolating */
219 bool ignore_on_isolate;
220
7a6000a6
LP
221 /* Ignore this unit when snapshotting */
222 bool ignore_on_snapshot;
223
49f43d5f 224 /* Did the last condition check succeed? */
90bbc946
LP
225 bool condition_result;
226
9d58f1db
LP
227 bool in_load_queue:1;
228 bool in_dbus_queue:1;
229 bool in_cleanup_queue:1;
701cc384
LP
230 bool in_gc_queue:1;
231
9d58f1db 232 bool sent_dbus_new_signal:1;
6c073082
LP
233
234 bool no_gc:1;
cd6d0a45
LP
235
236 bool in_audit:1;
87f0e418
LP
237};
238
57020a3a
LP
239struct UnitRef {
240 /* Keeps tracks of references to a unit. This is useful so
241 * that we can merge two units if necessary and correct all
242 * references to them */
243
244 Unit* unit;
245 LIST_FIELDS(UnitRef, refs);
246};
247
c6918296
MS
248struct UnitStatusMessageFormats {
249 const char *starting_stopping[2];
250 const char *finished_start_job[_JOB_RESULT_MAX];
251 const char *finished_stop_job[_JOB_RESULT_MAX];
252};
253
87f0e418
LP
254#include "service.h"
255#include "timer.h"
256#include "socket.h"
257#include "target.h"
258#include "device.h"
259#include "mount.h"
260#include "automount.h"
261#include "snapshot.h"
07b0b134 262#include "swap.h"
01f78473 263#include "path.h"
87f0e418 264
87f0e418 265struct UnitVTable {
7d17cfbc
MS
266 /* How much memory does an object of this unit type need */
267 size_t object_size;
268
3ef63c31
LP
269 /* If greater than 0, the offset into the object where
270 * ExecContext is found, if the unit type has that */
271 size_t exec_context_offset;
272
f975e971
LP
273 /* Config file sections this unit type understands, separated
274 * by NUL chars */
275 const char *sections;
276
e537352b 277 /* This should reset all type-specific variables. This should
a16e1123
LP
278 * not allocate memory, and is called with zero-initialized
279 * data. It should hence only initialize variables that need
280 * to be set != 0. */
e537352b
LP
281 void (*init)(Unit *u);
282
a16e1123
LP
283 /* This should free all type-specific variables. It should be
284 * idempotent. */
285 void (*done)(Unit *u);
286
e537352b
LP
287 /* Actually load data from disk. This may fail, and should set
288 * load_state to UNIT_LOADED, UNIT_MERGED or leave it at
289 * UNIT_STUB if no configuration could be found. */
290 int (*load)(Unit *u);
291
c5315881 292 /* If a lot of units got created via enumerate(), this is
e537352b 293 * where to actually set the state and call unit_notify(). */
f50e0a01 294 int (*coldplug)(Unit *u);
87f0e418
LP
295
296 void (*dump)(Unit *u, FILE *f, const char *prefix);
297
298 int (*start)(Unit *u);
299 int (*stop)(Unit *u);
300 int (*reload)(Unit *u);
301
c74f17d9 302 int (*kill)(Unit *u, KillWho w, int signo, DBusError *error);
8a0867d6 303
87f0e418
LP
304 bool (*can_reload)(Unit *u);
305
a16e1123
LP
306 /* Write all data that cannot be restored from other sources
307 * away using unit_serialize_item() */
308 int (*serialize)(Unit *u, FILE *f, FDSet *fds);
309
310 /* Restore one item from the serialization */
311 int (*deserialize_item)(Unit *u, const char *key, const char *data, FDSet *fds);
312
87f0e418
LP
313 /* Boils down the more complex internal state of this unit to
314 * a simpler one that the engine can understand */
315 UnitActiveState (*active_state)(Unit *u);
316
10a94420
LP
317 /* Returns the substate specific to this unit type as
318 * string. This is purely information so that we can give the
35b8ca3a 319 * user a more fine grained explanation in which actual state a
10a94420
LP
320 * unit is in. */
321 const char* (*sub_state_to_string)(Unit *u);
322
701cc384
LP
323 /* Return true when there is reason to keep this entry around
324 * even nothing references it and it isn't active in any
325 * way */
326 bool (*check_gc)(Unit *u);
327
328 /* Return true when this unit is suitable for snapshotting */
329 bool (*check_snapshot)(Unit *u);
330
acbb0225 331 void (*fd_event)(Unit *u, int fd, uint32_t events, Watch *w);
87f0e418 332 void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
acbb0225 333 void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w);
7824bbeb 334
fdf20a31
MM
335 /* Reset failed state if we are in failed state */
336 void (*reset_failed)(Unit *u);
5632e374 337
05e343b7
LP
338 /* Called whenever any of the cgroups this unit watches for
339 * ran empty */
8e274523
LP
340 void (*cgroup_notify_empty)(Unit *u);
341
8c47c732 342 /* Called whenever a process of this unit sends us a message */
c952c6ec 343 void (*notify_message)(Unit *u, pid_t pid, char **tags);
8c47c732 344
05e343b7
LP
345 /* Called whenever a name thus Unit registered for comes or
346 * goes away. */
347 void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner);
348
349 /* Called whenever a bus PID lookup finishes */
350 void (*bus_query_pid_done)(Unit *u, const char *name, pid_t pid);
351
4139c1b2 352 /* Called for each message received on the bus */
5e8d1c9a 353 DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message);
4139c1b2 354
a7f241db
LP
355 /* Return the unit this unit is following */
356 Unit *(*following)(Unit *u);
357
6210e7fc
LP
358 /* Return the set of units that are following each other */
359 int (*following_set)(Unit *u, Set **s);
360
f50e0a01
LP
361 /* This is called for each unit type and should be used to
362 * enumerate existing devices and load them. However,
363 * everything that is loaded here should still stay in
364 * inactive state. It is the job of the coldplug() call above
365 * to put the units into the initial state. */
7824bbeb 366 int (*enumerate)(Manager *m);
f50e0a01
LP
367
368 /* Type specific cleanups. */
7824bbeb 369 void (*shutdown)(Manager *m);
9d58f1db 370
c4e2ceae 371 /* When sending out PropertiesChanged signal, which properties
96d4ce01 372 * shall be invalidated? This is a NUL separated list of
c4e2ceae
LP
373 * strings, to minimize relocations a little. */
374 const char *bus_invalidating_properties;
375
376 /* The interface name */
377 const char *bus_interface;
378
c6918296
MS
379 UnitStatusMessageFormats status_message_formats;
380
9d58f1db
LP
381 /* Can units of this type have multiple names? */
382 bool no_alias:1;
383
9d58f1db
LP
384 /* Instances make no sense for this type */
385 bool no_instances:1;
386
701cc384
LP
387 /* Exclude from automatic gc */
388 bool no_gc:1;
87f0e418
LP
389};
390
391extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
392
ac155bb8 393#define UNIT_VTABLE(u) unit_vtable[(u)->type]
87f0e418
LP
394
395/* For casting a unit into the various unit types */
396#define DEFINE_CAST(UPPERCASE, MixedCase) \
397 static inline MixedCase* UPPERCASE(Unit *u) { \
ac155bb8 398 if (_unlikely_(!u || u->type != UNIT_##UPPERCASE)) \
87f0e418
LP
399 return NULL; \
400 \
401 return (MixedCase*) u; \
402 }
403
404/* For casting the various unit types into a unit */
ac155bb8 405#define UNIT(u) (&(u)->meta)
87f0e418
LP
406
407DEFINE_CAST(SOCKET, Socket);
408DEFINE_CAST(TIMER, Timer);
409DEFINE_CAST(SERVICE, Service);
410DEFINE_CAST(TARGET, Target);
411DEFINE_CAST(DEVICE, Device);
412DEFINE_CAST(MOUNT, Mount);
413DEFINE_CAST(AUTOMOUNT, Automount);
414DEFINE_CAST(SNAPSHOT, Snapshot);
07b0b134 415DEFINE_CAST(SWAP, Swap);
01f78473 416DEFINE_CAST(PATH, Path);
87f0e418 417
7d17cfbc 418Unit *unit_new(Manager *m, size_t size);
87f0e418
LP
419void unit_free(Unit *u);
420
421int unit_add_name(Unit *u, const char *name);
9e2f7c11 422
701cc384 423int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference);
2c966c03
LP
424int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference);
425
701cc384 426int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference);
2c966c03
LP
427int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference);
428
701cc384 429int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference);
2c966c03 430int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference);
0ae97ec1 431
23a177ef
LP
432int unit_add_exec_dependencies(Unit *u, ExecContext *c);
433
8e274523
LP
434int unit_add_cgroup(Unit *u, CGroupBonding *b);
435int unit_add_cgroup_from_text(Unit *u, const char *name);
d686d8a9 436int unit_add_default_cgroups(Unit *u);
8e274523 437CGroupBonding* unit_get_default_cgroup(Unit *u);
ab1f0633 438int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback);
8e274523 439
0ae97ec1 440int unit_choose_id(Unit *u, const char *name);
f50e0a01 441int unit_set_description(Unit *u, const char *description);
87f0e418 442
701cc384
LP
443bool unit_check_gc(Unit *u);
444
87f0e418 445void unit_add_to_load_queue(Unit *u);
c1e1601e 446void unit_add_to_dbus_queue(Unit *u);
23a177ef 447void unit_add_to_cleanup_queue(Unit *u);
701cc384 448void unit_add_to_gc_queue(Unit *u);
87f0e418
LP
449
450int unit_merge(Unit *u, Unit *other);
23a177ef
LP
451int unit_merge_by_name(Unit *u, const char *other);
452
453Unit *unit_follow_merge(Unit *u);
87f0e418 454
e537352b
LP
455int unit_load_fragment_and_dropin(Unit *u);
456int unit_load_fragment_and_dropin_optional(Unit *u);
87f0e418
LP
457int unit_load(Unit *unit);
458
87f0e418
LP
459const char *unit_description(Unit *u);
460
f278026d
LP
461bool unit_has_name(Unit *u, const char *name);
462
87f0e418
LP
463UnitActiveState unit_active_state(Unit *u);
464
10a94420
LP
465const char* unit_sub_state_to_string(Unit *u);
466
87f0e418
LP
467void unit_dump(Unit *u, FILE *f, const char *prefix);
468
469bool unit_can_reload(Unit *u);
470bool unit_can_start(Unit *u);
2528a7a6 471bool unit_can_isolate(Unit *u);
87f0e418
LP
472
473int unit_start(Unit *u);
474int unit_stop(Unit *u);
475int unit_reload(Unit *u);
476
c74f17d9 477int unit_kill(Unit *u, KillWho w, int signo, DBusError *error);
8a0867d6 478
e2f3b44c 479void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success);
87f0e418 480
acbb0225
LP
481int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w);
482void unit_unwatch_fd(Unit *u, Watch *w);
87f0e418
LP
483
484int unit_watch_pid(Unit *u, pid_t pid);
485void unit_unwatch_pid(Unit *u, pid_t pid);
486
36697dc0 487int unit_watch_timer(Unit *u, clockid_t, bool relative, usec_t usec, Watch *w);
acbb0225 488void unit_unwatch_timer(Unit *u, Watch *w);
87f0e418 489
05e343b7
LP
490int unit_watch_bus_name(Unit *u, const char *name);
491void unit_unwatch_bus_name(Unit *u, const char *name);
492
87f0e418
LP
493bool unit_job_is_applicable(Unit *u, JobType j);
494
0301abf4
LP
495int set_unit_path(const char *p);
496
50159e6a
LP
497char *unit_dbus_path(Unit *u);
498
f6ff8c29 499int unit_load_related_unit(Unit *u, const char *type, Unit **_found);
a16e1123 500int unit_get_related_unit(Unit *u, const char *type, Unit **_found);
f6ff8c29 501
a16e1123 502bool unit_can_serialize(Unit *u);
6b78f9b4 503int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs);
93a46b0b 504void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr_(4,5);
a16e1123
LP
505void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value);
506int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
507
6e2ef85b
LP
508int unit_add_node_link(Unit *u, const char *what, bool wants);
509
cca098b0
LP
510int unit_coldplug(Unit *u);
511
5831e9b7 512void unit_status_printf(Unit *u, const char *status, const char *format, ...);
9e58ff9c 513
45fb0699
LP
514bool unit_need_daemon_reload(Unit *u);
515
fdf20a31 516void unit_reset_failed(Unit *u);
5632e374 517
a7f241db
LP
518Unit *unit_following(Unit *u);
519
18ffdfda 520bool unit_pending_inactive(Unit *u);
f976f3f6 521bool unit_pending_active(Unit *u);
18ffdfda 522
bba34eed
LP
523int unit_add_default_target_dependency(Unit *u, Unit *target);
524
41f9172f
LP
525char *unit_default_cgroup_path(Unit *u);
526
6210e7fc
LP
527int unit_following_set(Unit *u, Set **s);
528
c0daa706
LP
529void unit_trigger_on_failure(Unit *u);
530
90bbc946
LP
531bool unit_condition_test(Unit *u);
532
a4375746
LP
533UnitFileState unit_get_unit_file_state(Unit *u);
534
57020a3a
LP
535Unit* unit_ref_set(UnitRef *ref, Unit *u);
536void unit_ref_unset(UnitRef *ref);
537
538#define UNIT_DEREF(ref) ((ref).unit)
539
7c8fa05c
LP
540int unit_add_one_mount_link(Unit *u, Mount *m);
541int unit_add_mount_links(Unit *u);
542
cba6e062 543int unit_exec_context_defaults(Unit *u, ExecContext *c);
e06c73cc 544
3ef63c31
LP
545ExecContext *unit_get_exec_context(Unit *u);
546
94f04347
LP
547const char *unit_active_state_to_string(UnitActiveState i);
548UnitActiveState unit_active_state_from_string(const char *s);
549
550const char *unit_dependency_to_string(UnitDependency i);
551UnitDependency unit_dependency_from_string(const char *s);