]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/manager.h
core: add "invocation ID" concept to service manager
[thirdparty/systemd.git] / src / core / manager.h
CommitLineData
c2f1db8f 1#pragma once
60918275 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
71d35b6b 22#include <libmount.h>
60918275 23#include <stdbool.h>
a66d02c3 24#include <stdio.h>
ea430986 25
718db961
LP
26#include "sd-bus.h"
27#include "sd-event.h"
71d35b6b 28
4ad49000 29#include "cgroup-util.h"
400f1a33 30#include "fdset.h"
2e5c94b9
LP
31#include "hashmap.h"
32#include "list.h"
2e5c94b9 33#include "ratelimit.h"
a16e1123 34
4f0f902f 35/* Enforce upper limit how many names we allow */
59d1a833 36#define MANAGER_MAX_NAMES 131072 /* 128K */
4f0f902f 37
60918275 38typedef struct Manager Manager;
acbb0225 39
f755e3b7 40typedef enum ManagerState {
d81afec1 41 MANAGER_INITIALIZING,
f755e3b7 42 MANAGER_STARTING,
a16e1123 43 MANAGER_RUNNING,
f755e3b7
LP
44 MANAGER_DEGRADED,
45 MANAGER_MAINTENANCE,
46 MANAGER_STOPPING,
47 _MANAGER_STATE_MAX,
48 _MANAGER_STATE_INVALID = -1
49} ManagerState;
50
51typedef enum ManagerExitCode {
52 MANAGER_OK,
a16e1123
LP
53 MANAGER_EXIT,
54 MANAGER_RELOAD,
55 MANAGER_REEXECUTE,
b9080b03
FF
56 MANAGER_REBOOT,
57 MANAGER_POWEROFF,
58 MANAGER_HALT,
59 MANAGER_KEXEC,
664f88a7 60 MANAGER_SWITCH_ROOT,
a16e1123
LP
61 _MANAGER_EXIT_CODE_MAX,
62 _MANAGER_EXIT_CODE_INVALID = -1
63} ManagerExitCode;
64
24dd31c1
LN
65typedef enum CADBurstAction {
66 CAD_BURST_ACTION_IGNORE,
67 CAD_BURST_ACTION_REBOOT,
68 CAD_BURST_ACTION_POWEROFF,
69 _CAD_BURST_ACTION_MAX,
70 _CAD_BURST_ACTION_INVALID = -1
71} CADBurstAction;
72
127d5fd1
ZJS
73typedef enum StatusType {
74 STATUS_TYPE_EPHEMERAL,
75 STATUS_TYPE_NORMAL,
ebc5788e 76 STATUS_TYPE_EMERGENCY,
127d5fd1
ZJS
77} StatusType;
78
400f1a33 79#include "execute.h"
60918275 80#include "job.h"
84e3543e 81#include "path-lookup.h"
4d7213b2 82#include "show-status.h"
400f1a33 83#include "unit-name.h"
60918275
LP
84
85struct Manager {
87f0e418 86 /* Note that the set of units we know of is allowed to be
35b8ca3a 87 * inconsistent. However the subset of it that is loaded may
87d1515d
LP
88 * not, and the list of jobs may neither. */
89
87f0e418
LP
90 /* Active jobs and units */
91 Hashmap *units; /* name string => Unit object n:1 */
4b58153d 92 Hashmap *units_by_invocation_id;
60918275
LP
93 Hashmap *jobs; /* job id => Job object 1:1 */
94
ef734fd6
LP
95 /* To make it easy to iterate through the units of a specific
96 * type we maintain a per type linked list */
ac155bb8 97 LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]);
ef734fd6 98
87f0e418 99 /* Units that need to be loaded */
ac155bb8 100 LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */
60918275 101
034c6ed7
LP
102 /* Jobs that need to be run */
103 LIST_HEAD(Job, run_queue); /* more a stack than a queue, too */
104
c1e1601e
LP
105 /* Units and jobs that have not yet been announced via
106 * D-Bus. When something about a job changes it is added here
107 * if it is not in there yet. This allows easy coalescing of
108 * D-Bus change signals. */
ac155bb8 109 LIST_HEAD(Unit, dbus_unit_queue);
c1e1601e
LP
110 LIST_HEAD(Job, dbus_job_queue);
111
701cc384 112 /* Units to remove */
ac155bb8 113 LIST_HEAD(Unit, cleanup_queue);
23a177ef 114
701cc384 115 /* Units to check when doing GC */
ac155bb8 116 LIST_HEAD(Unit, gc_queue);
701cc384 117
4ad49000
LP
118 /* Units that should be realized */
119 LIST_HEAD(Unit, cgroup_queue);
120
718db961
LP
121 sd_event *event;
122
5ba6985b
LP
123 /* We use two hash tables here, since the same PID might be
124 * watched by two different units: once the unit that forked
125 * it off, and possibly a different unit to which it was
126 * joined as cgroup member. Since we know that it is either
127 * one or two units for each PID we just use to hashmaps
128 * here. */
129 Hashmap *watch_pids1; /* pid => Unit object n:1 */
130 Hashmap *watch_pids2; /* pid => Unit object n:1 */
9152c765 131
95ae05c0
WC
132 /* A set contains all units which cgroup should be refreshed after startup */
133 Set *startup_units;
134
f755e3b7
LP
135 /* A set which contains all currently failed units */
136 Set *failed_units;
137
752b5905
LP
138 sd_event_source *run_queue_event_source;
139
c952c6ec 140 char *notify_socket;
718db961
LP
141 int notify_fd;
142 sd_event_source *notify_event_source;
143
d8fdc620
LP
144 int cgroups_agent_fd;
145 sd_event_source *cgroups_agent_event_source;
146
718db961
LP
147 int signal_fd;
148 sd_event_source *signal_event_source;
c952c6ec 149
718db961
LP
150 int time_change_fd;
151 sd_event_source *time_change_event_source;
9d58f1db 152
718db961 153 sd_event_source *jobs_in_progress_event_source;
acbb0225 154
00d9ef85
LP
155 int user_lookup_fds[2];
156 sd_event_source *user_lookup_event_source;
157
463d0d15 158 UnitFileScope unit_file_scope;
84e3543e 159 LookupPaths lookup_paths;
fe51822e 160 Set *unit_path_cache;
036643a2 161
1137a57c
LP
162 char **environment;
163
e96d6be7
LP
164 usec_t runtime_watchdog;
165 usec_t shutdown_watchdog;
166
915b3753
LP
167 dual_timestamp firmware_timestamp;
168 dual_timestamp loader_timestamp;
169 dual_timestamp kernel_timestamp;
e9ddabc2 170 dual_timestamp initrd_timestamp;
915b3753 171 dual_timestamp userspace_timestamp;
b0c918b9 172 dual_timestamp finish_timestamp;
2928b0a8 173
c2e0d600
TA
174 dual_timestamp security_start_timestamp;
175 dual_timestamp security_finish_timestamp;
518d10e9
UTL
176 dual_timestamp generators_start_timestamp;
177 dual_timestamp generators_finish_timestamp;
718db961
LP
178 dual_timestamp units_load_start_timestamp;
179 dual_timestamp units_load_finish_timestamp;
8d567588 180
25ac040b 181 struct udev* udev;
9670d583
LP
182
183 /* Data specific to the device subsystem */
f94ea366 184 struct udev_monitor* udev_monitor;
718db961 185 sd_event_source *udev_event_source;
8fe914ec 186 Hashmap *devices_by_sysfs;
ef734fd6
LP
187
188 /* Data specific to the mount subsystem */
d379d442 189 struct libmnt_monitor *mount_monitor;
718db961 190 sd_event_source *mount_event_source;
ea430986 191
07b0b134
ML
192 /* Data specific to the swap filesystem */
193 FILE *proc_swaps;
718db961 194 sd_event_source *swap_event_source;
9670d583 195 Hashmap *swaps_by_devnode;
07b0b134 196
ea430986 197 /* Data specific to the D-Bus subsystem */
718db961
LP
198 sd_bus *api_bus, *system_bus;
199 Set *private_buses;
200 int private_listen_fd;
201 sd_event_source *private_listen_event_source;
8f8f05a9
LP
202
203 /* Contains all the clients that are subscribed to signals via
204 the API bus. Note that private bus connections are always
205 considered subscribes, since they last for very short only,
206 and it is much simpler that way. */
207 sd_bus_track *subscribed;
208 char **deserialized_subscribed;
5e8d1c9a 209
8f88ecf6
LP
210 /* This is used during reloading: before the reload we queue
211 * the reply message here, and afterwards we send it */
212 sd_bus_message *queued_message;
8e274523 213
05e343b7 214 Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */
05e343b7 215
71445ae7
LP
216 bool send_reloading_done;
217
7fab9d01 218 uint32_t current_job_id;
bacbccb7 219 uint32_t default_unit_job_id;
7fab9d01 220
9d58f1db
LP
221 /* Data specific to the Automount subsystem */
222 int dev_autofs_fd;
223
8e274523 224 /* Data specific to the cgroup subsystem */
4ad49000 225 Hashmap *cgroup_unit;
efdb0237 226 CGroupMask cgroup_supported;
9444b1f2 227 char *cgroup_root;
e537352b 228
efdb0237
LP
229 /* Notifications from cgroups, when the unified hierarchy is
230 * used is done via inotify. */
231 int cgroup_inotify_fd;
232 sd_event_source *cgroup_inotify_event_source;
233 Hashmap *cgroup_inotify_wd_unit;
701cc384 234
35b8ca3a 235 /* Make sure the user cannot accidentally unmount our cgroup
33be102a
LP
236 * file system */
237 int pin_cgroupfs_fd;
238
efdb0237
LP
239 int gc_marker;
240 unsigned n_in_gc_queue;
241
9d58f1db 242 /* Flags */
b9080b03 243 ManagerExitCode exit_code:5;
41447faf 244
9d58f1db 245 bool dispatching_load_queue:1;
9d58f1db
LP
246 bool dispatching_dbus_queue:1;
247
72bc8d00 248 bool taint_usr:1;
0d8c31ff
ZJS
249 bool test_run:1;
250
287419c1
AC
251 /* If non-zero, exit with the following value when the systemd
252 * process terminate. Useful for containers: systemd-nspawn could get
253 * the return value. */
254 uint8_t return_value;
255
d450b6f2 256 ShowStatus show_status;
f295f5c0 257 bool confirm_spawn;
31a7eb86 258 bool no_console_output;
d3689161 259
0a494f1f
LP
260 ExecOutput default_std_output, default_std_error;
261
085afe36 262 usec_t default_restart_usec, default_timeout_start_usec, default_timeout_stop_usec;
1f19a534 263
3f41e1e5
LN
264 usec_t default_start_limit_interval;
265 unsigned default_start_limit_burst;
266
085afe36
LP
267 bool default_cpu_accounting;
268 bool default_memory_accounting;
13c31542 269 bool default_io_accounting;
085afe36 270 bool default_blockio_accounting;
03a7b521 271 bool default_tasks_accounting;
085afe36 272
0af20ea2 273 uint64_t default_tasks_max;
bd8f585b
LP
274 usec_t default_timer_accuracy_usec;
275
517d56b1 276 struct rlimit *rlimit[_RLIMIT_MAX];
c93ff2e9 277
a7556052
LP
278 /* non-zero if we are reloading or reexecuting, */
279 int n_reloading;
e409f875
LP
280
281 unsigned n_installed_jobs;
76bf48b7 282 unsigned n_failed_jobs;
f2b68789 283
03b717a3 284 /* Jobs in progress watching */
637f8b8e 285 unsigned n_running_jobs;
7ed9f6cd 286 unsigned n_on_console;
03b717a3 287 unsigned jobs_in_progress_iteration;
637f8b8e 288
e46b13c8
ZJS
289 /* Do we have any outstanding password prompts? */
290 int have_ask_password;
291 int ask_password_inotify_fd;
292 sd_event_source *ask_password_event_source;
293
f2b68789 294 /* Type=idle pipes */
31a7eb86 295 int idle_pipe[4];
718db961 296 sd_event_source *idle_pipe_event_source;
664f88a7
LP
297
298 char *switch_root;
299 char *switch_root_init;
a57f7e2c
LP
300
301 /* This maps all possible path prefixes to the units needing
302 * them. It's a hashmap with a path string as key and a Set as
303 * value where Unit objects are contained. */
304 Hashmap *units_requiring_mounts_for;
e3dd987c 305
283868e1
SW
306 /* Used for processing polkit authorization responses */
307 Hashmap *polkit_registry;
2e5c94b9 308
29206d46
LP
309 /* Dynamic users/groups, indexed by their name */
310 Hashmap *dynamic_users;
311
00d9ef85
LP
312 /* Keep track of all UIDs and GIDs any of our services currently use. This is useful for the RemoveIPC= logic. */
313 Hashmap *uid_refs;
314 Hashmap *gid_refs;
315
24dd31c1 316 /* When the user hits C-A-D more than 7 times per 2s, do something immediately... */
2e5c94b9 317 RateLimit ctrl_alt_del_ratelimit;
24dd31c1 318 CADBurstAction cad_burst_action;
f2341e0a
LP
319
320 const char *unit_log_field;
321 const char *unit_log_format_string;
ae2a2c53 322
4b58153d
LP
323 const char *invocation_log_field;
324 const char *invocation_log_format_string;
325
463d0d15 326 int first_boot; /* tri-state */
60918275
LP
327};
328
463d0d15
LP
329#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)
330#define MANAGER_IS_USER(m) ((m)->unit_file_scope != UNIT_FILE_SYSTEM)
331
2c289ea8
LP
332#define MANAGER_IS_RELOADING(m) ((m)->n_reloading > 0)
333
463d0d15 334int manager_new(UnitFileScope scope, bool test_run, Manager **m);
06d8d842 335Manager* manager_free(Manager *m);
60918275 336
ba64af90 337void manager_enumerate(Manager *m);
a16e1123 338int manager_startup(Manager *m, FILE *serialization, FDSet *fds);
f50e0a01 339
60918275 340Job *manager_get_job(Manager *m, uint32_t id);
87f0e418 341Unit *manager_get_unit(Manager *m, const char *name);
60918275 342
86fbf370 343int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j);
ea430986 344
718db961
LP
345int manager_load_unit_prepare(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
346int manager_load_unit(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
347int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u);
28247076 348
4bd29fe5
LP
349int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret);
350int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, sd_bus_error *e, Job **_ret);
53f18416 351int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Job **ret);
60918275 352
87f0e418 353void manager_dump_units(Manager *s, FILE *f, const char *prefix);
cea8e32e 354void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
a66d02c3 355
7fad411c
LP
356void manager_clear_jobs(Manager *m);
357
c1e1601e 358unsigned manager_dispatch_load_queue(Manager *m);
f50e0a01 359
718db961 360int manager_environment_add(Manager *m, char **minus, char **plus);
c93ff2e9 361int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
b2bb3dbe 362
9152c765 363int manager_loop(Manager *m);
83c60c9f 364
d8d5ab98 365int manager_open_serialization(Manager *m, FILE **_f);
a16e1123 366
b3680f49 367int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
a16e1123
LP
368int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
369
370int manager_reload(Manager *m);
371
fdf20a31 372void manager_reset_failed(Manager *m);
5632e374 373
4927fcae 374void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success);
e983b760 375void manager_send_unit_plymouth(Manager *m, Unit *u);
4927fcae 376
31afa0a4 377bool manager_unit_inactive_or_pending(Manager *m, const char *name);
8f6df3fa 378
b0c918b9
LP
379void manager_check_finished(Manager *m);
380
4cfa2c99 381void manager_recheck_journal(Manager *m);
f1dd0c3f 382
d450b6f2 383void manager_set_show_status(Manager *m, ShowStatus mode);
e2680723
LP
384void manager_set_first_boot(Manager *m, bool b);
385
127d5fd1 386void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
cb8ccb22 387void manager_flip_auto_status(Manager *m, bool enable);
68b29a9f 388
a57f7e2c 389Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
e66cf1a3
LP
390
391const char *manager_get_runtime_prefix(Manager *m);
f755e3b7
LP
392
393ManagerState manager_state(Manager *m);
394
5269eb6b 395int manager_update_failed_units(Manager *m, Unit *u, bool failed);
03455c28 396
00d9ef85
LP
397void manager_unref_uid(Manager *m, uid_t uid, bool destroy_now);
398int manager_ref_uid(Manager *m, uid_t uid, bool clean_ipc);
399
400void manager_unref_gid(Manager *m, gid_t gid, bool destroy_now);
401int manager_ref_gid(Manager *m, gid_t gid, bool destroy_now);
402
403void manager_vacuum_uid_refs(Manager *m);
404void manager_vacuum_gid_refs(Manager *m);
405
406void manager_serialize_uid_refs(Manager *m, FILE *f);
407void manager_deserialize_uid_refs_one(Manager *m, const char *value);
408
409void manager_serialize_gid_refs(Manager *m, FILE *f);
410void manager_deserialize_gid_refs_one(Manager *m, const char *value);
411
f755e3b7
LP
412const char *manager_state_to_string(ManagerState m) _const_;
413ManagerState manager_state_from_string(const char *s) _pure_;
24dd31c1
LN
414
415const char *cad_burst_action_to_string(CADBurstAction a) _const_;
416CADBurstAction cad_burst_action_from_string(const char *s) _pure_;