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