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