]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/manager.h
tree-wide: remove Lennart's copyright lines
[thirdparty/systemd.git] / src / core / manager.h
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
c2f1db8f 2#pragma once
60918275
LP
3
4#include <stdbool.h>
a66d02c3 5#include <stdio.h>
ea430986 6
718db961
LP
7#include "sd-bus.h"
8#include "sd-event.h"
71d35b6b 9
4ad49000 10#include "cgroup-util.h"
400f1a33 11#include "fdset.h"
2e5c94b9 12#include "hashmap.h"
6a48d82f 13#include "ip-address-access.h"
2e5c94b9 14#include "list.h"
2e5c94b9 15#include "ratelimit.h"
a16e1123 16
227b8a76 17struct libmnt_monitor;
57b7a260 18typedef struct Unit Unit;
227b8a76 19
4f0f902f 20/* Enforce upper limit how many names we allow */
59d1a833 21#define MANAGER_MAX_NAMES 131072 /* 128K */
4f0f902f 22
60918275 23typedef struct Manager Manager;
acbb0225 24
f755e3b7 25typedef enum ManagerState {
d81afec1 26 MANAGER_INITIALIZING,
f755e3b7 27 MANAGER_STARTING,
a16e1123 28 MANAGER_RUNNING,
f755e3b7
LP
29 MANAGER_DEGRADED,
30 MANAGER_MAINTENANCE,
31 MANAGER_STOPPING,
32 _MANAGER_STATE_MAX,
33 _MANAGER_STATE_INVALID = -1
34} ManagerState;
35
36typedef enum ManagerExitCode {
37 MANAGER_OK,
a16e1123
LP
38 MANAGER_EXIT,
39 MANAGER_RELOAD,
40 MANAGER_REEXECUTE,
b9080b03
FF
41 MANAGER_REBOOT,
42 MANAGER_POWEROFF,
43 MANAGER_HALT,
44 MANAGER_KEXEC,
664f88a7 45 MANAGER_SWITCH_ROOT,
a16e1123
LP
46 _MANAGER_EXIT_CODE_MAX,
47 _MANAGER_EXIT_CODE_INVALID = -1
48} ManagerExitCode;
49
127d5fd1
ZJS
50typedef enum StatusType {
51 STATUS_TYPE_EPHEMERAL,
52 STATUS_TYPE_NORMAL,
ebc5788e 53 STATUS_TYPE_EMERGENCY,
127d5fd1
ZJS
54} StatusType;
55
9f9f0342
LP
56typedef enum ManagerTimestamp {
57 MANAGER_TIMESTAMP_FIRMWARE,
58 MANAGER_TIMESTAMP_LOADER,
59 MANAGER_TIMESTAMP_KERNEL,
60 MANAGER_TIMESTAMP_INITRD,
61 MANAGER_TIMESTAMP_USERSPACE,
62 MANAGER_TIMESTAMP_FINISH,
63
64 MANAGER_TIMESTAMP_SECURITY_START,
65 MANAGER_TIMESTAMP_SECURITY_FINISH,
66 MANAGER_TIMESTAMP_GENERATORS_START,
67 MANAGER_TIMESTAMP_GENERATORS_FINISH,
68 MANAGER_TIMESTAMP_UNITS_LOAD_START,
69 MANAGER_TIMESTAMP_UNITS_LOAD_FINISH,
70 _MANAGER_TIMESTAMP_MAX,
71 _MANAGER_TIMESTAMP_INVALID = -1,
72} ManagerTimestamp;
73
400f1a33 74#include "execute.h"
60918275 75#include "job.h"
84e3543e 76#include "path-lookup.h"
4d7213b2 77#include "show-status.h"
400f1a33 78#include "unit-name.h"
60918275 79
e0a3da1f
ZJS
80enum {
81 /* 0 = run normally */
e8112e67
ZJS
82 MANAGER_TEST_RUN_MINIMAL = 1 << 1, /* create basic data structures */
83 MANAGER_TEST_RUN_BASIC = 1 << 2, /* interact with the environment */
84 MANAGER_TEST_RUN_ENV_GENERATORS = 1 << 3, /* also run env generators */
85 MANAGER_TEST_RUN_GENERATORS = 1 << 4, /* also run unit generators */
86 MANAGER_TEST_FULL = MANAGER_TEST_RUN_BASIC | MANAGER_TEST_RUN_ENV_GENERATORS | MANAGER_TEST_RUN_GENERATORS,
e0a3da1f
ZJS
87};
88assert_cc((MANAGER_TEST_FULL & UINT8_MAX) == MANAGER_TEST_FULL);
89
60918275 90struct Manager {
87f0e418 91 /* Note that the set of units we know of is allowed to be
35b8ca3a 92 * inconsistent. However the subset of it that is loaded may
87d1515d
LP
93 * not, and the list of jobs may neither. */
94
87f0e418
LP
95 /* Active jobs and units */
96 Hashmap *units; /* name string => Unit object n:1 */
4b58153d 97 Hashmap *units_by_invocation_id;
60918275
LP
98 Hashmap *jobs; /* job id => Job object 1:1 */
99
ef734fd6
LP
100 /* To make it easy to iterate through the units of a specific
101 * type we maintain a per type linked list */
ac155bb8 102 LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]);
ef734fd6 103
87f0e418 104 /* Units that need to be loaded */
ac155bb8 105 LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */
60918275 106
034c6ed7
LP
107 /* Jobs that need to be run */
108 LIST_HEAD(Job, run_queue); /* more a stack than a queue, too */
109
c1e1601e
LP
110 /* Units and jobs that have not yet been announced via
111 * D-Bus. When something about a job changes it is added here
112 * if it is not in there yet. This allows easy coalescing of
113 * D-Bus change signals. */
ac155bb8 114 LIST_HEAD(Unit, dbus_unit_queue);
c1e1601e
LP
115 LIST_HEAD(Job, dbus_job_queue);
116
701cc384 117 /* Units to remove */
ac155bb8 118 LIST_HEAD(Unit, cleanup_queue);
23a177ef 119
c5a97ed1
LP
120 /* Units and jobs to check when doing GC */
121 LIST_HEAD(Unit, gc_unit_queue);
122 LIST_HEAD(Job, gc_job_queue);
701cc384 123
4ad49000 124 /* Units that should be realized */
91a6073e 125 LIST_HEAD(Unit, cgroup_realize_queue);
4ad49000 126
09e24654
LP
127 /* Units whose cgroup ran empty */
128 LIST_HEAD(Unit, cgroup_empty_queue);
129
19496554
MS
130 /* Target units whose default target dependencies haven't been set yet */
131 LIST_HEAD(Unit, target_deps_queue);
132
718db961
LP
133 sd_event *event;
134
62a76913
LP
135 /* This maps PIDs we care about to units that are interested in. We allow multiple units to he interested in
136 * the same PID and multiple PIDs to be relevant to the same unit. Since in most cases only a single unit will
137 * be interested in the same PID we use a somewhat special encoding here: the first unit interested in a PID is
138 * stored directly in the hashmap, keyed by the PID unmodified. If there are other units interested too they'll
139 * be stored in a NULL-terminated array, and keyed by the negative PID. This is safe as pid_t is signed and
140 * negative PIDs are not used for regular processes but process groups, which we don't care about in this
141 * context, but this allows us to use the negative range for our own purposes. */
142 Hashmap *watch_pids; /* pid => unit as well as -pid => array of units */
9152c765 143
95ae05c0
WC
144 /* A set contains all units which cgroup should be refreshed after startup */
145 Set *startup_units;
146
f755e3b7
LP
147 /* A set which contains all currently failed units */
148 Set *failed_units;
149
752b5905
LP
150 sd_event_source *run_queue_event_source;
151
c952c6ec 152 char *notify_socket;
718db961
LP
153 int notify_fd;
154 sd_event_source *notify_event_source;
155
d8fdc620
LP
156 int cgroups_agent_fd;
157 sd_event_source *cgroups_agent_event_source;
158
718db961
LP
159 int signal_fd;
160 sd_event_source *signal_event_source;
c952c6ec 161
575b300b
LP
162 sd_event_source *sigchld_event_source;
163
718db961
LP
164 int time_change_fd;
165 sd_event_source *time_change_event_source;
9d58f1db 166
bbf5fd8e
LP
167 sd_event_source *timezone_change_event_source;
168
718db961 169 sd_event_source *jobs_in_progress_event_source;
acbb0225 170
00d9ef85
LP
171 int user_lookup_fds[2];
172 sd_event_source *user_lookup_event_source;
173
5f109056
LP
174 sd_event_source *sync_bus_names_event_source;
175
463d0d15 176 UnitFileScope unit_file_scope;
84e3543e 177 LookupPaths lookup_paths;
fe51822e 178 Set *unit_path_cache;
036643a2 179
1137a57c
LP
180 char **environment;
181
e96d6be7
LP
182 usec_t runtime_watchdog;
183 usec_t shutdown_watchdog;
184
9f9f0342 185 dual_timestamp timestamps[_MANAGER_TIMESTAMP_MAX];
8d567588 186
25ac040b 187 struct udev* udev;
9670d583
LP
188
189 /* Data specific to the device subsystem */
f94ea366 190 struct udev_monitor* udev_monitor;
718db961 191 sd_event_source *udev_event_source;
8fe914ec 192 Hashmap *devices_by_sysfs;
ef734fd6
LP
193
194 /* Data specific to the mount subsystem */
d379d442 195 struct libmnt_monitor *mount_monitor;
718db961 196 sd_event_source *mount_event_source;
ea430986 197
07b0b134
ML
198 /* Data specific to the swap filesystem */
199 FILE *proc_swaps;
718db961 200 sd_event_source *swap_event_source;
9670d583 201 Hashmap *swaps_by_devnode;
07b0b134 202
ea430986 203 /* Data specific to the D-Bus subsystem */
718db961
LP
204 sd_bus *api_bus, *system_bus;
205 Set *private_buses;
206 int private_listen_fd;
207 sd_event_source *private_listen_event_source;
8f8f05a9
LP
208
209 /* Contains all the clients that are subscribed to signals via
210 the API bus. Note that private bus connections are always
211 considered subscribes, since they last for very short only,
212 and it is much simpler that way. */
213 sd_bus_track *subscribed;
214 char **deserialized_subscribed;
5e8d1c9a 215
8f88ecf6
LP
216 /* This is used during reloading: before the reload we queue
217 * the reply message here, and afterwards we send it */
218 sd_bus_message *queued_message;
8e274523 219
05e343b7 220 Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */
05e343b7 221
71445ae7
LP
222 bool send_reloading_done;
223
7fab9d01 224 uint32_t current_job_id;
bacbccb7 225 uint32_t default_unit_job_id;
7fab9d01 226
9d58f1db
LP
227 /* Data specific to the Automount subsystem */
228 int dev_autofs_fd;
229
8e274523 230 /* Data specific to the cgroup subsystem */
4ad49000 231 Hashmap *cgroup_unit;
efdb0237 232 CGroupMask cgroup_supported;
9444b1f2 233 char *cgroup_root;
e537352b 234
09e24654 235 /* Notifications from cgroups, when the unified hierarchy is used is done via inotify. */
efdb0237
LP
236 int cgroup_inotify_fd;
237 sd_event_source *cgroup_inotify_event_source;
238 Hashmap *cgroup_inotify_wd_unit;
701cc384 239
09e24654
LP
240 /* A defer event for handling cgroup empty events and processing them after SIGCHLD in all cases. */
241 sd_event_source *cgroup_empty_event_source;
242
35b8ca3a 243 /* Make sure the user cannot accidentally unmount our cgroup
33be102a
LP
244 * file system */
245 int pin_cgroupfs_fd;
246
892a035c 247 unsigned gc_marker;
efdb0237 248
bbf5fd8e
LP
249 /* The stat() data the last time we saw /etc/localtime */
250 usec_t etc_localtime_mtime;
251 bool etc_localtime_accessible:1;
252
9d58f1db 253 /* Flags */
b9080b03 254 ManagerExitCode exit_code:5;
41447faf 255
9d58f1db 256 bool dispatching_load_queue:1;
9d58f1db
LP
257 bool dispatching_dbus_queue:1;
258
72bc8d00 259 bool taint_usr:1;
e0a3da1f 260
d8eb10d6 261 /* Have we already sent out the READY=1 notification? */
0c2826c6
ZJS
262 bool ready_sent:1;
263
d8eb10d6
ZJS
264 /* Have we already printed the taint line if necessary? */
265 bool taint_logged:1;
266
00b5974f
LP
267 /* Have we ever changed the "kernel.pid_max" sysctl? */
268 bool sysctl_pid_max_changed:1;
269
e0a3da1f 270 unsigned test_run_flags:8;
0d8c31ff 271
287419c1
AC
272 /* If non-zero, exit with the following value when the systemd
273 * process terminate. Useful for containers: systemd-nspawn could get
274 * the return value. */
275 uint8_t return_value;
276
d450b6f2 277 ShowStatus show_status;
7d5ceb64 278 char *confirm_spawn;
31a7eb86 279 bool no_console_output;
2a12e32e 280 bool service_watchdogs;
d3689161 281
0a494f1f
LP
282 ExecOutput default_std_output, default_std_error;
283
085afe36 284 usec_t default_restart_usec, default_timeout_start_usec, default_timeout_stop_usec;
1f19a534 285
3f41e1e5
LN
286 usec_t default_start_limit_interval;
287 unsigned default_start_limit_burst;
288
085afe36
LP
289 bool default_cpu_accounting;
290 bool default_memory_accounting;
13c31542 291 bool default_io_accounting;
085afe36 292 bool default_blockio_accounting;
03a7b521 293 bool default_tasks_accounting;
377bfd2d 294 bool default_ip_accounting;
085afe36 295
0af20ea2 296 uint64_t default_tasks_max;
bd8f585b
LP
297 usec_t default_timer_accuracy_usec;
298
a6ecbf83 299 int original_log_level;
bda7d78b 300 LogTarget original_log_target;
a6ecbf83 301 bool log_level_overridden:1;
bda7d78b 302 bool log_target_overridden:1;
a6ecbf83 303
517d56b1 304 struct rlimit *rlimit[_RLIMIT_MAX];
c93ff2e9 305
a7556052
LP
306 /* non-zero if we are reloading or reexecuting, */
307 int n_reloading;
a7a7163d
DT
308 /* A set which contains all jobs that started before reload and finished
309 * during it */
310 Set *pending_finished_jobs;
e409f875
LP
311
312 unsigned n_installed_jobs;
76bf48b7 313 unsigned n_failed_jobs;
f2b68789 314
03b717a3 315 /* Jobs in progress watching */
637f8b8e 316 unsigned n_running_jobs;
7ed9f6cd 317 unsigned n_on_console;
03b717a3 318 unsigned jobs_in_progress_iteration;
637f8b8e 319
e46b13c8
ZJS
320 /* Do we have any outstanding password prompts? */
321 int have_ask_password;
322 int ask_password_inotify_fd;
323 sd_event_source *ask_password_event_source;
324
f2b68789 325 /* Type=idle pipes */
31a7eb86 326 int idle_pipe[4];
718db961 327 sd_event_source *idle_pipe_event_source;
664f88a7
LP
328
329 char *switch_root;
330 char *switch_root_init;
a57f7e2c
LP
331
332 /* This maps all possible path prefixes to the units needing
333 * them. It's a hashmap with a path string as key and a Set as
334 * value where Unit objects are contained. */
335 Hashmap *units_requiring_mounts_for;
e3dd987c 336
283868e1
SW
337 /* Used for processing polkit authorization responses */
338 Hashmap *polkit_registry;
2e5c94b9 339
29206d46
LP
340 /* Dynamic users/groups, indexed by their name */
341 Hashmap *dynamic_users;
342
00d9ef85
LP
343 /* Keep track of all UIDs and GIDs any of our services currently use. This is useful for the RemoveIPC= logic. */
344 Hashmap *uid_refs;
345 Hashmap *gid_refs;
346
e8a565cb
YW
347 /* ExecRuntime, indexed by their owner unit id */
348 Hashmap *exec_runtime_by_id;
349
24dd31c1 350 /* When the user hits C-A-D more than 7 times per 2s, do something immediately... */
2e5c94b9 351 RateLimit ctrl_alt_del_ratelimit;
ae8c7939 352 EmergencyAction cad_burst_action;
f2341e0a
LP
353
354 const char *unit_log_field;
355 const char *unit_log_format_string;
ae2a2c53 356
4b58153d
LP
357 const char *invocation_log_field;
358 const char *invocation_log_format_string;
359
463d0d15 360 int first_boot; /* tri-state */
3536f49e 361
62a76913 362 /* Prefixes of e.g. RuntimeDirectory= */
72fd1768 363 char *prefix[_EXEC_DIRECTORY_TYPE_MAX];
62a76913
LP
364
365 /* Used in the SIGCHLD and sd_notify() message invocation logic to avoid that we dispatch the same event
366 * multiple times on the same unit. */
367 unsigned sigchldgen;
368 unsigned notifygen;
60918275
LP
369};
370
463d0d15
LP
371#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)
372#define MANAGER_IS_USER(m) ((m)->unit_file_scope != UNIT_FILE_SYSTEM)
373
2c289ea8
LP
374#define MANAGER_IS_RELOADING(m) ((m)->n_reloading > 0)
375
49d5666c
LP
376#define MANAGER_IS_FINISHED(m) (dual_timestamp_is_set((m)->timestamps + MANAGER_TIMESTAMP_FINISH))
377
4259d202
LP
378/* The exit code is set to OK as soon as we enter the main loop, and set otherwise as soon as we are done with it */
379#define MANAGER_IS_RUNNING(m) ((m)->exit_code == MANAGER_OK)
380
e0a3da1f 381int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **m);
06d8d842 382Manager* manager_free(Manager *m);
c70cac54 383DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
60918275 384
a16e1123 385int manager_startup(Manager *m, FILE *serialization, FDSet *fds);
f50e0a01 386
60918275 387Job *manager_get_job(Manager *m, uint32_t id);
87f0e418 388Unit *manager_get_unit(Manager *m, const char *name);
60918275 389
86fbf370 390int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j);
ea430986 391
718db961
LP
392int manager_load_unit_prepare(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
393int manager_load_unit(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
4109ede7 394int manager_load_startable_unit_or_warn(Manager *m, const char *name, const char *path, Unit **ret);
718db961 395int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u);
28247076 396
4bd29fe5
LP
397int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret);
398int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, sd_bus_error *e, Job **_ret);
53f18416 399int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Job **ret);
15d167f8 400int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e);
60918275 401
87f0e418 402void manager_dump_units(Manager *s, FILE *f, const char *prefix);
cea8e32e 403void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
ad75b9e7 404void manager_dump(Manager *s, FILE *f, const char *prefix);
713f6f90 405int manager_get_dump_string(Manager *m, char **ret);
a66d02c3 406
7fad411c
LP
407void manager_clear_jobs(Manager *m);
408
c1e1601e 409unsigned manager_dispatch_load_queue(Manager *m);
f50e0a01 410
718db961 411int manager_environment_add(Manager *m, char **minus, char **plus);
c93ff2e9 412int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
b2bb3dbe 413
9152c765 414int manager_loop(Manager *m);
83c60c9f 415
d8d5ab98 416int manager_open_serialization(Manager *m, FILE **_f);
a16e1123 417
b3680f49 418int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
a16e1123
LP
419int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
420
421int manager_reload(Manager *m);
422
fdf20a31 423void manager_reset_failed(Manager *m);
5632e374 424
4927fcae 425void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success);
e983b760 426void manager_send_unit_plymouth(Manager *m, Unit *u);
4927fcae 427
31afa0a4 428bool manager_unit_inactive_or_pending(Manager *m, const char *name);
8f6df3fa 429
b0c918b9
LP
430void manager_check_finished(Manager *m);
431
8559b3b7 432void manager_recheck_dbus(Manager *m);
4cfa2c99 433void manager_recheck_journal(Manager *m);
f1dd0c3f 434
d450b6f2 435void manager_set_show_status(Manager *m, ShowStatus mode);
e2680723
LP
436void manager_set_first_boot(Manager *m, bool b);
437
127d5fd1 438void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
cb8ccb22 439void manager_flip_auto_status(Manager *m, bool enable);
68b29a9f 440
a57f7e2c 441Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
e66cf1a3 442
f755e3b7
LP
443ManagerState manager_state(Manager *m);
444
5269eb6b 445int manager_update_failed_units(Manager *m, Unit *u, bool failed);
03455c28 446
00d9ef85
LP
447void manager_unref_uid(Manager *m, uid_t uid, bool destroy_now);
448int manager_ref_uid(Manager *m, uid_t uid, bool clean_ipc);
449
450void manager_unref_gid(Manager *m, gid_t gid, bool destroy_now);
451int manager_ref_gid(Manager *m, gid_t gid, bool destroy_now);
452
453void manager_vacuum_uid_refs(Manager *m);
454void manager_vacuum_gid_refs(Manager *m);
455
456void manager_serialize_uid_refs(Manager *m, FILE *f);
457void manager_deserialize_uid_refs_one(Manager *m, const char *value);
458
459void manager_serialize_gid_refs(Manager *m, FILE *f);
460void manager_deserialize_gid_refs_one(Manager *m, const char *value);
461
af6b0ecc
LP
462char *manager_taint_string(Manager *m);
463
adefcf28
LP
464void manager_ref_console(Manager *m);
465void manager_unref_console(Manager *m);
466
a6ecbf83
FB
467void manager_override_log_level(Manager *m, int level);
468void manager_restore_original_log_level(Manager *m);
469
bda7d78b
FB
470void manager_override_log_target(Manager *m, LogTarget target);
471void manager_restore_original_log_target(Manager *m);
472
f755e3b7
LP
473const char *manager_state_to_string(ManagerState m) _const_;
474ManagerState manager_state_from_string(const char *s) _pure_;
7d5ceb64
FB
475
476const char *manager_get_confirm_spawn(Manager *m);
b0eb2944
FB
477bool manager_is_confirm_spawn_disabled(Manager *m);
478void manager_disable_confirm_spawn(void);
9f9f0342
LP
479
480const char *manager_timestamp_to_string(ManagerTimestamp m) _const_;
481ManagerTimestamp manager_timestamp_from_string(const char *s) _pure_;