]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.h
Merge pull request #7246 from poettering/journal-extra-fields
[thirdparty/systemd.git] / src / core / unit.h
CommitLineData
c2f1db8f 1#pragma once
87f0e418 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
87f0e418
LP
22#include <stdbool.h>
23#include <stdlib.h>
bbc9006e 24#include <unistd.h>
87f0e418 25
ac155bb8 26typedef struct Unit Unit;
87f0e418 27typedef struct UnitVTable UnitVTable;
57020a3a 28typedef struct UnitRef UnitRef;
c6918296 29typedef struct UnitStatusMessageFormats UnitStatusMessageFormats;
87f0e418 30
6a48d82f 31#include "bpf-program.h"
134e56dc 32#include "condition.h"
87a47f99 33#include "emergency-action.h"
a4375746 34#include "install.h"
71d35b6b 35#include "list.h"
0a9f8ed0 36#include "unit-name.h"
6b659ed8 37#include "cgroup.h"
87f0e418 38
db2cb23b
UTL
39typedef enum KillOperation {
40 KILL_TERMINATE,
1d98fef1 41 KILL_TERMINATE_AND_LOG,
db2cb23b
UTL
42 KILL_KILL,
43 KILL_ABORT,
4940c0b0
LP
44 _KILL_OPERATION_MAX,
45 _KILL_OPERATION_INVALID = -1
db2cb23b
UTL
46} KillOperation;
47
87f0e418 48static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) {
3742095b 49 return IN_SET(t, UNIT_ACTIVE, UNIT_RELOADING);
87f0e418
LP
50}
51
52static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) {
3742095b 53 return IN_SET(t, UNIT_ACTIVE, UNIT_ACTIVATING, UNIT_RELOADING);
87f0e418
LP
54}
55
56static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) {
3742095b 57 return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED, UNIT_DEACTIVATING);
6124958c
LP
58}
59
fdf20a31 60static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
3742095b 61 return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED);
87f0e418
LP
62}
63
eef85c4a
LP
64/* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
65 * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
66 * created as a result of multiple "reasons", hence the bitmask. */
67typedef enum UnitDependencyMask {
68 /* Configured directly by the unit file, .wants/.requries symlink or drop-in, or as an immediate result of a
69 * non-dependency option configured that way. */
70 UNIT_DEPENDENCY_FILE = 1 << 0,
71
72 /* As unconditional implicit dependency (not affected by unit configuration — except by the unit name and
73 * type) */
74 UNIT_DEPENDENCY_IMPLICIT = 1 << 1,
75
76 /* A dependency effected by DefaultDependencies=yes. Note that dependencies marked this way are conceptually
77 * just a subset of UNIT_DEPENDENCY_FILE, as DefaultDependencies= is itself a unit file setting that can only
78 * be set in unit files. We make this two separate bits only to help debugging how dependencies came to be. */
79 UNIT_DEPENDENCY_DEFAULT = 1 << 2,
80
81 /* A dependency created from udev rules */
82 UNIT_DEPENDENCY_UDEV = 1 << 3,
83
84 /* A dependency created because of some unit's RequiresMountsFor= setting */
85 UNIT_DEPENDENCY_PATH = 1 << 4,
86
87 /* A dependency created because of data read from /proc/self/mountinfo and no other configuration source */
88 UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT = 1 << 5,
89
90 /* A dependency created because of data read from /proc/self/mountinfo, but conditionalized by
91 * DefaultDependencies= and thus also involving configuration from UNIT_DEPENDENCY_FILE sources */
92 UNIT_DEPENDENCY_MOUNTINFO_DEFAULT = 1 << 6,
93
94 /* A dependency created because of data read from /proc/swaps and no other configuration source */
95 UNIT_DEPENDENCY_PROC_SWAP = 1 << 7,
96
97 _UNIT_DEPENDENCY_MASK_FULL = (1 << 8) - 1,
98} UnitDependencyMask;
99
100/* The Unit's dependencies[] hashmaps use this structure as value. It has the same size as a void pointer, and thus can
101 * be stored directly as hashmap value, without any indirection. Note that this stores two masks, as both the origin
102 * and the destination of a dependency might have created it. */
103typedef union UnitDependencyInfo {
104 void *data;
105 struct {
106 UnitDependencyMask origin_mask:16;
107 UnitDependencyMask destination_mask:16;
108 } _packed_;
109} UnitDependencyInfo;
110
ef734fd6
LP
111#include "job.h"
112
a016b922
LP
113struct UnitRef {
114 /* Keeps tracks of references to a unit. This is useful so
115 * that we can merge two units if necessary and correct all
116 * references to them */
117
118 Unit* unit;
119 LIST_FIELDS(UnitRef, refs);
120};
121
906c06f6
DM
122typedef enum UnitCGroupBPFState {
123 UNIT_CGROUP_BPF_OFF = 0,
124 UNIT_CGROUP_BPF_ON = 1,
125 UNIT_CGROUP_BPF_INVALIDATED = -1,
126} UnitCGroupBPFState;
127
ac155bb8 128struct Unit {
87f0e418 129 Manager *manager;
23a177ef 130
87f0e418
LP
131 UnitType type;
132 UnitLoadState load_state;
23a177ef 133 Unit *merged_into;
87f0e418
LP
134
135 char *id; /* One name is special because we use it for identification. Points to an entry in the names set */
9e2f7c11 136 char *instance;
87f0e418
LP
137
138 Set *names;
87f0e418 139
eef85c4a
LP
140 /* For each dependency type we maintain a Hashmap whose key is the Unit* object, and the value encodes why the
141 * dependency exists, using the UnitDependencyInfo type */
142 Hashmap *dependencies[_UNIT_DEPENDENCY_MAX];
143
144 /* Similar, for RequiresMountsFor= path dependencies. The key is the path, the value the UnitDependencyInfo type */
145 Hashmap *requires_mounts_for;
7c8fa05c 146
87f0e418 147 char *description;
49dbfa7b 148 char **documentation;
faf919f1 149
6be1e7d5 150 char *fragment_path; /* if loaded from a config file this is the primary path to it */
1b64d026 151 char *source_path; /* if converted, the source file */
ae7a7182 152 char **dropin_paths;
f78f265f 153
45fb0699 154 usec_t fragment_mtime;
1b64d026 155 usec_t source_mtime;
ae7a7182 156 usec_t dropin_mtime;
87f0e418 157
4f4afc88
LP
158 /* If this is a transient unit we are currently writing, this is where we are writing it to */
159 FILE *transient_file;
160
e0209d83 161 /* If there is something to do with this unit, then this is the installed job for it */
87f0e418
LP
162 Job *job;
163
e0209d83
MS
164 /* JOB_NOP jobs are special and can be installed without disturbing the real job. */
165 Job *nop_job;
166
bbc29086
DM
167 /* The slot used for watching NameOwnerChanged signals */
168 sd_bus_slot *match_bus_slot;
169
05a98afd
LP
170 /* References to this unit from clients */
171 sd_bus_track *bus_track;
172 char **deserialized_refs;
173
f189ab18 174 /* Job timeout and action to take */
faf919f1 175 usec_t job_timeout;
a2df3ea4 176 usec_t job_running_timeout;
eae51da3 177 bool job_running_timeout_set:1;
87a47f99 178 EmergencyAction job_timeout_action;
f189ab18 179 char *job_timeout_reboot_arg;
faf919f1 180
57020a3a
LP
181 /* References to this */
182 LIST_HEAD(UnitRef, refs);
183
52661efd
LP
184 /* Conditions to check */
185 LIST_HEAD(Condition, conditions);
59fccdc5 186 LIST_HEAD(Condition, asserts);
52661efd 187
90bbc946 188 dual_timestamp condition_timestamp;
59fccdc5 189 dual_timestamp assert_timestamp;
90bbc946 190
a483fb59
LP
191 /* Updated whenever the low-level state changes */
192 dual_timestamp state_change_timestamp;
193
194 /* Updated whenever the (high-level) active state enters or leaves the active or inactive states */
63983207
LP
195 dual_timestamp inactive_exit_timestamp;
196 dual_timestamp active_enter_timestamp;
197 dual_timestamp active_exit_timestamp;
198 dual_timestamp inactive_enter_timestamp;
87f0e418 199
a016b922
LP
200 UnitRef slice;
201
ef734fd6 202 /* Per type list */
ac155bb8 203 LIST_FIELDS(Unit, units_by_type);
c1e1601e 204
7c8fa05c
LP
205 /* All units which have requires_mounts_for set */
206 LIST_FIELDS(Unit, has_requires_mounts_for);
207
701cc384 208 /* Load queue */
ac155bb8 209 LIST_FIELDS(Unit, load_queue);
701cc384 210
c1e1601e 211 /* D-Bus queue */
ac155bb8 212 LIST_FIELDS(Unit, dbus_queue);
23a177ef
LP
213
214 /* Cleanup queue */
ac155bb8 215 LIST_FIELDS(Unit, cleanup_queue);
9d58f1db 216
701cc384 217 /* GC queue */
ac155bb8 218 LIST_FIELDS(Unit, gc_queue);
701cc384 219
4ad49000 220 /* CGroup realize members queue */
91a6073e 221 LIST_FIELDS(Unit, cgroup_realize_queue);
4ad49000 222
09e24654
LP
223 /* cgroup empty queue */
224 LIST_FIELDS(Unit, cgroup_empty_queue);
225
a911bb9a
LP
226 /* PIDs we keep an eye on. Note that a unit might have many
227 * more, but these are the ones we care enough about to
228 * process SIGCHLD for */
229 Set *pids;
230
36f20ae3
KW
231 /* Used in sigchld event invocation to avoid repeat events being invoked */
232 uint64_t sigchldgen;
233
701cc384 234 /* Used during GC sweeps */
eced69b3 235 unsigned gc_marker;
701cc384 236
8821a00f
LP
237 /* Error code when we didn't manage to load the unit (negative) */
238 int load_error;
239
6bf0f408
LP
240 /* Put a ratelimit on unit starting */
241 RateLimit start_limit;
87a47f99 242 EmergencyAction start_limit_action;
6bf0f408
LP
243 char *reboot_arg;
244
67bfdc97
LP
245 /* Make sure we never enter endless loops with the check unneeded logic, or the BindsTo= logic */
246 RateLimit auto_stop_ratelimit;
bea355da 247
00d9ef85
LP
248 /* Reference to a specific UID/GID */
249 uid_t ref_uid;
250 gid_t ref_gid;
251
d2dc52db 252 /* Cached unit file state and preset */
a4375746 253 UnitFileState unit_file_state;
d2dc52db 254 int unit_file_preset;
a4375746 255
66ebf6c0
TH
256 /* Where the cpu.stat or cpuacct.usage was at the time the unit was started */
257 nsec_t cpu_usage_base;
fe700f46 258 nsec_t cpu_usage_last; /* the most recently read value */
5ad096b3 259
7c52a17b
ZJS
260 /* Counterparts in the cgroup filesystem */
261 char *cgroup_path;
efdb0237 262 CGroupMask cgroup_realized_mask;
ccf78df1 263 CGroupMask cgroup_enabled_mask;
efdb0237
LP
264 CGroupMask cgroup_subtree_mask;
265 CGroupMask cgroup_members_mask;
266 int cgroup_inotify_wd;
7c52a17b 267
6a48d82f
DM
268 /* IP BPF Firewalling/accounting */
269 int ip_accounting_ingress_map_fd;
270 int ip_accounting_egress_map_fd;
271
272 int ipv4_allow_map_fd;
273 int ipv6_allow_map_fd;
274 int ipv4_deny_map_fd;
275 int ipv6_deny_map_fd;
276
277 BPFProgram *ip_bpf_ingress;
278 BPFProgram *ip_bpf_egress;
279
6b659ed8
LP
280 uint64_t ip_accounting_extra[_CGROUP_IP_ACCOUNTING_METRIC_MAX];
281
7c52a17b
ZJS
282 /* How to start OnFailure units */
283 JobMode on_failure_job_mode;
284
4b58153d
LP
285 /* The current invocation ID */
286 sd_id128_t invocation_id;
287 char invocation_id_string[SD_ID128_STRING_MAX]; /* useful when logging */
288
9d58f1db
LP
289 /* Garbage collect us we nobody wants or requires us anymore */
290 bool stop_when_unneeded;
291
35b8ca3a 292 /* Create default dependencies */
a40eb732
LP
293 bool default_dependencies;
294
b5e9dba8
LP
295 /* Refuse manual starting, allow starting only indirectly via dependency. */
296 bool refuse_manual_start;
297
298 /* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */
299 bool refuse_manual_stop;
300
2528a7a6
LP
301 /* Allow isolation requests */
302 bool allow_isolate;
303
c8f4d764
LP
304 /* Ignore this unit when isolating */
305 bool ignore_on_isolate;
306
49f43d5f 307 /* Did the last condition check succeed? */
90bbc946 308 bool condition_result;
59fccdc5 309 bool assert_result;
90bbc946 310
c2756a68
LP
311 /* Is this a transient unit? */
312 bool transient;
313
f5869324
LP
314 /* Is this a unit that is always running and cannot be stopped? */
315 bool perpetual;
316
9d58f1db
LP
317 bool in_load_queue:1;
318 bool in_dbus_queue:1;
319 bool in_cleanup_queue:1;
701cc384 320 bool in_gc_queue:1;
91a6073e 321 bool in_cgroup_realize_queue:1;
09e24654 322 bool in_cgroup_empty_queue:1;
701cc384 323
9d58f1db 324 bool sent_dbus_new_signal:1;
6c073082 325
cd6d0a45 326 bool in_audit:1;
a57f7e2c
LP
327
328 bool cgroup_realized:1;
bc432dc7
LP
329 bool cgroup_members_mask_valid:1;
330 bool cgroup_subtree_mask_valid:1;
f78f265f 331
906c06f6
DM
332 UnitCGroupBPFState cgroup_bpf_state:2;
333
6bf0f408
LP
334 bool start_limit_hit:1;
335
f78f265f 336 /* Did we already invoke unit_coldplug() for this unit? */
f8a30ce5 337 bool coldplugged:1;
05a98afd
LP
338
339 /* For transient units: whether to add a bus track reference after creating the unit */
340 bool bus_track_add:1;
d3070fbd
LP
341
342 /* Remember which unit state files we created */
343 bool exported_invocation_id:1;
344 bool exported_log_level_max:1;
345 bool exported_log_extra_fields:1;
87f0e418
LP
346};
347
c6918296
MS
348struct UnitStatusMessageFormats {
349 const char *starting_stopping[2];
350 const char *finished_start_job[_JOB_RESULT_MAX];
351 const char *finished_stop_job[_JOB_RESULT_MAX];
352};
353
8e2af478
LP
354typedef enum UnitSetPropertiesMode {
355 UNIT_CHECK = 0,
356 UNIT_RUNTIME = 1,
357 UNIT_PERSISTENT = 2,
358} UnitSetPropertiesMode;
359
71d35b6b 360#include "automount.h"
87f0e418 361#include "device.h"
c1ff5570 362#include "path.h"
6c12b52e 363#include "scope.h"
71d35b6b
TA
364#include "slice.h"
365#include "socket.h"
366#include "swap.h"
367#include "target.h"
368#include "timer.h"
87f0e418 369
87f0e418 370struct UnitVTable {
7d17cfbc
MS
371 /* How much memory does an object of this unit type need */
372 size_t object_size;
373
3ef63c31
LP
374 /* If greater than 0, the offset into the object where
375 * ExecContext is found, if the unit type has that */
376 size_t exec_context_offset;
377
4ad49000
LP
378 /* If greater than 0, the offset into the object where
379 * CGroupContext is found, if the unit type has that */
380 size_t cgroup_context_offset;
381
718db961
LP
382 /* If greater than 0, the offset into the object where
383 * KillContext is found, if the unit type has that */
384 size_t kill_context_offset;
385
613b411c
LP
386 /* If greater than 0, the offset into the object where the
387 * pointer to ExecRuntime is found, if the unit type has
388 * that */
389 size_t exec_runtime_offset;
390
29206d46
LP
391 /* If greater than 0, the offset into the object where the pointer to DynamicCreds is found, if the unit type
392 * has that. */
393 size_t dynamic_creds_offset;
394
ee33e53a 395 /* The name of the configuration file section with the private settings of this unit */
4ad49000 396 const char *private_section;
71645aca 397
f975e971
LP
398 /* Config file sections this unit type understands, separated
399 * by NUL chars */
400 const char *sections;
401
e537352b 402 /* This should reset all type-specific variables. This should
a16e1123
LP
403 * not allocate memory, and is called with zero-initialized
404 * data. It should hence only initialize variables that need
405 * to be set != 0. */
e537352b
LP
406 void (*init)(Unit *u);
407
a16e1123
LP
408 /* This should free all type-specific variables. It should be
409 * idempotent. */
410 void (*done)(Unit *u);
411
e537352b
LP
412 /* Actually load data from disk. This may fail, and should set
413 * load_state to UNIT_LOADED, UNIT_MERGED or leave it at
414 * UNIT_STUB if no configuration could be found. */
415 int (*load)(Unit *u);
416
c5315881 417 /* If a lot of units got created via enumerate(), this is
be847e82
LP
418 * where to actually set the state and call unit_notify(). */
419 int (*coldplug)(Unit *u);
87f0e418
LP
420
421 void (*dump)(Unit *u, FILE *f, const char *prefix);
422
423 int (*start)(Unit *u);
424 int (*stop)(Unit *u);
425 int (*reload)(Unit *u);
426
718db961 427 int (*kill)(Unit *u, KillWho w, int signo, sd_bus_error *error);
8a0867d6 428
87f0e418
LP
429 bool (*can_reload)(Unit *u);
430
a16e1123
LP
431 /* Write all data that cannot be restored from other sources
432 * away using unit_serialize_item() */
433 int (*serialize)(Unit *u, FILE *f, FDSet *fds);
434
435 /* Restore one item from the serialization */
436 int (*deserialize_item)(Unit *u, const char *key, const char *data, FDSet *fds);
437
01e10de3 438 /* Try to match up fds with what we need for this unit */
9ff1a6f1 439 void (*distribute_fds)(Unit *u, FDSet *fds);
01e10de3 440
87f0e418
LP
441 /* Boils down the more complex internal state of this unit to
442 * a simpler one that the engine can understand */
443 UnitActiveState (*active_state)(Unit *u);
444
10a94420
LP
445 /* Returns the substate specific to this unit type as
446 * string. This is purely information so that we can give the
35b8ca3a 447 * user a more fine grained explanation in which actual state a
10a94420
LP
448 * unit is in. */
449 const char* (*sub_state_to_string)(Unit *u);
450
701cc384
LP
451 /* Return true when there is reason to keep this entry around
452 * even nothing references it and it isn't active in any
453 * way */
454 bool (*check_gc)(Unit *u);
455
a354329f
LP
456 /* When the unit is not running and no job for it queued we
457 * shall release its runtime resources */
f0bfbfac 458 void (*release_resources)(Unit *u, bool inactive);
a354329f 459
718db961 460 /* Invoked on every child that died */
87f0e418 461 void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
7824bbeb 462
fdf20a31
MM
463 /* Reset failed state if we are in failed state */
464 void (*reset_failed)(Unit *u);
5632e374 465
05e343b7
LP
466 /* Called whenever any of the cgroups this unit watches for
467 * ran empty */
4ad49000 468 void (*notify_cgroup_empty)(Unit *u);
8e274523 469
8c47c732 470 /* Called whenever a process of this unit sends us a message */
a354329f 471 void (*notify_message)(Unit *u, pid_t pid, char **tags, FDSet *fds);
8c47c732 472
00d9ef85 473 /* Called whenever a name this Unit registered for comes or goes away. */
05e343b7
LP
474 void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner);
475
8e2af478 476 /* Called for each property that is being set */
718db961 477 int (*bus_set_property)(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error);
8e2af478
LP
478
479 /* Called after at least one property got changed to apply the necessary change */
480 int (*bus_commit_properties)(Unit *u);
481
a7f241db
LP
482 /* Return the unit this unit is following */
483 Unit *(*following)(Unit *u);
484
6210e7fc
LP
485 /* Return the set of units that are following each other */
486 int (*following_set)(Unit *u, Set **s);
487
3ecaa09b
LP
488 /* Invoked each time a unit this unit is triggering changes
489 * state or gains/loses a job */
490 void (*trigger_notify)(Unit *u, Unit *trigger);
491
8742514c
LP
492 /* Called whenever CLOCK_REALTIME made a jump */
493 void (*time_change)(Unit *u);
494
7a7821c8
LP
495 /* Returns the next timeout of a unit */
496 int (*get_timeout)(Unit *u, usec_t *timeout);
68db7a3b 497
291d565a
LP
498 /* Returns the main PID if there is any defined, or 0. */
499 pid_t (*main_pid)(Unit *u);
500
501 /* Returns the main PID if there is any defined, or 0. */
502 pid_t (*control_pid)(Unit *u);
503
f50e0a01
LP
504 /* This is called for each unit type and should be used to
505 * enumerate existing devices and load them. However,
506 * everything that is loaded here should still stay in
507 * inactive state. It is the job of the coldplug() call above
508 * to put the units into the initial state. */
ba64af90 509 void (*enumerate)(Manager *m);
f50e0a01
LP
510
511 /* Type specific cleanups. */
7824bbeb 512 void (*shutdown)(Manager *m);
9d58f1db 513
0faacd47
LP
514 /* If this function is set and return false all jobs for units
515 * of this type will immediately fail. */
1c2e9646 516 bool (*supported)(void);
0faacd47 517
718db961
LP
518 /* The bus vtable */
519 const sd_bus_vtable *bus_vtable;
520
718db961 521 /* The strings to print in status messages */
c6918296
MS
522 UnitStatusMessageFormats status_message_formats;
523
c2756a68
LP
524 /* True if transient units of this type are OK */
525 bool can_transient:1;
c5a97ed1
LP
526
527 /* True if queued jobs of this type should be GC'ed if no other job needs them anymore */
528 bool gc_jobs:1;
87f0e418
LP
529};
530
531extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
532
ac155bb8 533#define UNIT_VTABLE(u) unit_vtable[(u)->type]
87f0e418
LP
534
535/* For casting a unit into the various unit types */
536#define DEFINE_CAST(UPPERCASE, MixedCase) \
537 static inline MixedCase* UPPERCASE(Unit *u) { \
ac155bb8 538 if (_unlikely_(!u || u->type != UNIT_##UPPERCASE)) \
87f0e418
LP
539 return NULL; \
540 \
541 return (MixedCase*) u; \
542 }
543
544/* For casting the various unit types into a unit */
ac155bb8 545#define UNIT(u) (&(u)->meta)
87f0e418 546
35b7ff80
LP
547#define UNIT_HAS_EXEC_CONTEXT(u) (UNIT_VTABLE(u)->exec_context_offset > 0)
548#define UNIT_HAS_CGROUP_CONTEXT(u) (UNIT_VTABLE(u)->cgroup_context_offset > 0)
549#define UNIT_HAS_KILL_CONTEXT(u) (UNIT_VTABLE(u)->kill_context_offset > 0)
550
eef85c4a 551#define UNIT_TRIGGER(u) ((Unit*) hashmap_first_key((u)->dependencies[UNIT_TRIGGERS]))
3ecaa09b 552
87f0e418 553DEFINE_CAST(SERVICE, Service);
e821075a 554DEFINE_CAST(SOCKET, Socket);
87f0e418
LP
555DEFINE_CAST(TARGET, Target);
556DEFINE_CAST(DEVICE, Device);
557DEFINE_CAST(MOUNT, Mount);
558DEFINE_CAST(AUTOMOUNT, Automount);
07b0b134 559DEFINE_CAST(SWAP, Swap);
e821075a 560DEFINE_CAST(TIMER, Timer);
01f78473 561DEFINE_CAST(PATH, Path);
a016b922 562DEFINE_CAST(SLICE, Slice);
6c12b52e 563DEFINE_CAST(SCOPE, Scope);
87f0e418 564
7d17cfbc 565Unit *unit_new(Manager *m, size_t size);
87f0e418
LP
566void unit_free(Unit *u);
567
a581e45a 568int unit_new_for_name(Manager *m, size_t size, const char *name, Unit **ret);
87f0e418 569int unit_add_name(Unit *u, const char *name);
9e2f7c11 570
eef85c4a
LP
571int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference, UnitDependencyMask mask);
572int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference, UnitDependencyMask mask);
2c966c03 573
eef85c4a
LP
574int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference, UnitDependencyMask mask);
575int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference, UnitDependencyMask mask);
2c966c03 576
23a177ef
LP
577int unit_add_exec_dependencies(Unit *u, ExecContext *c);
578
0ae97ec1 579int unit_choose_id(Unit *u, const char *name);
f50e0a01 580int unit_set_description(Unit *u, const char *description);
87f0e418 581
701cc384
LP
582bool unit_check_gc(Unit *u);
583
87f0e418 584void unit_add_to_load_queue(Unit *u);
c1e1601e 585void unit_add_to_dbus_queue(Unit *u);
23a177ef 586void unit_add_to_cleanup_queue(Unit *u);
701cc384 587void unit_add_to_gc_queue(Unit *u);
87f0e418
LP
588
589int unit_merge(Unit *u, Unit *other);
23a177ef
LP
590int unit_merge_by_name(Unit *u, const char *other);
591
44a6b1b6 592Unit *unit_follow_merge(Unit *u) _pure_;
87f0e418 593
e537352b
LP
594int unit_load_fragment_and_dropin(Unit *u);
595int unit_load_fragment_and_dropin_optional(Unit *u);
87f0e418
LP
596int unit_load(Unit *unit);
597
d79200e2
LP
598int unit_set_slice(Unit *u, Unit *slice);
599int unit_set_default_slice(Unit *u);
a016b922 600
44a6b1b6 601const char *unit_description(Unit *u) _pure_;
87f0e418 602
f278026d
LP
603bool unit_has_name(Unit *u, const char *name);
604
87f0e418
LP
605UnitActiveState unit_active_state(Unit *u);
606
10a94420
LP
607const char* unit_sub_state_to_string(Unit *u);
608
87f0e418
LP
609void unit_dump(Unit *u, FILE *f, const char *prefix);
610
44a6b1b6
ZJS
611bool unit_can_reload(Unit *u) _pure_;
612bool unit_can_start(Unit *u) _pure_;
f5869324 613bool unit_can_stop(Unit *u) _pure_;
44a6b1b6 614bool unit_can_isolate(Unit *u) _pure_;
87f0e418
LP
615
616int unit_start(Unit *u);
617int unit_stop(Unit *u);
618int unit_reload(Unit *u);
619
718db961
LP
620int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error);
621int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t control_pid, sd_bus_error *error);
8a0867d6 622
e2f3b44c 623void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success);
87f0e418 624
87f0e418
LP
625int unit_watch_pid(Unit *u, pid_t pid);
626void unit_unwatch_pid(Unit *u, pid_t pid);
a911bb9a
LP
627void unit_unwatch_all_pids(Unit *u);
628
629void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2);
87f0e418 630
9806e87d 631int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name);
05e343b7
LP
632int unit_watch_bus_name(Unit *u, const char *name);
633void unit_unwatch_bus_name(Unit *u, const char *name);
634
87f0e418
LP
635bool unit_job_is_applicable(Unit *u, JobType j);
636
0301abf4
LP
637int set_unit_path(const char *p);
638
50159e6a 639char *unit_dbus_path(Unit *u);
4b58153d 640char *unit_dbus_path_invocation_id(Unit *u);
50159e6a 641
f6ff8c29
LP
642int unit_load_related_unit(Unit *u, const char *type, Unit **_found);
643
44a6b1b6 644bool unit_can_serialize(Unit *u) _pure_;
a34ceba6 645
6b78f9b4 646int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs);
a16e1123 647int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
07429866 648void unit_deserialize_skip(FILE *f);
a16e1123 649
a34ceba6
LP
650int unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value);
651int unit_serialize_item_escaped(Unit *u, FILE *f, const char *key, const char *value);
652int unit_serialize_item_fd(Unit *u, FILE *f, FDSet *fds, const char *key, int fd);
653void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_(4,5);
654
eef85c4a 655int unit_add_node_dependency(Unit *u, const char *what, bool wants, UnitDependency d, UnitDependencyMask mask);
6e2ef85b 656
be847e82 657int unit_coldplug(Unit *u);
cca098b0 658
44b601bc 659void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0);
d1a34ae9 660void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t);
9e58ff9c 661
45fb0699
LP
662bool unit_need_daemon_reload(Unit *u);
663
fdf20a31 664void unit_reset_failed(Unit *u);
5632e374 665
a7f241db 666Unit *unit_following(Unit *u);
eeaedb7c 667int unit_following_set(Unit *u, Set **s);
a7f241db 668
9444b1f2
LP
669const char *unit_slice_name(Unit *u);
670
44a6b1b6
ZJS
671bool unit_stop_pending(Unit *u) _pure_;
672bool unit_inactive_or_pending(Unit *u) _pure_;
31afa0a4 673bool unit_active_or_pending(Unit *u);
18ffdfda 674
bba34eed
LP
675int unit_add_default_target_dependency(Unit *u, Unit *target);
676
3ecaa09b
LP
677void unit_start_on_failure(Unit *u);
678void unit_trigger_notify(Unit *u);
c0daa706 679
a4375746 680UnitFileState unit_get_unit_file_state(Unit *u);
d2dc52db 681int unit_get_unit_file_preset(Unit *u);
a4375746 682
57020a3a
LP
683Unit* unit_ref_set(UnitRef *ref, Unit *u);
684void unit_ref_unset(UnitRef *ref);
685
686#define UNIT_DEREF(ref) ((ref).unit)
9444b1f2 687#define UNIT_ISSET(ref) (!!(ref).unit)
57020a3a 688
598459ce 689int unit_patch_contexts(Unit *u);
e06c73cc 690
44a6b1b6 691ExecContext *unit_get_exec_context(Unit *u) _pure_;
718db961 692KillContext *unit_get_kill_context(Unit *u) _pure_;
4ad49000 693CGroupContext *unit_get_cgroup_context(Unit *u) _pure_;
598459ce 694
613b411c
LP
695ExecRuntime *unit_get_exec_runtime(Unit *u) _pure_;
696
697int unit_setup_exec_runtime(Unit *u);
29206d46 698int unit_setup_dynamic_creds(Unit *u);
3ef63c31 699
8e2af478 700int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data);
44b601bc 701int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_(4,5);
b9ec9359
LP
702
703int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data);
44b601bc 704int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_(4,5);
b9ec9359 705
db2cb23b 706int unit_kill_context(Unit *u, KillContext *c, KillOperation k, pid_t main_pid, pid_t control_pid, bool main_pid_alien);
cd2086fe 707
c2756a68
LP
708int unit_make_transient(Unit *u);
709
eef85c4a 710int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask);
a57f7e2c 711
1c2e9646
LP
712bool unit_type_supported(UnitType t);
713
0f13f3bd
LP
714bool unit_is_pristine(Unit *u);
715
291d565a
LP
716pid_t unit_control_pid(Unit *u);
717pid_t unit_main_pid(Unit *u);
718
1c2e9646
LP
719static inline bool unit_supported(Unit *u) {
720 return unit_type_supported(u->type);
721}
722
8b4305c7
LP
723void unit_warn_if_dir_nonempty(Unit *u, const char* where);
724int unit_fail_if_symlink(Unit *u, const char* where);
725
07299350
LP
726int unit_start_limit_test(Unit *u);
727
00d9ef85
LP
728void unit_unref_uid(Unit *u, bool destroy_now);
729int unit_ref_uid(Unit *u, uid_t uid, bool clean_ipc);
730
731void unit_unref_gid(Unit *u, bool destroy_now);
732int unit_ref_gid(Unit *u, gid_t gid, bool clean_ipc);
733
734int unit_ref_uid_gid(Unit *u, uid_t uid, gid_t gid);
735void unit_unref_uid_gid(Unit *u, bool destroy_now);
736
737void unit_notify_user_lookup(Unit *u, uid_t uid, gid_t gid);
738
4b58153d
LP
739int unit_set_invocation_id(Unit *u, sd_id128_t id);
740int unit_acquire_invocation_id(Unit *u);
741
c891efaf
FB
742bool unit_shall_confirm_spawn(Unit *u);
743
f0d47797
LP
744void unit_set_exec_params(Unit *s, ExecParameters *p);
745
a79279c7
LP
746int unit_fork_helper_process(Unit *u, pid_t *ret);
747
c999cf38
LP
748void unit_remove_dependencies(Unit *u, UnitDependencyMask mask);
749
d3070fbd
LP
750void unit_export_state_files(Unit *u);
751void unit_unlink_state_files(Unit *u);
752
e8e581bf
ZJS
753/* Macros which append UNIT= or USER_UNIT= to the message */
754
f2341e0a
LP
755#define log_unit_full(unit, level, error, ...) \
756 ({ \
8dec4a9d 757 const Unit *_u = (unit); \
4b58153d 758 _u ? log_object_internal(level, error, __FILE__, __LINE__, __func__, _u->manager->unit_log_field, _u->id, _u->manager->invocation_log_field, _u->invocation_id_string, ##__VA_ARGS__) : \
f2341e0a
LP
759 log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
760 })
761
762#define log_unit_debug(unit, ...) log_unit_full(unit, LOG_DEBUG, 0, ##__VA_ARGS__)
763#define log_unit_info(unit, ...) log_unit_full(unit, LOG_INFO, 0, ##__VA_ARGS__)
764#define log_unit_notice(unit, ...) log_unit_full(unit, LOG_NOTICE, 0, ##__VA_ARGS__)
765#define log_unit_warning(unit, ...) log_unit_full(unit, LOG_WARNING, 0, ##__VA_ARGS__)
766#define log_unit_error(unit, ...) log_unit_full(unit, LOG_ERR, 0, ##__VA_ARGS__)
767
768#define log_unit_debug_errno(unit, error, ...) log_unit_full(unit, LOG_DEBUG, error, ##__VA_ARGS__)
769#define log_unit_info_errno(unit, error, ...) log_unit_full(unit, LOG_INFO, error, ##__VA_ARGS__)
770#define log_unit_notice_errno(unit, error, ...) log_unit_full(unit, LOG_NOTICE, error, ##__VA_ARGS__)
771#define log_unit_warning_errno(unit, error, ...) log_unit_full(unit, LOG_WARNING, error, ##__VA_ARGS__)
772#define log_unit_error_errno(unit, error, ...) log_unit_full(unit, LOG_ERR, error, ##__VA_ARGS__)
773
774#define LOG_UNIT_MESSAGE(unit, fmt, ...) "MESSAGE=%s: " fmt, (unit)->id, ##__VA_ARGS__
775#define LOG_UNIT_ID(unit) (unit)->manager->unit_log_format_string, (unit)->id
f1c50bec 776#define LOG_UNIT_INVOCATION_ID(unit) (unit)->manager->invocation_log_format_string, (unit)->invocation_id_string