]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/manager.c
core: don't reference rescue/emergency targets in --user mode
[thirdparty/systemd.git] / src / core / manager.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a7334b09
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 15 Lesser General Public License for more details.
a7334b09 16
5430f7f2 17 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
60918275 21#include <errno.h>
400f1a33
LP
22#include <fcntl.h>
23#include <linux/kd.h>
9152c765 24#include <signal.h>
713f6f90 25#include <stdio_ext.h>
400f1a33 26#include <string.h>
e46b13c8 27#include <sys/epoll.h>
400f1a33 28#include <sys/inotify.h>
e1414003 29#include <sys/ioctl.h>
400f1a33 30#include <sys/reboot.h>
8742514c 31#include <sys/timerfd.h>
400f1a33
LP
32#include <sys/wait.h>
33#include <unistd.h>
830f6caa 34
349cc4a5 35#if HAVE_AUDIT
4927fcae 36#include <libaudit.h>
830f6caa 37#endif
60918275 38
718db961 39#include "sd-daemon.h"
718db961 40#include "sd-messages.h"
3536f49e 41#include "sd-path.h"
81527be1 42
b5efdb8a 43#include "alloc-util.h"
400f1a33
LP
44#include "audit-fd.h"
45#include "boot-timestamps.h"
46#include "bus-common-errors.h"
47#include "bus-error.h"
48#include "bus-kernel.h"
49#include "bus-util.h"
00d9ef85 50#include "clean-ipc.h"
400f1a33
LP
51#include "dbus-job.h"
52#include "dbus-manager.h"
53#include "dbus-unit.h"
54#include "dbus.h"
d063a527 55#include "dirent-util.h"
400f1a33 56#include "env-util.h"
4f5dd394 57#include "escape.h"
89711996 58#include "exec-util.h"
d3070fbd 59#include "execute.h"
400f1a33 60#include "exit-status.h"
3ffd4af2 61#include "fd-util.h"
0d39fa9c 62#include "fileio.h"
f4f15635 63#include "fs-util.h"
60918275 64#include "hashmap.h"
c004493c 65#include "io-util.h"
d3070fbd 66#include "label.h"
400f1a33 67#include "locale-setup.h"
16354eff 68#include "log.h"
400f1a33 69#include "macro.h"
3ffd4af2 70#include "manager.h"
400f1a33 71#include "missing.h"
49e942b2 72#include "mkdir.h"
6bedfcbb 73#include "parse-util.h"
400f1a33
LP
74#include "path-lookup.h"
75#include "path-util.h"
76#include "process-util.h"
ea430986 77#include "ratelimit.h"
c6878637 78#include "rm-rf.h"
400f1a33 79#include "signal-util.h"
514f4ef5 80#include "special.h"
8fcde012 81#include "stat-util.h"
8b43440b 82#include "string-table.h"
07630cea 83#include "string-util.h"
400f1a33
LP
84#include "strv.h"
85#include "terminal-util.h"
86#include "time-util.h"
87#include "transaction.h"
affb60b1 88#include "umask-util.h"
400f1a33 89#include "unit-name.h"
00d9ef85 90#include "user-util.h"
400f1a33 91#include "util.h"
5dc4c17f 92#include "virt.h"
e96d6be7 93#include "watchdog.h"
60918275 94
a47806fa 95#define NOTIFY_RCVBUF_SIZE (8*1024*1024)
d8fdc620 96#define CGROUPS_AGENT_RCVBUF_SIZE (8*1024*1024)
a47806fa 97
03b717a3 98/* Initial delay and the interval for printing status messages about running jobs */
fd08a840
ZJS
99#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
100#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
03b717a3
MS
101#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
102
718db961 103static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
d8fdc620 104static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
718db961
LP
105static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
106static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
107static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
00d9ef85 108static int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
718db961 109static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
752b5905 110static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
64691d20 111static int manager_run_environment_generators(Manager *m);
e801700e 112static int manager_run_generators(Manager *m);
718db961 113
2ae56591 114static void manager_watch_jobs_in_progress(Manager *m) {
e5723c89 115 usec_t next;
cfa9677b 116 int r;
e5723c89 117
718db961 118 assert(m);
03b717a3 119
42bf1ae1
FB
120 /* We do not want to show the cylon animation if the user
121 * needs to confirm service executions otherwise confirmation
122 * messages will be screwed by the cylon animation. */
b0eb2944 123 if (!manager_is_confirm_spawn_disabled(m))
42bf1ae1
FB
124 return;
125
718db961 126 if (m->jobs_in_progress_event_source)
2ae56591 127 return;
03b717a3 128
e5723c89 129 next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
cfa9677b 130 r = sd_event_add_time(
6a0f1f6d
LP
131 m->event,
132 &m->jobs_in_progress_event_source,
133 CLOCK_MONOTONIC,
134 next, 0,
135 manager_dispatch_jobs_in_progress, m);
cfa9677b
MM
136 if (r < 0)
137 return;
7dfbe2e3
TG
138
139 (void) sd_event_source_set_description(m->jobs_in_progress_event_source, "manager-jobs-in-progress");
03b717a3
MS
140}
141
1fc464f6 142#define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED)-1) + sizeof(ANSI_HIGHLIGHT_RED)-1 + 2*(sizeof(ANSI_NORMAL)-1))
03b717a3 143
03b717a3
MS
144static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
145 char *p = buffer;
146
147 assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
148 assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
149
150 if (pos > 1) {
6282c859
MS
151 if (pos > 2)
152 p = mempset(p, ' ', pos-2);
64c3610b
FB
153 if (log_get_show_color())
154 p = stpcpy(p, ANSI_RED);
03b717a3
MS
155 *p++ = '*';
156 }
157
158 if (pos > 0 && pos <= width) {
64c3610b
FB
159 if (log_get_show_color())
160 p = stpcpy(p, ANSI_HIGHLIGHT_RED);
03b717a3
MS
161 *p++ = '*';
162 }
163
64c3610b
FB
164 if (log_get_show_color())
165 p = stpcpy(p, ANSI_NORMAL);
03b717a3
MS
166
167 if (pos < width) {
64c3610b
FB
168 if (log_get_show_color())
169 p = stpcpy(p, ANSI_RED);
03b717a3 170 *p++ = '*';
6282c859
MS
171 if (pos < width-1)
172 p = mempset(p, ' ', width-1-pos);
64c3610b
FB
173 if (log_get_show_color())
174 strcpy(p, ANSI_NORMAL);
03b717a3 175 }
03b717a3
MS
176}
177
cb8ccb22 178void manager_flip_auto_status(Manager *m, bool enable) {
f755e3b7
LP
179 assert(m);
180
cb8ccb22
ZJS
181 if (enable) {
182 if (m->show_status == SHOW_STATUS_AUTO)
183 manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
184 } else {
185 if (m->show_status == SHOW_STATUS_TEMPORARY)
186 manager_set_show_status(m, SHOW_STATUS_AUTO);
187 }
188}
189
03b717a3 190static void manager_print_jobs_in_progress(Manager *m) {
718db961 191 _cleanup_free_ char *job_of_n = NULL;
03b717a3
MS
192 Iterator i;
193 Job *j;
03b717a3
MS
194 unsigned counter = 0, print_nr;
195 char cylon[6 + CYLON_BUFFER_EXTRA + 1];
196 unsigned cylon_pos;
8bb310c3
ZJS
197 char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
198 uint64_t x;
03b717a3 199
718db961 200 assert(m);
9c3349e2 201 assert(m->n_running_jobs > 0);
718db961 202
cb8ccb22 203 manager_flip_auto_status(m, true);
d450b6f2 204
03b717a3
MS
205 print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
206
207 HASHMAP_FOREACH(j, m->jobs, i)
208 if (j->state == JOB_RUNNING && counter++ == print_nr)
209 break;
210
e970a72e
MS
211 /* m->n_running_jobs must be consistent with the contents of m->jobs,
212 * so the above loop must have succeeded in finding j. */
213 assert(counter == print_nr + 1);
51d122af 214 assert(j);
5a82a91a 215
03b717a3
MS
216 cylon_pos = m->jobs_in_progress_iteration % 14;
217 if (cylon_pos >= 8)
218 cylon_pos = 14 - cylon_pos;
219 draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
220
8bb310c3
ZJS
221 m->jobs_in_progress_iteration++;
222
d6483ba7
ZJS
223 if (m->n_running_jobs > 1) {
224 if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
225 job_of_n = NULL;
226 }
03b717a3 227
8bb310c3
ZJS
228 format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
229 if (job_get_timeout(j, &x) > 0)
230 format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
231
127d5fd1 232 manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
8bb310c3
ZJS
233 "%sA %s job is running for %s (%s / %s)",
234 strempty(job_of_n),
235 job_type_to_string(j->type),
236 unit_description(j->unit),
237 time, limit);
03b717a3
MS
238}
239
e46b13c8
ZJS
240static int have_ask_password(void) {
241 _cleanup_closedir_ DIR *dir;
8fb3f009 242 struct dirent *de;
e46b13c8
ZJS
243
244 dir = opendir("/run/systemd/ask-password");
245 if (!dir) {
246 if (errno == ENOENT)
247 return false;
248 else
249 return -errno;
250 }
251
8fb3f009 252 FOREACH_DIRENT_ALL(de, dir, return -errno) {
e46b13c8
ZJS
253 if (startswith(de->d_name, "ask."))
254 return true;
255 }
8fb3f009 256 return false;
e46b13c8
ZJS
257}
258
259static int manager_dispatch_ask_password_fd(sd_event_source *source,
260 int fd, uint32_t revents, void *userdata) {
261 Manager *m = userdata;
262
263 assert(m);
264
265 flush_fd(fd);
266
267 m->have_ask_password = have_ask_password();
268 if (m->have_ask_password < 0)
269 /* Log error but continue. Negative have_ask_password
270 * is treated as unknown status. */
c33b3297 271 log_error_errno(m->have_ask_password, "Failed to list /run/systemd/ask-password: %m");
e46b13c8
ZJS
272
273 return 0;
274}
275
276static void manager_close_ask_password(Manager *m) {
277 assert(m);
278
e46b13c8 279 m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
90990e28 280 m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
e46b13c8
ZJS
281 m->have_ask_password = -EINVAL;
282}
283
284static int manager_check_ask_password(Manager *m) {
285 int r;
286
287 assert(m);
288
289 if (!m->ask_password_event_source) {
290 assert(m->ask_password_inotify_fd < 0);
291
292 mkdir_p_label("/run/systemd/ask-password", 0755);
293
294 m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
4a62c710
MS
295 if (m->ask_password_inotify_fd < 0)
296 return log_error_errno(errno, "inotify_init1() failed: %m");
e46b13c8
ZJS
297
298 if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
56f64d95 299 log_error_errno(errno, "Failed to add watch on /run/systemd/ask-password: %m");
e46b13c8
ZJS
300 manager_close_ask_password(m);
301 return -errno;
302 }
303
304 r = sd_event_add_io(m->event, &m->ask_password_event_source,
305 m->ask_password_inotify_fd, EPOLLIN,
306 manager_dispatch_ask_password_fd, m);
307 if (r < 0) {
56f64d95 308 log_error_errno(errno, "Failed to add event source for /run/systemd/ask-password: %m");
e46b13c8
ZJS
309 manager_close_ask_password(m);
310 return -errno;
311 }
312
7dfbe2e3
TG
313 (void) sd_event_source_set_description(m->ask_password_event_source, "manager-ask-password");
314
e46b13c8
ZJS
315 /* Queries might have been added meanwhile... */
316 manager_dispatch_ask_password_fd(m->ask_password_event_source,
317 m->ask_password_inotify_fd, EPOLLIN, m);
318 }
319
320 return m->have_ask_password;
321}
322
31a7eb86 323static int manager_watch_idle_pipe(Manager *m) {
31a7eb86
ZJS
324 int r;
325
718db961
LP
326 assert(m);
327
328 if (m->idle_pipe_event_source)
31a7eb86
ZJS
329 return 0;
330
331 if (m->idle_pipe[2] < 0)
332 return 0;
333
151b9b96 334 r = sd_event_add_io(m->event, &m->idle_pipe_event_source, m->idle_pipe[2], EPOLLIN, manager_dispatch_idle_pipe_fd, m);
23bbb0de
MS
335 if (r < 0)
336 return log_error_errno(r, "Failed to watch idle pipe: %m");
31a7eb86 337
7dfbe2e3
TG
338 (void) sd_event_source_set_description(m->idle_pipe_event_source, "manager-idle-pipe");
339
31a7eb86 340 return 0;
31a7eb86
ZJS
341}
342
718db961
LP
343static void manager_close_idle_pipe(Manager *m) {
344 assert(m);
31a7eb86 345
cd72bd8a
LP
346 m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
347
3d94f76c
LP
348 safe_close_pair(m->idle_pipe);
349 safe_close_pair(m->idle_pipe + 2);
31a7eb86
ZJS
350}
351
8742514c 352static int manager_setup_time_change(Manager *m) {
718db961 353 int r;
b92bea5d
ZJS
354
355 /* We only care for the cancellation event, hence we set the
356 * timeout to the latest possible value. */
357 struct itimerspec its = {
358 .it_value.tv_sec = TIME_T_MAX,
359 };
8742514c 360
718db961
LP
361 assert(m);
362 assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
8742514c 363
e0a3da1f 364 if (m->test_run_flags)
0d8c31ff
ZJS
365 return 0;
366
8742514c
LP
367 /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
368 * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
369
718db961 370 m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
4a62c710
MS
371 if (m->time_change_fd < 0)
372 return log_error_errno(errno, "Failed to create timerfd: %m");
8742514c 373
718db961 374 if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
56f64d95 375 log_debug_errno(errno, "Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
03e334a1 376 m->time_change_fd = safe_close(m->time_change_fd);
8742514c
LP
377 return 0;
378 }
379
151b9b96 380 r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
23bbb0de
MS
381 if (r < 0)
382 return log_error_errno(r, "Failed to create time change event source: %m");
8742514c 383
7dfbe2e3
TG
384 (void) sd_event_source_set_description(m->time_change_event_source, "manager-time-change");
385
8742514c
LP
386 log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
387
388 return 0;
389}
390
80876c20 391static int enable_special_signals(Manager *m) {
718db961 392 _cleanup_close_ int fd = -1;
80876c20
LP
393
394 assert(m);
395
e0a3da1f 396 if (m->test_run_flags)
37453b3a
EV
397 return 0;
398
a41b539e 399 /* Enable that we get SIGINT on control-alt-del. In containers
c9999773
LP
400 * this will fail with EPERM (older) or EINVAL (newer), so
401 * ignore that. */
4c701096 402 if (reboot(RB_DISABLE_CAD) < 0 && !IN_SET(errno, EPERM, EINVAL))
56f64d95 403 log_warning_errno(errno, "Failed to enable ctrl-alt-del handling: %m");
80876c20 404
a41b539e
LP
405 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
406 if (fd < 0) {
407 /* Support systems without virtual console */
408 if (fd != -ENOENT)
56f64d95 409 log_warning_errno(errno, "Failed to open /dev/tty0: %m");
a41b539e 410 } else {
80876c20
LP
411 /* Enable that we get SIGWINCH on kbrequest */
412 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
56f64d95 413 log_warning_errno(errno, "Failed to enable kbrequest handling: %m");
80876c20
LP
414 }
415
416 return 0;
417}
418
ce578209 419static int manager_setup_signals(Manager *m) {
b92bea5d
ZJS
420 struct sigaction sa = {
421 .sa_handler = SIG_DFL,
422 .sa_flags = SA_NOCLDSTOP|SA_RESTART,
423 };
718db961
LP
424 sigset_t mask;
425 int r;
60918275 426
ce578209
LP
427 assert(m);
428
57c0c30e
LP
429 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
430
4dffec14
LP
431 /* We make liberal use of realtime signals here. On
432 * Linux/glibc we have 30 of them (with the exception of Linux
433 * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
434 * (aka SIGRTMAX). */
7d793605 435
4dffec14 436 assert_se(sigemptyset(&mask) == 0);
7d793605
LP
437 sigset_add_many(&mask,
438 SIGCHLD, /* Child died */
439 SIGTERM, /* Reexecute daemon */
440 SIGHUP, /* Reload configuration */
441 SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
442 SIGUSR2, /* systemd: dump status */
443 SIGINT, /* Kernel sends us this on control-alt-del */
444 SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
445 SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
4dffec14 446
7d793605 447 SIGRTMIN+0, /* systemd: start default.target */
0003d1ab 448 SIGRTMIN+1, /* systemd: isolate rescue.target */
7d793605
LP
449 SIGRTMIN+2, /* systemd: isolate emergency.target */
450 SIGRTMIN+3, /* systemd: start halt.target */
451 SIGRTMIN+4, /* systemd: start poweroff.target */
452 SIGRTMIN+5, /* systemd: start reboot.target */
0003d1ab 453 SIGRTMIN+6, /* systemd: start kexec.target */
4dffec14
LP
454
455 /* ... space for more special targets ... */
456
0003d1ab
LP
457 SIGRTMIN+13, /* systemd: Immediate halt */
458 SIGRTMIN+14, /* systemd: Immediate poweroff */
459 SIGRTMIN+15, /* systemd: Immediate reboot */
460 SIGRTMIN+16, /* systemd: Immediate kexec */
4dffec14
LP
461
462 /* ... space for more immediate system state changes ... */
463
0658666b
LP
464 SIGRTMIN+20, /* systemd: enable status messages */
465 SIGRTMIN+21, /* systemd: disable status messages */
253ee27a
LP
466 SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
467 SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
600b704e 468 SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
4dffec14
LP
469
470 /* .. one free signal here ... */
471
472#if !defined(__hppa64__) && !defined(__hppa__)
473 /* Apparently Linux on hppa has fewer RT
474 * signals (SIGRTMAX is SIGRTMIN+25 there),
475 * hence let's not try to make use of them
476 * here. Since these commands are accessible
477 * by different means and only really a safety
478 * net, the missing functionality on hppa
479 * shouldn't matter. */
480
4cfa2c99 481 SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
253ee27a
LP
482 SIGRTMIN+27, /* systemd: set log target to console */
483 SIGRTMIN+28, /* systemd: set log target to kmsg */
ee33e53a 484 SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete) */
4dffec14
LP
485
486 /* ... one free signal here SIGRTMIN+30 ... */
487#endif
7d793605 488 -1);
ce578209
LP
489 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
490
718db961
LP
491 m->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
492 if (m->signal_fd < 0)
ce578209
LP
493 return -errno;
494
151b9b96 495 r = sd_event_add_io(m->event, &m->signal_event_source, m->signal_fd, EPOLLIN, manager_dispatch_signal_fd, m);
718db961
LP
496 if (r < 0)
497 return r;
ce578209 498
7dfbe2e3
TG
499 (void) sd_event_source_set_description(m->signal_event_source, "manager-signal");
500
d8fdc620
LP
501 /* Process signals a bit earlier than the rest of things, but later than notify_fd processing, so that the
502 * notify processing can still figure out to which process/service a message belongs, before we reap the
503 * process. Also, process this before handling cgroup notifications, so that we always collect child exit
504 * status information before detecting that there's no process in a cgroup. */
505 r = sd_event_source_set_priority(m->signal_event_source, SD_EVENT_PRIORITY_NORMAL-6);
29083707
LP
506 if (r < 0)
507 return r;
508
463d0d15 509 if (MANAGER_IS_SYSTEM(m))
80876c20 510 return enable_special_signals(m);
e1414003 511
ce578209
LP
512 return 0;
513}
514
f069efb4
LP
515static void manager_clean_environment(Manager *m) {
516 assert(m);
517
518 /* Let's remove some environment variables that we
519 * need ourselves to communicate with our clients */
520 strv_env_unset_many(
521 m->environment,
522 "NOTIFY_SOCKET",
523 "MAINPID",
524 "MANAGERPID",
525 "LISTEN_PID",
526 "LISTEN_FDS",
8dd4c05b 527 "LISTEN_FDNAMES",
f069efb4
LP
528 "WATCHDOG_PID",
529 "WATCHDOG_USEC",
4b58153d 530 "INVOCATION_ID",
f069efb4
LP
531 NULL);
532}
533
e21fea24 534static int manager_default_environment(Manager *m) {
71ecc858
LP
535 assert(m);
536
463d0d15 537 if (MANAGER_IS_SYSTEM(m)) {
e21fea24
KS
538 /* The system manager always starts with a clean
539 * environment for its children. It does not import
71cb7d30 540 * the kernel's or the parents' exported variables.
e21fea24 541 *
71cb7d30 542 * The initial passed environment is untouched to keep
e21fea24
KS
543 * /proc/self/environ valid; it is used for tagging
544 * the init process inside containers. */
43638332
ZJS
545 m->environment = strv_new("PATH=" DEFAULT_PATH,
546 NULL);
e21fea24
KS
547
548 /* Import locale variables LC_*= from configuration */
549 locale_setup(&m->environment);
71cb7d30 550 } else
e21fea24
KS
551 /* The user manager passes its own environment
552 * along to its children. */
553 m->environment = strv_copy(environ);
43d03a83 554
e21fea24
KS
555 if (!m->environment)
556 return -ENOMEM;
8b55b8c4 557
f069efb4 558 manager_clean_environment(m);
9d5a3757
LP
559 strv_sort(m->environment);
560
e21fea24 561 return 0;
71ecc858
LP
562}
563
3536f49e
YW
564static int manager_setup_prefix(Manager *m) {
565 struct table_entry {
566 uint64_t type;
567 const char *suffix;
568 };
569
72fd1768 570 static const struct table_entry paths_system[_EXEC_DIRECTORY_TYPE_MAX] = {
3536f49e
YW
571 [EXEC_DIRECTORY_RUNTIME] = { SD_PATH_SYSTEM_RUNTIME, NULL },
572 [EXEC_DIRECTORY_STATE] = { SD_PATH_SYSTEM_STATE_PRIVATE, NULL },
573 [EXEC_DIRECTORY_CACHE] = { SD_PATH_SYSTEM_STATE_CACHE, NULL },
574 [EXEC_DIRECTORY_LOGS] = { SD_PATH_SYSTEM_STATE_LOGS, NULL },
575 [EXEC_DIRECTORY_CONFIGURATION] = { SD_PATH_SYSTEM_CONFIGURATION, NULL },
576 };
577
72fd1768 578 static const struct table_entry paths_user[_EXEC_DIRECTORY_TYPE_MAX] = {
3536f49e
YW
579 [EXEC_DIRECTORY_RUNTIME] = { SD_PATH_USER_RUNTIME, NULL },
580 [EXEC_DIRECTORY_STATE] = { SD_PATH_USER_CONFIGURATION, NULL },
c6218495
LP
581 [EXEC_DIRECTORY_CACHE] = { SD_PATH_USER_STATE_CACHE, NULL },
582 [EXEC_DIRECTORY_LOGS] = { SD_PATH_USER_CONFIGURATION, "log" },
583 [EXEC_DIRECTORY_CONFIGURATION] = { SD_PATH_USER_CONFIGURATION, NULL },
3536f49e
YW
584 };
585
586 const struct table_entry *p;
587 ExecDirectoryType i;
588 int r;
589
590 assert(m);
591
592 if (MANAGER_IS_SYSTEM(m))
593 p = paths_system;
594 else
595 p = paths_user;
596
72fd1768 597 for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++) {
3536f49e
YW
598 r = sd_path_home(p[i].type, p[i].suffix, &m->prefix[i]);
599 if (r < 0)
600 return r;
601 }
602
603 return 0;
604}
605
e0a3da1f 606int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) {
ce578209 607 Manager *m;
e3dd987c 608 int r;
8e274523
LP
609
610 assert(_m);
463d0d15 611 assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER));
ce578209 612
915b3753
LP
613 m = new0(Manager, 1);
614 if (!m)
8e274523 615 return -ENOMEM;
60918275 616
463d0d15 617 m->unit_file_scope = scope;
a16e1123 618 m->exit_code = _MANAGER_EXIT_CODE_INVALID;
bd8f585b 619 m->default_timer_accuracy_usec = USEC_PER_MINUTE;
9ded9cd1 620 m->default_tasks_accounting = true;
79baeeb9 621 m->default_tasks_max = UINT64_MAX;
bd389aa7
LP
622 m->default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
623 m->default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
624 m->default_restart_usec = DEFAULT_RESTART_USEC;
80876c20 625
349cc4a5 626#if ENABLE_EFI
463d0d15 627 if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
9f9f0342
LP
628 boot_timestamps(m->timestamps + MANAGER_TIMESTAMP_USERSPACE,
629 m->timestamps + MANAGER_TIMESTAMP_FIRMWARE,
630 m->timestamps + MANAGER_TIMESTAMP_LOADER);
463d0d15
LP
631#endif
632
f2341e0a 633 /* Prepare log fields we can use for structured logging */
463d0d15
LP
634 if (MANAGER_IS_SYSTEM(m)) {
635 m->unit_log_field = "UNIT=";
636 m->unit_log_format_string = "UNIT=%s";
4b58153d
LP
637
638 m->invocation_log_field = "INVOCATION_ID=";
f1c50bec 639 m->invocation_log_format_string = "INVOCATION_ID=%s";
463d0d15
LP
640 } else {
641 m->unit_log_field = "USER_UNIT=";
642 m->unit_log_format_string = "USER_UNIT=%s";
4b58153d
LP
643
644 m->invocation_log_field = "USER_INVOCATION_ID=";
f1c50bec 645 m->invocation_log_format_string = "USER_INVOCATION_ID=%s";
463d0d15 646 }
f2341e0a 647
718db961 648 m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
8742514c 649
d8fdc620 650 m->pin_cgroupfs_fd = m->notify_fd = m->cgroups_agent_fd = m->signal_fd = m->time_change_fd =
232f6754 651 m->dev_autofs_fd = m->private_listen_fd = m->cgroup_inotify_fd =
d8fdc620 652 m->ask_password_inotify_fd = -1;
d379d442 653
00d9ef85
LP
654 m->user_lookup_fds[0] = m->user_lookup_fds[1] = -1;
655
ea430986 656 m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
9152c765 657
e46b13c8 658 m->have_ask_password = -EINVAL; /* we don't know */
ae2a2c53 659 m->first_boot = -1;
e46b13c8 660
e0a3da1f 661 m->test_run_flags = test_run_flags;
0d8c31ff 662
2e5c94b9
LP
663 /* Reboot immediately if the user hits C-A-D more often than 7x per 2s */
664 RATELIMIT_INIT(m->ctrl_alt_del_ratelimit, 2 * USEC_PER_SEC, 7);
665
e21fea24
KS
666 r = manager_default_environment(m);
667 if (r < 0)
1137a57c
LP
668 goto fail;
669
d5099efc 670 r = hashmap_ensure_allocated(&m->units, &string_hash_ops);
718db961 671 if (r < 0)
60918275
LP
672 goto fail;
673
d5099efc 674 r = hashmap_ensure_allocated(&m->jobs, NULL);
718db961 675 if (r < 0)
60918275
LP
676 goto fail;
677
d5099efc 678 r = hashmap_ensure_allocated(&m->cgroup_unit, &string_hash_ops);
718db961 679 if (r < 0)
9152c765
LP
680 goto fail;
681
d5099efc 682 r = hashmap_ensure_allocated(&m->watch_bus, &string_hash_ops);
718db961 683 if (r < 0)
05e343b7
LP
684 goto fail;
685
718db961
LP
686 r = sd_event_default(&m->event);
687 if (r < 0)
8742514c
LP
688 goto fail;
689
151b9b96 690 r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
752b5905
LP
691 if (r < 0)
692 goto fail;
693
694 r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
695 if (r < 0)
696 goto fail;
697
698 r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
699 if (r < 0)
700 goto fail;
701
7dfbe2e3
TG
702 (void) sd_event_source_set_description(m->run_queue_event_source, "manager-run-queue");
703
8742514c
LP
704 r = manager_setup_signals(m);
705 if (r < 0)
9152c765
LP
706 goto fail;
707
8742514c
LP
708 r = manager_setup_cgroup(m);
709 if (r < 0)
8e274523
LP
710 goto fail;
711
8742514c
LP
712 r = manager_setup_time_change(m);
713 if (r < 0)
8c47c732
LP
714 goto fail;
715
9670d583
LP
716 m->udev = udev_new();
717 if (!m->udev) {
718 r = -ENOMEM;
719 goto fail;
720 }
721
d3070fbd
LP
722 if (MANAGER_IS_SYSTEM(m)) {
723 r = mkdir_label("/run/systemd/units", 0755);
724 if (r < 0 && r != -EEXIST)
725 goto fail;
726 }
727
232f6754
ZJS
728 /* Note that we do not set up the notify fd here. We do that after deserialization,
729 * since they might have gotten serialized across the reexec. */
d86f9d52 730
72bc8d00
LP
731 m->taint_usr = dir_is_empty("/usr") > 0;
732
3536f49e
YW
733 r = manager_setup_prefix(m);
734 if (r < 0)
735 goto fail;
736
8e274523
LP
737 *_m = m;
738 return 0;
60918275
LP
739
740fail:
741 manager_free(m);
8e274523 742 return r;
60918275
LP
743}
744
d86f9d52 745static int manager_setup_notify(Manager *m) {
7181dbdb 746 int r;
d86f9d52 747
e0a3da1f 748 if (m->test_run_flags)
0d8c31ff
ZJS
749 return 0;
750
d86f9d52
LP
751 if (m->notify_fd < 0) {
752 _cleanup_close_ int fd = -1;
920b52e4 753 union sockaddr_union sa = {
7181dbdb
LP
754 .sa.sa_family = AF_UNIX,
755 };
55836941 756 static const int one = 1;
d86f9d52
LP
757
758 /* First free all secondary fields */
a1e58e8e 759 m->notify_socket = mfree(m->notify_socket);
d86f9d52
LP
760 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
761
762 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
4a62c710
MS
763 if (fd < 0)
764 return log_error_errno(errno, "Failed to allocate notification socket: %m");
d86f9d52 765
a47806fa
LP
766 fd_inc_rcvbuf(fd, NOTIFY_RCVBUF_SIZE);
767
3536f49e 768 m->notify_socket = strappend(m->prefix[EXEC_DIRECTORY_RUNTIME], "/systemd/notify");
498e87d6
LP
769 if (!m->notify_socket)
770 return log_oom();
771
772 (void) mkdir_parents_label(m->notify_socket, 0755);
f0e62e89 773 (void) unlink(m->notify_socket);
7181dbdb
LP
774
775 strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
fc2fffe7 776 r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
4a62c710
MS
777 if (r < 0)
778 return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
d86f9d52
LP
779
780 r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
4a62c710
MS
781 if (r < 0)
782 return log_error_errno(errno, "SO_PASSCRED failed: %m");
d86f9d52 783
d86f9d52
LP
784 m->notify_fd = fd;
785 fd = -1;
786
787 log_debug("Using notification socket %s", m->notify_socket);
788 }
789
790 if (!m->notify_event_source) {
151b9b96 791 r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_dispatch_notify_fd, m);
895b3a7b
MS
792 if (r < 0)
793 return log_error_errno(r, "Failed to allocate notify event source: %m");
d86f9d52 794
d8fdc620
LP
795 /* Process notification messages a bit earlier than SIGCHLD, so that we can still identify to which
796 * service an exit message belongs. */
df006034 797 r = sd_event_source_set_priority(m->notify_event_source, SD_EVENT_PRIORITY_NORMAL-7);
23bbb0de
MS
798 if (r < 0)
799 return log_error_errno(r, "Failed to set priority of notify event source: %m");
7dfbe2e3
TG
800
801 (void) sd_event_source_set_description(m->notify_event_source, "manager-notify");
d86f9d52
LP
802 }
803
804 return 0;
805}
806
d8fdc620
LP
807static int manager_setup_cgroups_agent(Manager *m) {
808
809 static const union sockaddr_union sa = {
810 .un.sun_family = AF_UNIX,
811 .un.sun_path = "/run/systemd/cgroups-agent",
812 };
813 int r;
814
815 /* This creates a listening socket we receive cgroups agent messages on. We do not use D-Bus for delivering
816 * these messages from the cgroups agent binary to PID 1, as the cgroups agent binary is very short-living, and
817 * each instance of it needs a new D-Bus connection. Since D-Bus connections are SOCK_STREAM/AF_UNIX, on
818 * overloaded systems the backlog of the D-Bus socket becomes relevant, as not more than the configured number
819 * of D-Bus connections may be queued until the kernel will start dropping further incoming connections,
820 * possibly resulting in lost cgroups agent messages. To avoid this, we'll use a private SOCK_DGRAM/AF_UNIX
821 * socket, where no backlog is relevant as communication may take place without an actual connect() cycle, and
822 * we thus won't lose messages.
823 *
824 * Note that PID 1 will forward the agent message to system bus, so that the user systemd instance may listen
825 * to it. The system instance hence listens on this special socket, but the user instances listen on the system
826 * bus for these messages. */
827
e0a3da1f 828 if (m->test_run_flags)
d8fdc620
LP
829 return 0;
830
831 if (!MANAGER_IS_SYSTEM(m))
832 return 0;
833
c22800e4 834 r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
b4cccbc1
LP
835 if (r < 0)
836 return log_error_errno(r, "Failed to determine whether unified cgroups hierarchy is used: %m");
837 if (r > 0) /* We don't need this anymore on the unified hierarchy */
d8fdc620
LP
838 return 0;
839
840 if (m->cgroups_agent_fd < 0) {
841 _cleanup_close_ int fd = -1;
842
843 /* First free all secondary fields */
844 m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
845
846 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
847 if (fd < 0)
848 return log_error_errno(errno, "Failed to allocate cgroups agent socket: %m");
849
850 fd_inc_rcvbuf(fd, CGROUPS_AGENT_RCVBUF_SIZE);
851
852 (void) unlink(sa.un.sun_path);
853
854 /* Only allow root to connect to this socket */
855 RUN_WITH_UMASK(0077)
fc2fffe7 856 r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
d8fdc620
LP
857 if (r < 0)
858 return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
859
860 m->cgroups_agent_fd = fd;
861 fd = -1;
862 }
863
864 if (!m->cgroups_agent_event_source) {
865 r = sd_event_add_io(m->event, &m->cgroups_agent_event_source, m->cgroups_agent_fd, EPOLLIN, manager_dispatch_cgroups_agent_fd, m);
866 if (r < 0)
867 return log_error_errno(r, "Failed to allocate cgroups agent event source: %m");
868
869 /* Process cgroups notifications early, but after having processed service notification messages or
870 * SIGCHLD signals, so that a cgroup running empty is always just the last safety net of notification,
871 * and we collected the metadata the notification and SIGCHLD stuff offers first. Also see handling of
872 * cgroup inotify for the unified cgroup stuff. */
09e24654 873 r = sd_event_source_set_priority(m->cgroups_agent_event_source, SD_EVENT_PRIORITY_NORMAL-4);
d8fdc620
LP
874 if (r < 0)
875 return log_error_errno(r, "Failed to set priority of cgroups agent event source: %m");
876
877 (void) sd_event_source_set_description(m->cgroups_agent_event_source, "manager-cgroups-agent");
878 }
879
880 return 0;
881}
882
00d9ef85
LP
883static int manager_setup_user_lookup_fd(Manager *m) {
884 int r;
885
886 assert(m);
887
888 /* Set up the socket pair used for passing UID/GID resolution results from forked off processes to PID
889 * 1. Background: we can't do name lookups (NSS) from PID 1, since it might involve IPC and thus activation,
890 * and we might hence deadlock on ourselves. Hence we do all user/group lookups asynchronously from the forked
891 * off processes right before executing the binaries to start. In order to be able to clean up any IPC objects
892 * created by a unit (see RemoveIPC=) we need to know in PID 1 the used UID/GID of the executed processes,
893 * hence we establish this communication channel so that forked off processes can pass their UID/GID
894 * information back to PID 1. The forked off processes send their resolved UID/GID to PID 1 in a simple
895 * datagram, along with their unit name, so that we can share one communication socket pair among all units for
896 * this purpose.
897 *
898 * You might wonder why we need a communication channel for this that is independent of the usual notification
899 * socket scheme (i.e. $NOTIFY_SOCKET). The primary difference is about trust: data sent via the $NOTIFY_SOCKET
900 * channel is only accepted if it originates from the right unit and if reception was enabled for it. The user
901 * lookup socket OTOH is only accessible by PID 1 and its children until they exec(), and always available.
902 *
903 * Note that this function is called under two circumstances: when we first initialize (in which case we
904 * allocate both the socket pair and the event source to listen on it), and when we deserialize after a reload
905 * (in which case the socket pair already exists but we still need to allocate the event source for it). */
906
907 if (m->user_lookup_fds[0] < 0) {
908
909 /* Free all secondary fields */
910 safe_close_pair(m->user_lookup_fds);
911 m->user_lookup_event_source = sd_event_source_unref(m->user_lookup_event_source);
912
913 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, m->user_lookup_fds) < 0)
914 return log_error_errno(errno, "Failed to allocate user lookup socket: %m");
915
916 (void) fd_inc_rcvbuf(m->user_lookup_fds[0], NOTIFY_RCVBUF_SIZE);
917 }
918
919 if (!m->user_lookup_event_source) {
920 r = sd_event_add_io(m->event, &m->user_lookup_event_source, m->user_lookup_fds[0], EPOLLIN, manager_dispatch_user_lookup_fd, m);
921 if (r < 0)
922 return log_error_errno(errno, "Failed to allocate user lookup event source: %m");
923
924 /* Process even earlier than the notify event source, so that we always know first about valid UID/GID
925 * resolutions */
926 r = sd_event_source_set_priority(m->user_lookup_event_source, SD_EVENT_PRIORITY_NORMAL-8);
927 if (r < 0)
928 return log_error_errno(errno, "Failed to set priority ot user lookup event source: %m");
929
930 (void) sd_event_source_set_description(m->user_lookup_event_source, "user-lookup");
931 }
932
933 return 0;
934}
935
d86f9d52
LP
936static int manager_connect_bus(Manager *m, bool reexecuting) {
937 bool try_bus_connect;
5463fa0a 938 Unit *u = NULL;
d86f9d52
LP
939
940 assert(m);
941
e0a3da1f 942 if (m->test_run_flags)
0d8c31ff
ZJS
943 return 0;
944
5463fa0a
MS
945 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
946
d86f9d52 947 try_bus_connect =
41dfa61d 948 (u && SERVICE(u)->deserialized_state == SERVICE_RUNNING) &&
5463fa0a
MS
949 (reexecuting ||
950 (MANAGER_IS_USER(m) && getenv("DBUS_SESSION_BUS_ADDRESS")));
d86f9d52 951
ff9b60f3 952 /* Try to connect to the buses, if possible. */
d86f9d52
LP
953 return bus_init(m, try_bus_connect);
954}
955
23a177ef 956static unsigned manager_dispatch_cleanup_queue(Manager *m) {
595ed347 957 Unit *u;
23a177ef
LP
958 unsigned n = 0;
959
960 assert(m);
961
595ed347
MS
962 while ((u = m->cleanup_queue)) {
963 assert(u->in_cleanup_queue);
23a177ef 964
595ed347 965 unit_free(u);
23a177ef
LP
966 n++;
967 }
968
969 return n;
970}
971
eced69b3 972enum {
35b8ca3a 973 GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
eced69b3
LP
974 GC_OFFSET_UNSURE, /* No clue */
975 GC_OFFSET_GOOD, /* We still need this unit */
976 GC_OFFSET_BAD, /* We don't need this unit anymore */
977 _GC_OFFSET_MAX
978};
979
00d9ef85 980static void unit_gc_mark_good(Unit *u, unsigned gc_marker) {
4892084f 981 Unit *other;
eef85c4a
LP
982 Iterator i;
983 void *v;
4892084f
LN
984
985 u->gc_marker = gc_marker + GC_OFFSET_GOOD;
986
987 /* Recursively mark referenced units as GOOD as well */
eef85c4a 988 HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REFERENCES], i)
4892084f
LN
989 if (other->gc_marker == gc_marker + GC_OFFSET_UNSURE)
990 unit_gc_mark_good(other, gc_marker);
991}
992
eced69b3 993static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
701cc384 994 Unit *other;
eced69b3 995 bool is_bad;
eef85c4a
LP
996 Iterator i;
997 void *v;
701cc384
LP
998
999 assert(u);
1000
4c701096
YW
1001 if (IN_SET(u->gc_marker - gc_marker,
1002 GC_OFFSET_GOOD, GC_OFFSET_BAD, GC_OFFSET_UNSURE, GC_OFFSET_IN_PATH))
701cc384
LP
1003 return;
1004
ac155bb8 1005 if (u->in_cleanup_queue)
701cc384
LP
1006 goto bad;
1007
1008 if (unit_check_gc(u))
1009 goto good;
1010
ac155bb8 1011 u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
eced69b3
LP
1012
1013 is_bad = true;
1014
eef85c4a 1015 HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REFERENCED_BY], i) {
701cc384
LP
1016 unit_gc_sweep(other, gc_marker);
1017
ac155bb8 1018 if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
701cc384 1019 goto good;
eced69b3 1020
ac155bb8 1021 if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
eced69b3 1022 is_bad = false;
701cc384
LP
1023 }
1024
eced69b3
LP
1025 if (is_bad)
1026 goto bad;
1027
1028 /* We were unable to find anything out about this entry, so
1029 * let's investigate it later */
ac155bb8 1030 u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
eced69b3
LP
1031 unit_add_to_gc_queue(u);
1032 return;
1033
701cc384 1034bad:
eced69b3
LP
1035 /* We definitely know that this one is not useful anymore, so
1036 * let's mark it for deletion */
ac155bb8 1037 u->gc_marker = gc_marker + GC_OFFSET_BAD;
eced69b3 1038 unit_add_to_cleanup_queue(u);
701cc384
LP
1039 return;
1040
1041good:
4892084f 1042 unit_gc_mark_good(u, gc_marker);
701cc384
LP
1043}
1044
c5a97ed1
LP
1045static unsigned manager_dispatch_gc_unit_queue(Manager *m) {
1046 unsigned n = 0, gc_marker;
595ed347 1047 Unit *u;
701cc384
LP
1048
1049 assert(m);
1050
cf1265e1 1051 /* log_debug("Running GC..."); */
701cc384 1052
eced69b3
LP
1053 m->gc_marker += _GC_OFFSET_MAX;
1054 if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
c9c0cadb 1055 m->gc_marker = 1;
701cc384 1056
eced69b3
LP
1057 gc_marker = m->gc_marker;
1058
c5a97ed1 1059 while ((u = m->gc_unit_queue)) {
595ed347 1060 assert(u->in_gc_queue);
701cc384 1061
595ed347 1062 unit_gc_sweep(u, gc_marker);
eced69b3 1063
c5a97ed1 1064 LIST_REMOVE(gc_queue, m->gc_unit_queue, u);
595ed347 1065 u->in_gc_queue = false;
701cc384
LP
1066
1067 n++;
1068
4c701096
YW
1069 if (IN_SET(u->gc_marker - gc_marker,
1070 GC_OFFSET_BAD, GC_OFFSET_UNSURE)) {
cc3bc3e6 1071 if (u->id)
f2341e0a 1072 log_unit_debug(u, "Collecting.");
595ed347
MS
1073 u->gc_marker = gc_marker + GC_OFFSET_BAD;
1074 unit_add_to_cleanup_queue(u);
701cc384
LP
1075 }
1076 }
1077
701cc384
LP
1078 return n;
1079}
1080
c5a97ed1
LP
1081static unsigned manager_dispatch_gc_job_queue(Manager *m) {
1082 unsigned n = 0;
1083 Job *j;
1084
1085 assert(m);
1086
1087 while ((j = m->gc_job_queue)) {
1088 assert(j->in_gc_queue);
1089
1090 LIST_REMOVE(gc_queue, m->gc_job_queue, j);
1091 j->in_gc_queue = false;
1092
1093 n++;
1094
1095 if (job_check_gc(j))
1096 continue;
1097
1098 log_unit_debug(j->unit, "Collecting job.");
1099 (void) job_finish_and_invalidate(j, JOB_COLLECTED, false, false);
1100 }
1101
1102 return n;
1103}
1104
a16e1123 1105static void manager_clear_jobs_and_units(Manager *m) {
a16e1123 1106 Unit *u;
60918275
LP
1107
1108 assert(m);
1109
87f0e418
LP
1110 while ((u = hashmap_first(m->units)))
1111 unit_free(u);
964e0949
LP
1112
1113 manager_dispatch_cleanup_queue(m);
1114
1115 assert(!m->load_queue);
1116 assert(!m->run_queue);
1117 assert(!m->dbus_unit_queue);
1118 assert(!m->dbus_job_queue);
1119 assert(!m->cleanup_queue);
c5a97ed1
LP
1120 assert(!m->gc_unit_queue);
1121 assert(!m->gc_job_queue);
964e0949 1122
964e0949
LP
1123 assert(hashmap_isempty(m->jobs));
1124 assert(hashmap_isempty(m->units));
9e9e2b72
MS
1125
1126 m->n_on_console = 0;
1127 m->n_running_jobs = 0;
a16e1123
LP
1128}
1129
06d8d842 1130Manager* manager_free(Manager *m) {
a16e1123 1131 UnitType c;
c93ff2e9 1132 int i;
35aba85a 1133 ExecDirectoryType dt;
87f0e418 1134
06d8d842
ZJS
1135 if (!m)
1136 return NULL;
a16e1123
LP
1137
1138 manager_clear_jobs_and_units(m);
23a177ef 1139
7824bbeb
LP
1140 for (c = 0; c < _UNIT_TYPE_MAX; c++)
1141 if (unit_vtable[c]->shutdown)
1142 unit_vtable[c]->shutdown(m);
1143
a1f31f47 1144 /* If we reexecute ourselves, we keep the root cgroup around */
c6c18be3 1145 manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
8e274523 1146
07a78643 1147 lookup_paths_flush_generator(&m->lookup_paths);
5a1e9937 1148
5e8d1c9a 1149 bus_done(m);
ea430986 1150
29206d46
LP
1151 dynamic_user_vacuum(m, false);
1152 hashmap_free(m->dynamic_users);
1153
87f0e418 1154 hashmap_free(m->units);
4b58153d 1155 hashmap_free(m->units_by_invocation_id);
60918275 1156 hashmap_free(m->jobs);
5ba6985b
LP
1157 hashmap_free(m->watch_pids1);
1158 hashmap_free(m->watch_pids2);
05e343b7 1159 hashmap_free(m->watch_bus);
9152c765 1160
95ae05c0 1161 set_free(m->startup_units);
f755e3b7
LP
1162 set_free(m->failed_units);
1163
718db961
LP
1164 sd_event_source_unref(m->signal_event_source);
1165 sd_event_source_unref(m->notify_event_source);
d8fdc620 1166 sd_event_source_unref(m->cgroups_agent_event_source);
718db961
LP
1167 sd_event_source_unref(m->time_change_event_source);
1168 sd_event_source_unref(m->jobs_in_progress_event_source);
752b5905 1169 sd_event_source_unref(m->run_queue_event_source);
00d9ef85 1170 sd_event_source_unref(m->user_lookup_event_source);
718db961 1171
03e334a1
LP
1172 safe_close(m->signal_fd);
1173 safe_close(m->notify_fd);
d8fdc620 1174 safe_close(m->cgroups_agent_fd);
03e334a1 1175 safe_close(m->time_change_fd);
00d9ef85 1176 safe_close_pair(m->user_lookup_fds);
718db961 1177
e46b13c8
ZJS
1178 manager_close_ask_password(m);
1179
718db961
LP
1180 manager_close_idle_pipe(m);
1181
9670d583 1182 udev_unref(m->udev);
718db961 1183 sd_event_unref(m->event);
60918275 1184
c952c6ec
LP
1185 free(m->notify_socket);
1186
84e3543e 1187 lookup_paths_free(&m->lookup_paths);
1137a57c 1188 strv_free(m->environment);
036643a2 1189
4ad49000 1190 hashmap_free(m->cgroup_unit);
c6c18be3 1191 set_free_free(m->unit_path_cache);
33be102a 1192
664f88a7
LP
1193 free(m->switch_root);
1194 free(m->switch_root_init);
1195
517d56b1 1196 for (i = 0; i < _RLIMIT_MAX; i++)
d9814c76 1197 m->rlimit[i] = mfree(m->rlimit[i]);
c93ff2e9 1198
a57f7e2c
LP
1199 assert(hashmap_isempty(m->units_requiring_mounts_for));
1200 hashmap_free(m->units_requiring_mounts_for);
1201
00d9ef85
LP
1202 hashmap_free(m->uid_refs);
1203 hashmap_free(m->gid_refs);
1204
72fd1768 1205 for (dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++)
35aba85a
YW
1206 m->prefix[dt] = mfree(m->prefix[dt]);
1207
6b430fdb 1208 return mfree(m);
60918275
LP
1209}
1210
ba64af90 1211void manager_enumerate(Manager *m) {
f50e0a01 1212 UnitType c;
f50e0a01
LP
1213
1214 assert(m);
1215
a16e1123
LP
1216 /* Let's ask every type to load all units from disk/kernel
1217 * that it might know */
0faacd47 1218 for (c = 0; c < _UNIT_TYPE_MAX; c++) {
1c2e9646 1219 if (!unit_type_supported(c)) {
03afec3c 1220 log_debug("Unit type .%s is not supported on this system.", unit_type_to_string(c));
0faacd47 1221 continue;
a57f7e2c 1222 }
f50e0a01 1223
0faacd47
LP
1224 if (!unit_vtable[c]->enumerate)
1225 continue;
1226
ba64af90 1227 unit_vtable[c]->enumerate(m);
0faacd47
LP
1228 }
1229
f50e0a01 1230 manager_dispatch_load_queue(m);
a16e1123
LP
1231}
1232
007c6337 1233static void manager_coldplug(Manager *m) {
a16e1123
LP
1234 Iterator i;
1235 Unit *u;
1236 char *k;
007c6337 1237 int r;
a16e1123
LP
1238
1239 assert(m);
f50e0a01
LP
1240
1241 /* Then, let's set up their initial state. */
1242 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
1243
1244 /* ignore aliases */
ac155bb8 1245 if (u->id != k)
f50e0a01
LP
1246 continue;
1247
007c6337
LP
1248 r = unit_coldplug(u);
1249 if (r < 0)
1250 log_warning_errno(r, "We couldn't coldplug %s, proceeding anyway: %m", u->id);
f50e0a01 1251 }
a16e1123
LP
1252}
1253
fe51822e
LP
1254static void manager_build_unit_path_cache(Manager *m) {
1255 char **i;
fe51822e
LP
1256 int r;
1257
1258 assert(m);
1259
1260 set_free_free(m->unit_path_cache);
1261
d5099efc 1262 m->unit_path_cache = set_new(&string_hash_ops);
874310b7 1263 if (!m->unit_path_cache) {
d063a527
LP
1264 r = -ENOMEM;
1265 goto fail;
fe51822e
LP
1266 }
1267
1268 /* This simply builds a list of files we know exist, so that
1269 * we don't always have to go to disk */
1270
a3c4eb07 1271 STRV_FOREACH(i, m->lookup_paths.search_path) {
d063a527 1272 _cleanup_closedir_ DIR *d = NULL;
fe51822e
LP
1273 struct dirent *de;
1274
bd0af849
ZJS
1275 d = opendir(*i);
1276 if (!d) {
874310b7 1277 if (errno != ENOENT)
d063a527 1278 log_warning_errno(errno, "Failed to open directory %s, ignoring: %m", *i);
fe51822e
LP
1279 continue;
1280 }
1281
d063a527 1282 FOREACH_DIRENT(de, d, r = -errno; goto fail) {
fe51822e
LP
1283 char *p;
1284
605405c6 1285 p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name);
44d91056 1286 if (!p) {
fe51822e
LP
1287 r = -ENOMEM;
1288 goto fail;
1289 }
1290
ef42202a
ZJS
1291 r = set_consume(m->unit_path_cache, p);
1292 if (r < 0)
fe51822e 1293 goto fail;
fe51822e 1294 }
fe51822e
LP
1295 }
1296
1297 return;
1298
1299fail:
d063a527
LP
1300 log_warning_errno(r, "Failed to build unit path cache, proceeding without: %m");
1301 m->unit_path_cache = set_free_free(m->unit_path_cache);
fe51822e
LP
1302}
1303
9ff1a6f1 1304static void manager_distribute_fds(Manager *m, FDSet *fds) {
9588bc32 1305 Iterator i;
9ff1a6f1 1306 Unit *u;
9588bc32
LP
1307
1308 assert(m);
1309
1310 HASHMAP_FOREACH(u, m->units, i) {
1311
1312 if (fdset_size(fds) <= 0)
1313 break;
1314
9ff1a6f1
LP
1315 if (!UNIT_VTABLE(u)->distribute_fds)
1316 continue;
9588bc32 1317
9ff1a6f1
LP
1318 UNIT_VTABLE(u)->distribute_fds(u, fds);
1319 }
9588bc32
LP
1320}
1321
a16e1123 1322int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
17f01ace 1323 int r;
a16e1123
LP
1324
1325 assert(m);
1326
a1f31f47
ZJS
1327 /* If we are running in test mode, we still want to run the generators,
1328 * but we should not touch the real generator directories. */
1329 r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope,
e0a3da1f 1330 m->test_run_flags ? LOOKUP_PATHS_TEMPORARY_GENERATED : 0,
a1f31f47 1331 NULL);
e801700e
ZJS
1332 if (r < 0)
1333 return r;
5a1e9937 1334
64691d20
ZJS
1335 r = manager_run_environment_generators(m);
1336 if (r < 0)
1337 return r;
1338
a1f31f47
ZJS
1339 /* Make sure the transient directory always exists, so that it remains
1340 * in the search path */
1341 r = mkdir_p_label(m->lookup_paths.transient, 0755);
1342 if (r < 0)
17f01ace
ZJS
1343 return log_error_errno(r, "Failed to create transient generator directory \"%s\": %m",
1344 m->lookup_paths.transient);
39591351 1345
9f9f0342 1346 dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_GENERATORS_START);
a3c4eb07 1347 r = manager_run_generators(m);
9f9f0342 1348 dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_GENERATORS_FINISH);
07719a21
LP
1349 if (r < 0)
1350 return r;
1351
fd130612 1352 /* If this is the first boot, and we are in the host system, then preset everything */
81fe6cde 1353 if (m->first_boot > 0 &&
fd130612 1354 MANAGER_IS_SYSTEM(m) &&
e0a3da1f 1355 !m->test_run_flags) {
81fe6cde 1356
17f01ace
ZJS
1357 r = unit_file_preset_all(UNIT_FILE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
1358 if (r < 0)
1359 log_full_errno(r == -EEXIST ? LOG_NOTICE : LOG_WARNING, r,
1360 "Failed to populate /etc with preset unit settings, ignoring: %m");
28dd66ec
LB
1361 else
1362 log_info("Populated /etc with preset unit settings.");
1363 }
1364
a1453343 1365 lookup_paths_reduce(&m->lookup_paths);
fe51822e
LP
1366 manager_build_unit_path_cache(m);
1367
9f611ad8
LP
1368 /* If we will deserialize make sure that during enumeration
1369 * this is already known, so we increase the counter here
1370 * already */
1371 if (serialization)
313cefa1 1372 m->n_reloading++;
9f611ad8 1373
a16e1123 1374 /* First, enumerate what we can from all config files */
9f9f0342 1375 dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_START);
ba64af90 1376 manager_enumerate(m);
9f9f0342 1377 dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
a16e1123
LP
1378
1379 /* Second, deserialize if there is something to deserialize */
07429866 1380 if (serialization) {
1cd974ed 1381 r = manager_deserialize(m, serialization, fds);
07429866 1382 if (r < 0)
17f01ace 1383 return log_error_errno(r, "Deserialization failed: %m");
07429866 1384 }
a16e1123 1385
01e10de3
LP
1386 /* Any fds left? Find some unit which wants them. This is
1387 * useful to allow container managers to pass some file
1388 * descriptors to us pre-initialized. This enables
1389 * socket-based activation of entire containers. */
9ff1a6f1 1390 manager_distribute_fds(m, fds);
01e10de3 1391
d86f9d52
LP
1392 /* We might have deserialized the notify fd, but if we didn't
1393 * then let's create the bus now */
17f01ace
ZJS
1394 r = manager_setup_notify(m);
1395 if (r < 0)
1396 /* No sense to continue without notifications, our children would fail anyway. */
1397 return r;
d86f9d52 1398
17f01ace
ZJS
1399 r = manager_setup_cgroups_agent(m);
1400 if (r < 0)
1401 /* Likewise, no sense to continue without empty cgroup notifications. */
1402 return r;
d8fdc620 1403
17f01ace
ZJS
1404 r = manager_setup_user_lookup_fd(m);
1405 if (r < 0)
1406 /* This shouldn't fail, except if things are really broken. */
1407 return r;
00d9ef85 1408
232f6754 1409 /* Let's connect to the bus now. */
05a98afd
LP
1410 (void) manager_connect_bus(m, !!serialization);
1411
1412 (void) bus_track_coldplug(m, &m->subscribed, false, m->deserialized_subscribed);
1413 m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
e3dd987c 1414
a16e1123 1415 /* Third, fire things up! */
007c6337 1416 manager_coldplug(m);
a16e1123 1417
29206d46
LP
1418 /* Release any dynamic users no longer referenced */
1419 dynamic_user_vacuum(m, true);
1420
00d9ef85
LP
1421 /* Release any references to UIDs/GIDs no longer referenced, and destroy any IPC owned by them */
1422 manager_vacuum_uid_refs(m);
1423 manager_vacuum_gid_refs(m);
1424
9f611ad8 1425 if (serialization) {
a7556052 1426 assert(m->n_reloading > 0);
313cefa1 1427 m->n_reloading--;
71445ae7
LP
1428
1429 /* Let's wait for the UnitNew/JobNew messages being
1430 * sent, before we notify that the reload is
1431 * finished */
1432 m->send_reloading_done = true;
9f611ad8
LP
1433 }
1434
17f01ace 1435 return 0;
f50e0a01
LP
1436}
1437
4bd29fe5 1438int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret) {
e5b5ae50 1439 int r;
7527cb52 1440 Transaction *tr;
e5b5ae50
LP
1441
1442 assert(m);
1443 assert(type < _JOB_TYPE_MAX);
87f0e418 1444 assert(unit);
e5b5ae50 1445 assert(mode < _JOB_MODE_MAX);
60918275 1446
7358dc02
ZJS
1447 if (mode == JOB_ISOLATE && type != JOB_START)
1448 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start.");
c497c7a9 1449
7358dc02
ZJS
1450 if (mode == JOB_ISOLATE && !unit->allow_isolate)
1451 return sd_bus_error_setf(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
2528a7a6 1452
f2341e0a 1453 log_unit_debug(unit, "Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
9f04bd52 1454
c6497ccb 1455 type = job_type_collapse(type, unit);
e0209d83 1456
23ade460 1457 tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
7527cb52
MS
1458 if (!tr)
1459 return -ENOMEM;
11dd41ce 1460
4bd29fe5 1461 r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, false,
3742095b 1462 IN_SET(mode, JOB_IGNORE_DEPENDENCIES, JOB_IGNORE_REQUIREMENTS),
b94fbd30 1463 mode == JOB_IGNORE_DEPENDENCIES, e);
7527cb52
MS
1464 if (r < 0)
1465 goto tr_abort;
c497c7a9 1466
7527cb52
MS
1467 if (mode == JOB_ISOLATE) {
1468 r = transaction_add_isolate_jobs(tr, m);
1469 if (r < 0)
1470 goto tr_abort;
1471 }
1472
1473 r = transaction_activate(tr, m, mode, e);
1474 if (r < 0)
1475 goto tr_abort;
e5b5ae50 1476
f2341e0a 1477 log_unit_debug(unit,
66870f90
ZJS
1478 "Enqueued job %s/%s as %u", unit->id,
1479 job_type_to_string(type), (unsigned) tr->anchor_job->id);
f50e0a01 1480
e5b5ae50 1481 if (_ret)
b94fbd30 1482 *_ret = tr->anchor_job;
60918275 1483
7527cb52 1484 transaction_free(tr);
e5b5ae50 1485 return 0;
7527cb52
MS
1486
1487tr_abort:
1488 transaction_abort(tr);
1489 transaction_free(tr);
1490 return r;
e5b5ae50 1491}
60918275 1492
53f18416 1493int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, sd_bus_error *e, Job **ret) {
4440b27d 1494 Unit *unit = NULL; /* just to appease gcc, initialization is not really necessary */
28247076
LP
1495 int r;
1496
1497 assert(m);
1498 assert(type < _JOB_TYPE_MAX);
1499 assert(name);
1500 assert(mode < _JOB_MODE_MAX);
1501
c3090674
LP
1502 r = manager_load_unit(m, name, NULL, NULL, &unit);
1503 if (r < 0)
28247076 1504 return r;
4440b27d 1505 assert(unit);
28247076 1506
53f18416
LP
1507 return manager_add_job(m, type, unit, mode, e, ret);
1508}
1509
1510int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Job **ret) {
4afd3348 1511 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
53f18416
LP
1512 int r;
1513
1514 assert(m);
1515 assert(type < _JOB_TYPE_MAX);
1516 assert(name);
1517 assert(mode < _JOB_MODE_MAX);
1518
1519 r = manager_add_job_by_name(m, type, name, mode, &error, ret);
1520 if (r < 0)
1521 return log_warning_errno(r, "Failed to enqueue %s job for %s: %s", job_mode_to_string(mode), name, bus_error_message(&error, r));
1522
1523 return r;
28247076
LP
1524}
1525
15d167f8
JW
1526int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e) {
1527 int r;
1528 Transaction *tr;
1529
1530 assert(m);
1531 assert(unit);
1532 assert(mode < _JOB_MODE_MAX);
1533 assert(mode != JOB_ISOLATE); /* Isolate is only valid for start */
1534
1535 tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
1536 if (!tr)
1537 return -ENOMEM;
1538
1539 /* We need an anchor job */
1540 r = transaction_add_job_and_dependencies(tr, JOB_NOP, unit, NULL, false, false, true, true, e);
1541 if (r < 0)
1542 goto tr_abort;
1543
1544 /* Failure in adding individual dependencies is ignored, so this always succeeds. */
1545 transaction_add_propagate_reload_jobs(tr, unit, tr->anchor_job, mode == JOB_IGNORE_DEPENDENCIES, e);
1546
1547 r = transaction_activate(tr, m, mode, e);
1548 if (r < 0)
1549 goto tr_abort;
1550
1551 transaction_free(tr);
1552 return 0;
1553
1554tr_abort:
1555 transaction_abort(tr);
1556 transaction_free(tr);
1557 return r;
1558}
1559
60918275
LP
1560Job *manager_get_job(Manager *m, uint32_t id) {
1561 assert(m);
1562
1563 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
1564}
1565
87f0e418 1566Unit *manager_get_unit(Manager *m, const char *name) {
60918275
LP
1567 assert(m);
1568 assert(name);
1569
87f0e418 1570 return hashmap_get(m->units, name);
60918275
LP
1571}
1572
c1e1601e 1573unsigned manager_dispatch_load_queue(Manager *m) {
595ed347 1574 Unit *u;
c1e1601e 1575 unsigned n = 0;
60918275
LP
1576
1577 assert(m);
1578
223dabab
LP
1579 /* Make sure we are not run recursively */
1580 if (m->dispatching_load_queue)
c1e1601e 1581 return 0;
223dabab
LP
1582
1583 m->dispatching_load_queue = true;
1584
87f0e418 1585 /* Dispatches the load queue. Takes a unit from the queue and
60918275
LP
1586 * tries to load its data until the queue is empty */
1587
595ed347
MS
1588 while ((u = m->load_queue)) {
1589 assert(u->in_load_queue);
034c6ed7 1590
595ed347 1591 unit_load(u);
c1e1601e 1592 n++;
60918275
LP
1593 }
1594
223dabab 1595 m->dispatching_load_queue = false;
c1e1601e 1596 return n;
60918275
LP
1597}
1598
c2756a68
LP
1599int manager_load_unit_prepare(
1600 Manager *m,
1601 const char *name,
1602 const char *path,
718db961 1603 sd_bus_error *e,
c2756a68
LP
1604 Unit **_ret) {
1605
87f0e418 1606 Unit *ret;
7d17cfbc 1607 UnitType t;
60918275
LP
1608 int r;
1609
1610 assert(m);
9e2f7c11 1611 assert(name || path);
7a6a095a 1612 assert(_ret);
60918275 1613
db06e3b6
LP
1614 /* This will prepare the unit for loading, but not actually
1615 * load anything from disk. */
0301abf4 1616
718db961
LP
1617 if (path && !is_path(path))
1618 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
9e2f7c11
LP
1619
1620 if (!name)
2b6bf07d 1621 name = basename(path);
9e2f7c11 1622
7d17cfbc
MS
1623 t = unit_name_to_type(name);
1624
5d512d54
LN
1625 if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
1626 if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
1627 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is missing the instance name.", name);
1628
718db961 1629 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name);
5d512d54 1630 }
60918275 1631
7d17cfbc
MS
1632 ret = manager_get_unit(m, name);
1633 if (ret) {
034c6ed7 1634 *_ret = ret;
413d6313 1635 return 1;
034c6ed7 1636 }
60918275 1637
7d17cfbc
MS
1638 ret = unit_new(m, unit_vtable[t]->object_size);
1639 if (!ret)
60918275
LP
1640 return -ENOMEM;
1641
7d17cfbc 1642 if (path) {
ac155bb8
MS
1643 ret->fragment_path = strdup(path);
1644 if (!ret->fragment_path) {
0301abf4
LP
1645 unit_free(ret);
1646 return -ENOMEM;
1647 }
7d17cfbc 1648 }
0301abf4 1649
1058cbf2
ZJS
1650 r = unit_add_name(ret, name);
1651 if (r < 0) {
87f0e418 1652 unit_free(ret);
1ffba6fe 1653 return r;
60918275
LP
1654 }
1655
87f0e418 1656 unit_add_to_load_queue(ret);
c1e1601e 1657 unit_add_to_dbus_queue(ret);
949061f0 1658 unit_add_to_gc_queue(ret);
c1e1601e 1659
7a6a095a 1660 *_ret = ret;
db06e3b6
LP
1661
1662 return 0;
1663}
1664
c2756a68
LP
1665int manager_load_unit(
1666 Manager *m,
1667 const char *name,
1668 const char *path,
718db961 1669 sd_bus_error *e,
c2756a68
LP
1670 Unit **_ret) {
1671
db06e3b6
LP
1672 int r;
1673
1674 assert(m);
7a6a095a 1675 assert(_ret);
db06e3b6
LP
1676
1677 /* This will load the service information files, but not actually
1678 * start any services or anything. */
1679
c3090674
LP
1680 r = manager_load_unit_prepare(m, name, path, e, _ret);
1681 if (r != 0)
db06e3b6
LP
1682 return r;
1683
f50e0a01 1684 manager_dispatch_load_queue(m);
60918275 1685
7a6a095a 1686 *_ret = unit_follow_merge(*_ret);
9e2f7c11 1687
60918275
LP
1688 return 0;
1689}
a66d02c3 1690
cea8e32e 1691void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1692 Iterator i;
a66d02c3
LP
1693 Job *j;
1694
1695 assert(s);
1696 assert(f);
1697
034c6ed7 1698 HASHMAP_FOREACH(j, s->jobs, i)
cea8e32e 1699 job_dump(j, f, prefix);
a66d02c3
LP
1700}
1701
87f0e418 1702void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1703 Iterator i;
87f0e418 1704 Unit *u;
11dd41ce 1705 const char *t;
a66d02c3
LP
1706
1707 assert(s);
1708 assert(f);
1709
87f0e418 1710 HASHMAP_FOREACH_KEY(u, t, s->units, i)
ac155bb8 1711 if (u->id == t)
87f0e418 1712 unit_dump(u, f, prefix);
a66d02c3 1713}
7fad411c 1714
ad75b9e7
LP
1715void manager_dump(Manager *m, FILE *f, const char *prefix) {
1716 ManagerTimestamp q;
1717
1718 assert(m);
1719 assert(f);
1720
1721 for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
1722 char buf[FORMAT_TIMESTAMP_MAX];
1723
1724 if (dual_timestamp_is_set(m->timestamps + q))
1725 fprintf(f, "%sTimestamp %s: %s\n",
1726 strempty(prefix),
1727 manager_timestamp_to_string(q),
1728 format_timestamp(buf, sizeof(buf), m->timestamps[q].realtime));
1729 }
1730
1731 manager_dump_units(m, f, prefix);
1732 manager_dump_jobs(m, f, prefix);
1733}
1734
713f6f90
LP
1735int manager_get_dump_string(Manager *m, char **ret) {
1736 _cleanup_free_ char *dump = NULL;
1737 _cleanup_fclose_ FILE *f = NULL;
1738 size_t size;
1739 int r;
1740
1741 assert(m);
1742 assert(ret);
1743
1744 f = open_memstream(&dump, &size);
1745 if (!f)
1746 return -errno;
1747
1748 __fsetlocking(f, FSETLOCKING_BYCALLER);
1749
1750 manager_dump(m, f, NULL);
1751
1752 r = fflush_and_check(f);
1753 if (r < 0)
1754 return r;
1755
1756 f = safe_fclose(f);
1757
1758 *ret = dump;
1759 dump = NULL;
1760
1761 return 0;
1762}
1763
7fad411c
LP
1764void manager_clear_jobs(Manager *m) {
1765 Job *j;
1766
1767 assert(m);
1768
7fad411c 1769 while ((j = hashmap_first(m->jobs)))
5273510e 1770 /* No need to recurse. We're cancelling all jobs. */
833f92ad 1771 job_finish_and_invalidate(j, JOB_CANCELED, false, false);
7fad411c 1772}
83c60c9f 1773
752b5905
LP
1774static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
1775 Manager *m = userdata;
83c60c9f 1776 Job *j;
034c6ed7 1777
752b5905
LP
1778 assert(source);
1779 assert(m);
9152c765 1780
034c6ed7 1781 while ((j = m->run_queue)) {
ac1135be 1782 assert(j->installed);
034c6ed7
LP
1783 assert(j->in_run_queue);
1784
1785 job_run_and_invalidate(j);
9152c765 1786 }
034c6ed7 1787
a0b64226 1788 if (m->n_running_jobs > 0)
03b717a3
MS
1789 manager_watch_jobs_in_progress(m);
1790
31a7eb86
ZJS
1791 if (m->n_on_console > 0)
1792 manager_watch_idle_pipe(m);
1793
752b5905 1794 return 1;
c1e1601e
LP
1795}
1796
9588bc32 1797static unsigned manager_dispatch_dbus_queue(Manager *m) {
c1e1601e 1798 Job *j;
595ed347 1799 Unit *u;
c1e1601e
LP
1800 unsigned n = 0;
1801
1802 assert(m);
1803
1804 if (m->dispatching_dbus_queue)
1805 return 0;
1806
1807 m->dispatching_dbus_queue = true;
1808
595ed347
MS
1809 while ((u = m->dbus_unit_queue)) {
1810 assert(u->in_dbus_queue);
c1e1601e 1811
595ed347 1812 bus_unit_send_change_signal(u);
c1e1601e
LP
1813 n++;
1814 }
1815
1816 while ((j = m->dbus_job_queue)) {
1817 assert(j->in_dbus_queue);
1818
1819 bus_job_send_change_signal(j);
1820 n++;
1821 }
1822
1823 m->dispatching_dbus_queue = false;
71445ae7
LP
1824
1825 if (m->send_reloading_done) {
1826 m->send_reloading_done = false;
1827
718db961 1828 bus_manager_send_reloading(m, false);
71445ae7
LP
1829 }
1830
718db961
LP
1831 if (m->queued_message)
1832 bus_send_queued_message(m);
1833
c1e1601e 1834 return n;
9152c765
LP
1835}
1836
d8fdc620
LP
1837static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1838 Manager *m = userdata;
1839 char buf[PATH_MAX+1];
1840 ssize_t n;
1841
1842 n = recv(fd, buf, sizeof(buf), 0);
1843 if (n < 0)
1844 return log_error_errno(errno, "Failed to read cgroups agent message: %m");
1845 if (n == 0) {
1846 log_error("Got zero-length cgroups agent message, ignoring.");
1847 return 0;
1848 }
1849 if ((size_t) n >= sizeof(buf)) {
1850 log_error("Got overly long cgroups agent message, ignoring.");
1851 return 0;
1852 }
1853
1854 if (memchr(buf, 0, n)) {
1855 log_error("Got cgroups agent message with embedded NUL byte, ignoring.");
1856 return 0;
1857 }
1858 buf[n] = 0;
1859
1860 manager_notify_cgroup_empty(m, buf);
d5f15326 1861 (void) bus_forward_agent_released(m, buf);
d8fdc620
LP
1862
1863 return 0;
1864}
1865
8523bf7d 1866static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, const char *buf, FDSet *fds) {
5ba6985b
LP
1867 _cleanup_strv_free_ char **tags = NULL;
1868
1869 assert(m);
1870 assert(u);
1871 assert(buf);
5ba6985b
LP
1872
1873 tags = strv_split(buf, "\n\r");
1874 if (!tags) {
1875 log_oom();
1876 return;
1877 }
1878
5ba6985b 1879 if (UNIT_VTABLE(u)->notify_message)
a354329f 1880 UNIT_VTABLE(u)->notify_message(u, pid, tags, fds);
a86b7675
ZJS
1881 else if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
1882 _cleanup_free_ char *x = NULL, *y = NULL;
1883
1884 x = cescape(buf);
1885 if (x)
1886 y = ellipsize(x, 20, 90);
1887 log_unit_debug(u, "Got notification message \"%s\", ignoring.", strnull(y));
1888 }
5ba6985b
LP
1889}
1890
718db961 1891static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
3d0b8a55 1892
b215b0ed 1893 _cleanup_fdset_free_ FDSet *fds = NULL;
718db961 1894 Manager *m = userdata;
b215b0ed
DH
1895 char buf[NOTIFY_BUFFER_MAX+1];
1896 struct iovec iovec = {
1897 .iov_base = buf,
1898 .iov_len = sizeof(buf)-1,
1899 };
1900 union {
1901 struct cmsghdr cmsghdr;
1902 uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
1903 CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
1904 } control = {};
1905 struct msghdr msghdr = {
1906 .msg_iov = &iovec,
1907 .msg_iovlen = 1,
1908 .msg_control = &control,
1909 .msg_controllen = sizeof(control),
1910 };
1911
1912 struct cmsghdr *cmsg;
1913 struct ucred *ucred = NULL;
b215b0ed
DH
1914 Unit *u1, *u2, *u3;
1915 int r, *fd_array = NULL;
1916 unsigned n_fds = 0;
8c47c732
LP
1917 ssize_t n;
1918
1919 assert(m);
718db961
LP
1920 assert(m->notify_fd == fd);
1921
1922 if (revents != EPOLLIN) {
1923 log_warning("Got unexpected poll event for notify fd.");
1924 return 0;
1925 }
8c47c732 1926
045a3d59 1927 n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC);
b215b0ed 1928 if (n < 0) {
c55ae51e
LP
1929 if (IN_SET(errno, EAGAIN, EINTR))
1930 return 0; /* Spurious wakeup, try again */
8c47c732 1931
c55ae51e
LP
1932 /* If this is any other, real error, then let's stop processing this socket. This of course means we
1933 * won't take notification messages anymore, but that's still better than busy looping around this:
1934 * being woken up over and over again but being unable to actually read the message off the socket. */
1935 return log_error_errno(errno, "Failed to receive notification message: %m");
b215b0ed 1936 }
a354329f 1937
b215b0ed
DH
1938 CMSG_FOREACH(cmsg, &msghdr) {
1939 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
a354329f 1940
b215b0ed
DH
1941 fd_array = (int*) CMSG_DATA(cmsg);
1942 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
a354329f 1943
b215b0ed
DH
1944 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1945 cmsg->cmsg_type == SCM_CREDENTIALS &&
1946 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
a354329f 1947
b215b0ed 1948 ucred = (struct ucred*) CMSG_DATA(cmsg);
a354329f 1949 }
b215b0ed 1950 }
a354329f 1951
b215b0ed
DH
1952 if (n_fds > 0) {
1953 assert(fd_array);
a354329f 1954
b215b0ed
DH
1955 r = fdset_new_array(&fds, fd_array, n_fds);
1956 if (r < 0) {
1957 close_many(fd_array, n_fds);
9987750e
FB
1958 log_oom();
1959 return 0;
a354329f 1960 }
b215b0ed 1961 }
8c47c732 1962
b215b0ed
DH
1963 if (!ucred || ucred->pid <= 0) {
1964 log_warning("Received notify message without valid credentials. Ignoring.");
1965 return 0;
1966 }
8c47c732 1967
045a3d59 1968 if ((size_t) n >= sizeof(buf) || (msghdr.msg_flags & MSG_TRUNC)) {
b215b0ed
DH
1969 log_warning("Received notify message exceeded maximum size. Ignoring.");
1970 return 0;
1971 }
8c47c732 1972
875ca88d
LP
1973 /* As extra safety check, let's make sure the string we get doesn't contain embedded NUL bytes. We permit one
1974 * trailing NUL byte in the message, but don't expect it. */
1975 if (n > 1 && memchr(buf, 0, n-1)) {
1976 log_warning("Received notify message with embedded NUL bytes. Ignoring.");
1977 return 0;
1978 }
1979
1980 /* Make sure it's NUL-terminated. */
b215b0ed 1981 buf[n] = 0;
8c47c732 1982
b215b0ed
DH
1983 /* Notify every unit that might be interested, but try
1984 * to avoid notifying the same one multiple times. */
1985 u1 = manager_get_unit_by_pid_cgroup(m, ucred->pid);
c4bee3c4 1986 if (u1)
8523bf7d 1987 manager_invoke_notify_message(m, u1, ucred->pid, buf, fds);
5ba6985b 1988
b215b0ed 1989 u2 = hashmap_get(m->watch_pids1, PID_TO_PTR(ucred->pid));
c4bee3c4 1990 if (u2 && u2 != u1)
8523bf7d 1991 manager_invoke_notify_message(m, u2, ucred->pid, buf, fds);
5ba6985b 1992
b215b0ed 1993 u3 = hashmap_get(m->watch_pids2, PID_TO_PTR(ucred->pid));
c4bee3c4 1994 if (u3 && u3 != u2 && u3 != u1)
8523bf7d 1995 manager_invoke_notify_message(m, u3, ucred->pid, buf, fds);
8c47c732 1996
c4bee3c4 1997 if (!u1 && !u2 && !u3)
b215b0ed 1998 log_warning("Cannot find unit for notify message of PID "PID_FMT".", ucred->pid);
a354329f 1999
b215b0ed 2000 if (fdset_size(fds) > 0)
5fd2c135 2001 log_warning("Got extra auxiliary fds with notification message, closing them.");
8c47c732
LP
2002
2003 return 0;
2004}
2005
96d66d89 2006static void invoke_sigchld_event(Manager *m, Unit *u, const siginfo_t *si) {
36f20ae3
KW
2007 uint64_t iteration;
2008
5ba6985b
LP
2009 assert(m);
2010 assert(u);
2011 assert(si);
2012
36f20ae3
KW
2013 sd_event_get_iteration(m->event, &iteration);
2014
f2341e0a 2015 log_unit_debug(u, "Child "PID_FMT" belongs to %s", si->si_pid, u->id);
5ba6985b
LP
2016
2017 unit_unwatch_pid(u, si->si_pid);
e57051f5 2018
36f20ae3 2019 if (UNIT_VTABLE(u)->sigchld_event) {
ccc2c98e
LN
2020 if (set_size(u->pids) <= 1 ||
2021 iteration != u->sigchldgen ||
2022 unit_main_pid(u) == si->si_pid ||
2023 unit_control_pid(u) == si->si_pid) {
36f20ae3
KW
2024 UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
2025 u->sigchldgen = iteration;
2026 } else
1e706c8d 2027 log_debug("%s already issued a sigchld this iteration %" PRIu64 ", skipping. Pids still being watched %d", u->id, iteration, set_size(u->pids));
36f20ae3 2028 }
5ba6985b
LP
2029}
2030
034c6ed7 2031static int manager_dispatch_sigchld(Manager *m) {
9152c765
LP
2032 assert(m);
2033
2034 for (;;) {
b92bea5d 2035 siginfo_t si = {};
9152c765 2036
4112df16
LP
2037 /* First we call waitd() for a PID and do not reap the
2038 * zombie. That way we can still access /proc/$PID for
2039 * it while it is a zombie. */
2040 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
acbb0225
LP
2041
2042 if (errno == ECHILD)
2043 break;
2044
4112df16
LP
2045 if (errno == EINTR)
2046 continue;
2047
9152c765 2048 return -errno;
acbb0225 2049 }
9152c765 2050
4112df16 2051 if (si.si_pid <= 0)
9152c765
LP
2052 break;
2053
3742095b 2054 if (IN_SET(si.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)) {
7fd1b19b 2055 _cleanup_free_ char *name = NULL;
70af4d17 2056 Unit *u1, *u2, *u3;
4112df16 2057
87d2c1ff 2058 get_process_comm(si.si_pid, &name);
4112df16 2059
5ba6985b
LP
2060 log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)",
2061 si.si_pid, strna(name),
2062 sigchld_code_to_string(si.si_code),
2063 si.si_status,
2064 strna(si.si_code == CLD_EXITED
2065 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
2066 : signal_to_string(si.si_status)));
2067
2068 /* And now figure out the unit this belongs
2069 * to, it might be multiple... */
b3ac818b 2070 u1 = manager_get_unit_by_pid_cgroup(m, si.si_pid);
70af4d17
LP
2071 if (u1)
2072 invoke_sigchld_event(m, u1, &si);
fea72cc0 2073 u2 = hashmap_get(m->watch_pids1, PID_TO_PTR(si.si_pid));
70af4d17
LP
2074 if (u2 && u2 != u1)
2075 invoke_sigchld_event(m, u2, &si);
fea72cc0 2076 u3 = hashmap_get(m->watch_pids2, PID_TO_PTR(si.si_pid));
70af4d17
LP
2077 if (u3 && u3 != u2 && u3 != u1)
2078 invoke_sigchld_event(m, u3, &si);
5ba6985b 2079 }
8c47c732 2080
4112df16
LP
2081 /* And now, we actually reap the zombie. */
2082 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
2083 if (errno == EINTR)
2084 continue;
2085
2086 return -errno;
2087 }
9152c765
LP
2088 }
2089
2090 return 0;
2091}
2092
c75fbada 2093static void manager_start_target(Manager *m, const char *name, JobMode mode) {
4afd3348 2094 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
28247076 2095 int r;
398ef8ba 2096
f2341e0a 2097 log_debug("Activating special unit %s", name);
1e001f52 2098
4bd29fe5 2099 r = manager_add_job_by_name(m, JOB_START, name, mode, &error, NULL);
bd0af849 2100 if (r < 0)
f2341e0a 2101 log_error("Failed to enqueue %s job: %s", name, bus_error_message(&error, r));
28247076
LP
2102}
2103
24dd31c1
LN
2104static void manager_handle_ctrl_alt_del(Manager *m) {
2105 /* If the user presses C-A-D more than
2106 * 7 times within 2s, we reboot/shutdown immediately,
2107 * unless it was disabled in system.conf */
2108
ae8c7939 2109 if (ratelimit_test(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE)
24dd31c1 2110 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
ae8c7939
LN
2111 else
2112 emergency_action(m, m->cad_burst_action, NULL,
2113 "Ctrl-Alt-Del was pressed more than 7 times within 2s");
24dd31c1
LN
2114}
2115
718db961
LP
2116static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
2117 Manager *m = userdata;
9152c765
LP
2118 ssize_t n;
2119 struct signalfd_siginfo sfsi;
2120 bool sigchld = false;
dacd6cee 2121 int r;
9152c765
LP
2122
2123 assert(m);
718db961
LP
2124 assert(m->signal_fd == fd);
2125
2126 if (revents != EPOLLIN) {
2127 log_warning("Got unexpected events from signal file descriptor.");
2128 return 0;
2129 }
9152c765
LP
2130
2131 for (;;) {
718db961 2132 n = read(m->signal_fd, &sfsi, sizeof(sfsi));
57cb4adf 2133 if (n != sizeof(sfsi)) {
8f4d6401
ZJS
2134 if (n >= 0) {
2135 log_warning("Truncated read from signal fd (%zu bytes)!", n);
2136 return 0;
2137 }
9152c765 2138
8f4d6401 2139 if (IN_SET(errno, EINTR, EAGAIN))
acbb0225 2140 break;
9152c765 2141
8f4d6401
ZJS
2142 /* We return an error here, which will kill this handler,
2143 * to avoid a busy loop on read error. */
2144 return log_error_errno(errno, "Reading from signal fd failed: %m");
9152c765
LP
2145 }
2146
4daf54a8 2147 log_received_signal(sfsi.ssi_signo == SIGCHLD ||
463d0d15 2148 (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m))
4daf54a8
ZJS
2149 ? LOG_DEBUG : LOG_INFO,
2150 &sfsi);
1e001f52 2151
b9cd2ec1
LP
2152 switch (sfsi.ssi_signo) {
2153
4112df16 2154 case SIGCHLD:
9152c765 2155 sigchld = true;
b9cd2ec1
LP
2156 break;
2157
6632c602 2158 case SIGTERM:
463d0d15 2159 if (MANAGER_IS_SYSTEM(m)) {
db06e3b6
LP
2160 /* This is for compatibility with the
2161 * original sysvinit */
ae57dad3
LP
2162 r = verify_run_space_and_log("Refusing to reexecute");
2163 if (r >= 0)
2164 m->exit_code = MANAGER_REEXECUTE;
a1b256b0
LP
2165 break;
2166 }
84e9af1e 2167
4831981d 2168 _fallthrough_;
e11dc4a2 2169 case SIGINT:
c75fbada 2170 if (MANAGER_IS_SYSTEM(m))
24dd31c1 2171 manager_handle_ctrl_alt_del(m);
c75fbada 2172 else
d60cb656
AJ
2173 manager_start_target(m, SPECIAL_EXIT_TARGET,
2174 JOB_REPLACE_IRREVERSIBLY);
a1b256b0 2175 break;
84e9af1e 2176
28247076 2177 case SIGWINCH:
463d0d15 2178 if (MANAGER_IS_SYSTEM(m))
7d793605 2179 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
84e9af1e 2180
28247076
LP
2181 /* This is a nop on non-init */
2182 break;
84e9af1e 2183
28247076 2184 case SIGPWR:
463d0d15 2185 if (MANAGER_IS_SYSTEM(m))
7d793605 2186 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
84e9af1e 2187
28247076 2188 /* This is a nop on non-init */
84e9af1e 2189 break;
6632c602 2190
1005d14f 2191 case SIGUSR1: {
57ee42ce
LP
2192 Unit *u;
2193
2194 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
2195
2196 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
2197 log_info("Trying to reconnect to bus...");
3996fbe2 2198 bus_init(m, true);
57ee42ce
LP
2199 }
2200
2201 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
2202 log_info("Loading D-Bus service...");
7d793605 2203 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
57ee42ce
LP
2204 }
2205
2206 break;
2207 }
2208
2149e37c 2209 case SIGUSR2: {
718db961 2210 _cleanup_free_ char *dump = NULL;
2149e37c 2211
713f6f90 2212 r = manager_get_dump_string(m, &dump);
dacd6cee 2213 if (r < 0) {
713f6f90 2214 log_warning_errno(errno, "Failed to acquire manager dump: %m");
b2cdc666
DM
2215 break;
2216 }
2217
2149e37c 2218 log_dump(LOG_INFO, dump);
1005d14f 2219 break;
2149e37c 2220 }
1005d14f 2221
a16e1123 2222 case SIGHUP:
ae57dad3
LP
2223 r = verify_run_space_and_log("Refusing to reload");
2224 if (r >= 0)
2225 m->exit_code = MANAGER_RELOAD;
a16e1123
LP
2226 break;
2227
7d793605 2228 default: {
253ee27a 2229
0003d1ab 2230 /* Starting SIGRTMIN+0 */
d60cb656
AJ
2231 static const struct {
2232 const char *target;
2233 JobMode mode;
2234 } target_table[] = {
2235 [0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
2236 [1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
2237 [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
2238 [3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
2239 [4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
2240 [5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
2241 [6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY }
0003d1ab
LP
2242 };
2243
2244 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
2245 static const ManagerExitCode code_table[] = {
2246 [0] = MANAGER_HALT,
2247 [1] = MANAGER_POWEROFF,
2248 [2] = MANAGER_REBOOT,
2249 [3] = MANAGER_KEXEC
7d793605
LP
2250 };
2251
2252 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
0003d1ab 2253 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
764e9b5f 2254 int idx = (int) sfsi.ssi_signo - SIGRTMIN;
d60cb656
AJ
2255 manager_start_target(m, target_table[idx].target,
2256 target_table[idx].mode);
7d793605
LP
2257 break;
2258 }
2259
0003d1ab
LP
2260 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
2261 (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
2262 m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
2263 break;
2264 }
2265
0658666b
LP
2266 switch (sfsi.ssi_signo - SIGRTMIN) {
2267
2268 case 20:
d450b6f2 2269 manager_set_show_status(m, SHOW_STATUS_YES);
0658666b
LP
2270 break;
2271
2272 case 21:
d450b6f2 2273 manager_set_show_status(m, SHOW_STATUS_NO);
0658666b
LP
2274 break;
2275
253ee27a
LP
2276 case 22:
2277 log_set_max_level(LOG_DEBUG);
4cee3a78 2278 log_info("Setting log level to debug.");
253ee27a
LP
2279 break;
2280
2281 case 23:
2282 log_set_max_level(LOG_INFO);
4cee3a78 2283 log_info("Setting log level to info.");
253ee27a
LP
2284 break;
2285
600b704e 2286 case 24:
463d0d15 2287 if (MANAGER_IS_USER(m)) {
600b704e
LP
2288 m->exit_code = MANAGER_EXIT;
2289 return 0;
2290 }
2291
2292 /* This is a nop on init */
2293 break;
2294
4cfa2c99 2295 case 26:
c1dc6153 2296 case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
4cfa2c99
LP
2297 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
2298 log_notice("Setting log target to journal-or-kmsg.");
2299 break;
2300
253ee27a
LP
2301 case 27:
2302 log_set_target(LOG_TARGET_CONSOLE);
2303 log_notice("Setting log target to console.");
2304 break;
2305
2306 case 28:
2307 log_set_target(LOG_TARGET_KMSG);
2308 log_notice("Setting log target to kmsg.");
2309 break;
2310
0658666b 2311 default:
4e240ab0 2312 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
0658666b 2313 }
b9cd2ec1 2314 }
7d793605 2315 }
9152c765
LP
2316 }
2317
2318 if (sigchld)
7b77ed8c 2319 manager_dispatch_sigchld(m);
034c6ed7
LP
2320
2321 return 0;
2322}
2323
718db961
LP
2324static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
2325 Manager *m = userdata;
2326 Iterator i;
2327 Unit *u;
034c6ed7
LP
2328
2329 assert(m);
718db961 2330 assert(m->time_change_fd == fd);
034c6ed7 2331
a80c1575 2332 log_struct(LOG_DEBUG,
2b044526 2333 "MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,
e2cc6eca 2334 LOG_MESSAGE("Time has been changed"),
718db961 2335 NULL);
034c6ed7 2336
718db961
LP
2337 /* Restart the watch */
2338 m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
03e334a1 2339 m->time_change_fd = safe_close(m->time_change_fd);
ef734fd6 2340
718db961 2341 manager_setup_time_change(m);
4e434314 2342
718db961
LP
2343 HASHMAP_FOREACH(u, m->units, i)
2344 if (UNIT_VTABLE(u)->time_change)
2345 UNIT_VTABLE(u)->time_change(u);
ea430986 2346
718db961
LP
2347 return 0;
2348}
ea430986 2349
718db961
LP
2350static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
2351 Manager *m = userdata;
8742514c 2352
718db961
LP
2353 assert(m);
2354 assert(m->idle_pipe[2] == fd);
8742514c 2355
718db961 2356 m->no_console_output = m->n_on_console > 0;
03b717a3 2357
718db961 2358 manager_close_idle_pipe(m);
03b717a3 2359
718db961
LP
2360 return 0;
2361}
31a7eb86 2362
718db961
LP
2363static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
2364 Manager *m = userdata;
fd08a840
ZJS
2365 int r;
2366 uint64_t next;
31a7eb86 2367
718db961 2368 assert(m);
fd08a840 2369 assert(source);
9152c765 2370
718db961 2371 manager_print_jobs_in_progress(m);
fd08a840
ZJS
2372
2373 next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
2374 r = sd_event_source_set_time(source, next);
2375 if (r < 0)
2376 return r;
2377
2378 return sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
9152c765
LP
2379}
2380
2381int manager_loop(Manager *m) {
2382 int r;
9152c765 2383
fac9f8df 2384 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
ea430986 2385
9152c765 2386 assert(m);
f755e3b7 2387 m->exit_code = MANAGER_OK;
9152c765 2388
fe51822e 2389 /* Release the path cache */
97044145 2390 m->unit_path_cache = set_free_free(m->unit_path_cache);
fe51822e 2391
b0c918b9
LP
2392 manager_check_finished(m);
2393
a4312405 2394 /* There might still be some zombies hanging around from
f3669545 2395 * before we were exec()'ed. Let's reap them. */
e96d6be7
LP
2396 r = manager_dispatch_sigchld(m);
2397 if (r < 0)
a4312405
LP
2398 return r;
2399
f755e3b7 2400 while (m->exit_code == MANAGER_OK) {
718db961 2401 usec_t wait_usec;
9152c765 2402
463d0d15 2403 if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && MANAGER_IS_SYSTEM(m))
e96d6be7
LP
2404 watchdog_ping();
2405
ea430986
LP
2406 if (!ratelimit_test(&rl)) {
2407 /* Yay, something is going seriously wrong, pause a little */
2408 log_warning("Looping too fast. Throttling execution a little.");
2409 sleep(1);
2410 }
2411
37a8e683 2412 if (manager_dispatch_load_queue(m) > 0)
23a177ef
LP
2413 continue;
2414
c5a97ed1
LP
2415 if (manager_dispatch_gc_job_queue(m) > 0)
2416 continue;
2417
2418 if (manager_dispatch_gc_unit_queue(m) > 0)
701cc384
LP
2419 continue;
2420
cf1265e1 2421 if (manager_dispatch_cleanup_queue(m) > 0)
c1e1601e 2422 continue;
034c6ed7 2423
91a6073e 2424 if (manager_dispatch_cgroup_realize_queue(m) > 0)
c1e1601e
LP
2425 continue;
2426
c1e1601e 2427 if (manager_dispatch_dbus_queue(m) > 0)
ea430986 2428 continue;
ea430986 2429
c757a65b 2430 /* Sleep for half the watchdog time */
463d0d15 2431 if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && MANAGER_IS_SYSTEM(m)) {
718db961
LP
2432 wait_usec = m->runtime_watchdog / 2;
2433 if (wait_usec <= 0)
2434 wait_usec = 1;
c757a65b 2435 } else
3a43da28 2436 wait_usec = USEC_INFINITY;
9152c765 2437
718db961 2438 r = sd_event_run(m->event, wait_usec);
23bbb0de
MS
2439 if (r < 0)
2440 return log_error_errno(r, "Failed to run event loop: %m");
a16e1123 2441 }
957ca890 2442
a16e1123 2443 return m->exit_code;
83c60c9f 2444}
ea430986 2445
718db961 2446int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u) {
ede3a796 2447 _cleanup_free_ char *n = NULL;
4b58153d 2448 sd_id128_t invocation_id;
ea430986 2449 Unit *u;
80fbf05e 2450 int r;
ea430986
LP
2451
2452 assert(m);
2453 assert(s);
2454 assert(_u);
2455
ede3a796
LP
2456 r = unit_name_from_dbus_path(s, &n);
2457 if (r < 0)
2458 return r;
ea430986 2459
4b58153d
LP
2460 /* Permit addressing units by invocation ID: if the passed bus path is suffixed by a 128bit ID then we use it
2461 * as invocation ID. */
2462 r = sd_id128_from_string(n, &invocation_id);
2463 if (r >= 0) {
2464 u = hashmap_get(m->units_by_invocation_id, &invocation_id);
2465 if (u) {
2466 *_u = u;
2467 return 0;
2468 }
2469
2470 return sd_bus_error_setf(e, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(invocation_id));
2471 }
2472
00c83b43
LP
2473 /* If this didn't work, we check if this is a unit name */
2474 if (!unit_name_is_valid(n, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
2475 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is neither a valid invocation ID nor unit name.", n);
2476
80fbf05e 2477 r = manager_load_unit(m, n, NULL, e, &u);
80fbf05e
MS
2478 if (r < 0)
2479 return r;
ea430986
LP
2480
2481 *_u = u;
ea430986
LP
2482 return 0;
2483}
86fbf370
LP
2484
2485int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
718db961 2486 const char *p;
86fbf370 2487 unsigned id;
718db961 2488 Job *j;
86fbf370
LP
2489 int r;
2490
2491 assert(m);
2492 assert(s);
2493 assert(_j);
2494
718db961
LP
2495 p = startswith(s, "/org/freedesktop/systemd1/job/");
2496 if (!p)
86fbf370
LP
2497 return -EINVAL;
2498
718db961 2499 r = safe_atou(p, &id);
8742514c 2500 if (r < 0)
86fbf370
LP
2501 return r;
2502
8742514c
LP
2503 j = manager_get_job(m, id);
2504 if (!j)
86fbf370
LP
2505 return -ENOENT;
2506
2507 *_j = j;
2508
2509 return 0;
2510}
dfcd764e 2511
4927fcae 2512void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
e537352b 2513
349cc4a5 2514#if HAVE_AUDIT
2ba11090 2515 _cleanup_free_ char *p = NULL;
0aa281df 2516 const char *msg;
7410616c 2517 int audit_fd, r;
e537352b 2518
463d0d15 2519 if (!MANAGER_IS_SYSTEM(m))
a1a078ee
LP
2520 return;
2521
c1165f82
LP
2522 audit_fd = get_audit_fd();
2523 if (audit_fd < 0)
e537352b
LP
2524 return;
2525
bbd3a7ba
LP
2526 /* Don't generate audit events if the service was already
2527 * started and we're just deserializing */
2c289ea8 2528 if (MANAGER_IS_RELOADING(m))
bbd3a7ba
LP
2529 return;
2530
ac155bb8 2531 if (u->type != UNIT_SERVICE)
f1dd0c3f
LP
2532 return;
2533
7410616c
LP
2534 r = unit_name_to_prefix_and_instance(u->id, &p);
2535 if (r < 0) {
2536 log_error_errno(r, "Failed to extract prefix and instance of unit name: %m");
e537352b
LP
2537 return;
2538 }
2539
63c372cb 2540 msg = strjoina("unit=", p);
0aa281df
LP
2541 if (audit_log_user_comm_message(audit_fd, type, msg, "systemd", NULL, NULL, NULL, success) < 0) {
2542 if (errno == EPERM)
391ade86 2543 /* We aren't allowed to send audit messages?
44785992 2544 * Then let's not retry again. */
c1165f82 2545 close_audit_fd();
0aa281df 2546 else
56f64d95 2547 log_warning_errno(errno, "Failed to send audit message: %m");
391ade86 2548 }
4927fcae 2549#endif
e537352b 2550
e537352b
LP
2551}
2552
e983b760 2553void manager_send_unit_plymouth(Manager *m, Unit *u) {
fc2fffe7 2554 static const union sockaddr_union sa = PLYMOUTH_SOCKET;
2ba11090
ZJS
2555 _cleanup_free_ char *message = NULL;
2556 _cleanup_close_ int fd = -1;
fc2fffe7 2557 int n = 0;
e983b760
LP
2558
2559 /* Don't generate plymouth events if the service was already
2560 * started and we're just deserializing */
2c289ea8 2561 if (MANAGER_IS_RELOADING(m))
e983b760
LP
2562 return;
2563
463d0d15 2564 if (!MANAGER_IS_SYSTEM(m))
e983b760
LP
2565 return;
2566
75f86906 2567 if (detect_container() > 0)
3772995a
LP
2568 return;
2569
ec2ce0c5 2570 if (!IN_SET(u->type, UNIT_SERVICE, UNIT_MOUNT, UNIT_SWAP))
e983b760
LP
2571 return;
2572
2573 /* We set SOCK_NONBLOCK here so that we rather drop the
2574 * message then wait for plymouth */
e62d8c39
ZJS
2575 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
2576 if (fd < 0) {
56f64d95 2577 log_error_errno(errno, "socket() failed: %m");
e983b760
LP
2578 return;
2579 }
2580
fc2fffe7 2581 if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
e983b760 2582
2ba11090 2583 if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
56f64d95 2584 log_error_errno(errno, "connect() failed: %m");
2ba11090 2585 return;
e983b760
LP
2586 }
2587
ac155bb8 2588 if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
0d0f0c50 2589 log_oom();
2ba11090 2590 return;
e983b760
LP
2591 }
2592
2593 errno = 0;
2ba11090
ZJS
2594 if (write(fd, message, n + 1) != n + 1)
2595 if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
56f64d95 2596 log_error_errno(errno, "Failed to write Plymouth message: %m");
e983b760
LP
2597}
2598
d8d5ab98 2599int manager_open_serialization(Manager *m, FILE **_f) {
504afd7c 2600 int fd;
a16e1123
LP
2601 FILE *f;
2602
2603 assert(_f);
2604
504afd7c
ZJS
2605 fd = open_serialization_fd("systemd-state");
2606 if (fd < 0)
2607 return fd;
a16e1123 2608
01e10de3 2609 f = fdopen(fd, "w+");
d86f9d52 2610 if (!f) {
03e334a1 2611 safe_close(fd);
a16e1123 2612 return -errno;
d86f9d52 2613 }
a16e1123
LP
2614
2615 *_f = f;
a16e1123
LP
2616 return 0;
2617}
2618
b3680f49 2619int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
9f9f0342
LP
2620 ManagerTimestamp q;
2621 const char *t;
a16e1123
LP
2622 Iterator i;
2623 Unit *u;
a16e1123
LP
2624 int r;
2625
2626 assert(m);
2627 assert(f);
2628 assert(fds);
2629
313cefa1 2630 m->n_reloading++;
38c52d46 2631
1fa2f38f 2632 fprintf(f, "current-job-id=%"PRIu32"\n", m->current_job_id);
33c5fae9
LP
2633 fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
2634 fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
0c2826c6
ZJS
2635 fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
2636 fprintf(f, "ready-sent=%s\n", yes_no(m->ready_sent));
01d67b43 2637
9f9f0342
LP
2638 for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
2639 /* The userspace and finish timestamps only apply to the host system, hence only serialize them there */
2640 if (in_initrd() && IN_SET(q, MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH))
2641 continue;
f38ed060 2642
9f9f0342
LP
2643 t = manager_timestamp_to_string(q);
2644 {
2645 char field[strlen(t) + strlen("-timestamp") + 1];
2646 strcpy(stpcpy(field, t), "-timestamp");
2647 dual_timestamp_serialize(f, field, m->timestamps + q);
2648 }
f38ed060 2649 }
47a483a1 2650
fe902fa4
ZJS
2651 if (!switching_root)
2652 (void) serialize_environment(f, m->environment);
4a9fd066 2653
d86f9d52
LP
2654 if (m->notify_fd >= 0) {
2655 int copy;
2656
2657 copy = fdset_put_dup(fds, m->notify_fd);
2658 if (copy < 0)
2659 return copy;
2660
2661 fprintf(f, "notify-fd=%i\n", copy);
2662 fprintf(f, "notify-socket=%s\n", m->notify_socket);
2663 }
2664
d8fdc620
LP
2665 if (m->cgroups_agent_fd >= 0) {
2666 int copy;
2667
2668 copy = fdset_put_dup(fds, m->cgroups_agent_fd);
2669 if (copy < 0)
2670 return copy;
2671
2672 fprintf(f, "cgroups-agent-fd=%i\n", copy);
2673 }
2674
00d9ef85
LP
2675 if (m->user_lookup_fds[0] >= 0) {
2676 int copy0, copy1;
2677
2678 copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
2679 if (copy0 < 0)
2680 return copy0;
2681
2682 copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
2683 if (copy1 < 0)
2684 return copy1;
2685
2686 fprintf(f, "user-lookup=%i %i\n", copy0, copy1);
2687 }
2688
05a98afd 2689 bus_track_serialize(m->subscribed, f, "subscribed");
6fa48533 2690
29206d46
LP
2691 r = dynamic_user_serialize(m, f, fds);
2692 if (r < 0)
2693 return r;
2694
00d9ef85
LP
2695 manager_serialize_uid_refs(m, f);
2696 manager_serialize_gid_refs(m, f);
2697
4b61c875 2698 fputc_unlocked('\n', f);
f2382a94 2699
a16e1123 2700 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
ac155bb8 2701 if (u->id != t)
a16e1123
LP
2702 continue;
2703
a16e1123 2704 /* Start marker */
4b61c875
LP
2705 fputs_unlocked(u->id, f);
2706 fputc_unlocked('\n', f);
a16e1123 2707
6fa48533
LP
2708 r = unit_serialize(u, f, fds, !switching_root);
2709 if (r < 0) {
313cefa1 2710 m->n_reloading--;
a16e1123 2711 return r;
38c52d46 2712 }
a16e1123
LP
2713 }
2714
a7556052 2715 assert(m->n_reloading > 0);
313cefa1 2716 m->n_reloading--;
38c52d46 2717
a16e1123
LP
2718 if (ferror(f))
2719 return -EIO;
2720
b23de6af
LP
2721 r = bus_fdset_add_all(m, fds);
2722 if (r < 0)
2723 return r;
2724
a16e1123
LP
2725 return 0;
2726}
2727
2728int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
2729 int r = 0;
2730
2731 assert(m);
2732 assert(f);
2733
2734 log_debug("Deserializing state...");
2735
313cefa1 2736 m->n_reloading++;
82c64bf5 2737
10f8e83c 2738 for (;;) {
d233c99a
ZJS
2739 char line[LINE_MAX];
2740 const char *val, *l;
10f8e83c
LP
2741
2742 if (!fgets(line, sizeof(line), f)) {
2743 if (feof(f))
2744 r = 0;
2745 else
2746 r = -errno;
2747
2748 goto finish;
2749 }
2750
2751 char_array_0(line);
2752 l = strstrip(line);
2753
2754 if (l[0] == 0)
2755 break;
2756
fb4650aa 2757 if ((val = startswith(l, "current-job-id="))) {
01d67b43
LP
2758 uint32_t id;
2759
fb4650aa 2760 if (safe_atou32(val, &id) < 0)
62c460c6 2761 log_notice("Failed to parse current job id value %s", val);
01d67b43
LP
2762 else
2763 m->current_job_id = MAX(m->current_job_id, id);
718db961 2764
fb4650aa 2765 } else if ((val = startswith(l, "n-installed-jobs="))) {
33c5fae9
LP
2766 uint32_t n;
2767
fb4650aa 2768 if (safe_atou32(val, &n) < 0)
62c460c6 2769 log_notice("Failed to parse installed jobs counter %s", val);
33c5fae9
LP
2770 else
2771 m->n_installed_jobs += n;
718db961 2772
fb4650aa 2773 } else if ((val = startswith(l, "n-failed-jobs="))) {
33c5fae9
LP
2774 uint32_t n;
2775
fb4650aa 2776 if (safe_atou32(val, &n) < 0)
62c460c6 2777 log_notice("Failed to parse failed jobs counter %s", val);
33c5fae9
LP
2778 else
2779 m->n_failed_jobs += n;
718db961 2780
fb4650aa 2781 } else if ((val = startswith(l, "taint-usr="))) {
01d67b43
LP
2782 int b;
2783
fb4650aa 2784 b = parse_boolean(val);
e3dd987c 2785 if (b < 0)
62c460c6 2786 log_notice("Failed to parse taint /usr flag %s", val);
01d67b43
LP
2787 else
2788 m->taint_usr = m->taint_usr || b;
718db961 2789
0c2826c6
ZJS
2790 } else if ((val = startswith(l, "ready-sent="))) {
2791 int b;
2792
2793 b = parse_boolean(val);
2794 if (b < 0)
2795 log_notice("Failed to parse ready-sent flag %s", val);
2796 else
2797 m->ready_sent = m->ready_sent || b;
2798
9f9f0342 2799 } else if (startswith(l, "env=")) {
fe902fa4 2800 r = deserialize_environment(&m->environment, l);
d233c99a
ZJS
2801 if (r == -ENOMEM)
2802 goto finish;
527b7a42 2803 if (r < 0)
d233c99a 2804 log_notice_errno(r, "Failed to parse environment entry: \"%s\": %m", l);
e3dd987c 2805
fb4650aa 2806 } else if ((val = startswith(l, "notify-fd="))) {
d86f9d52
LP
2807 int fd;
2808
fb4650aa 2809 if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
62c460c6 2810 log_notice("Failed to parse notify fd: \"%s\"", val);
d86f9d52 2811 else {
03e334a1
LP
2812 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
2813 safe_close(m->notify_fd);
d86f9d52
LP
2814 m->notify_fd = fdset_remove(fds, fd);
2815 }
2816
fb4650aa 2817 } else if ((val = startswith(l, "notify-socket="))) {
d86f9d52
LP
2818 char *n;
2819
fb4650aa 2820 n = strdup(val);
d86f9d52
LP
2821 if (!n) {
2822 r = -ENOMEM;
2823 goto finish;
2824 }
2825
2826 free(m->notify_socket);
2827 m->notify_socket = n;
2828
fb4650aa 2829 } else if ((val = startswith(l, "cgroups-agent-fd="))) {
d8fdc620
LP
2830 int fd;
2831
fb4650aa 2832 if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
62c460c6 2833 log_notice("Failed to parse cgroups agent fd: %s", val);
d8fdc620
LP
2834 else {
2835 m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
2836 safe_close(m->cgroups_agent_fd);
2837 m->cgroups_agent_fd = fdset_remove(fds, fd);
2838 }
2839
fb4650aa 2840 } else if ((val = startswith(l, "user-lookup="))) {
00d9ef85
LP
2841 int fd0, fd1;
2842
fb4650aa 2843 if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
62c460c6 2844 log_notice("Failed to parse user lookup fd: %s", val);
00d9ef85
LP
2845 else {
2846 m->user_lookup_event_source = sd_event_source_unref(m->user_lookup_event_source);
2847 safe_close_pair(m->user_lookup_fds);
2848 m->user_lookup_fds[0] = fdset_remove(fds, fd0);
2849 m->user_lookup_fds[1] = fdset_remove(fds, fd1);
2850 }
2851
fb4650aa
ZJS
2852 } else if ((val = startswith(l, "dynamic-user=")))
2853 dynamic_user_deserialize_one(m, val, fds);
2854 else if ((val = startswith(l, "destroy-ipc-uid=")))
2855 manager_deserialize_uid_refs_one(m, val);
2856 else if ((val = startswith(l, "destroy-ipc-gid=")))
2857 manager_deserialize_gid_refs_one(m, val);
2858 else if ((val = startswith(l, "subscribed="))) {
05a98afd 2859
fb4650aa 2860 if (strv_extend(&m->deserialized_subscribed, val) < 0)
05a98afd 2861 log_oom();
9f9f0342
LP
2862 } else {
2863 ManagerTimestamp q;
2864
2865 for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
2866 val = startswith(l, manager_timestamp_to_string(q));
2867 if (!val)
2868 continue;
05a98afd 2869
9f9f0342
LP
2870 val = startswith(val, "-timestamp=");
2871 if (val)
2872 break;
2873 }
05a98afd 2874
9f9f0342
LP
2875 if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
2876 dual_timestamp_deserialize(val, m->timestamps + q);
2877 else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
2878 log_notice("Unknown serialization item '%s'", l);
2879 }
10f8e83c
LP
2880 }
2881
a16e1123
LP
2882 for (;;) {
2883 Unit *u;
2884 char name[UNIT_NAME_MAX+2];
07429866 2885 const char* unit_name;
a16e1123
LP
2886
2887 /* Start marker */
2888 if (!fgets(name, sizeof(name), f)) {
2889 if (feof(f))
10f8e83c
LP
2890 r = 0;
2891 else
2892 r = -errno;
a16e1123 2893
82c64bf5 2894 goto finish;
a16e1123
LP
2895 }
2896
2897 char_array_0(name);
07429866 2898 unit_name = strstrip(name);
a16e1123 2899
07429866
ZJS
2900 r = manager_load_unit(m, unit_name, NULL, NULL, &u);
2901 if (r < 0) {
2902 log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", unit_name);
2903 if (r == -ENOMEM)
2904 goto finish;
2905 unit_deserialize_skip(f);
2906 continue;
2907 }
a16e1123 2908
01e10de3 2909 r = unit_deserialize(u, f, fds);
07429866
ZJS
2910 if (r < 0) {
2911 log_notice_errno(r, "Failed to deserialize unit \"%s\": %m", unit_name);
2912 if (r == -ENOMEM)
2913 goto finish;
2914 }
a16e1123
LP
2915 }
2916
10f8e83c 2917finish:
145b1f79 2918 if (ferror(f))
82c64bf5 2919 r = -EIO;
a16e1123 2920
a7556052 2921 assert(m->n_reloading > 0);
313cefa1 2922 m->n_reloading--;
82c64bf5
LP
2923
2924 return r;
a16e1123
LP
2925}
2926
2927int manager_reload(Manager *m) {
2928 int r, q;
51d122af
ZJS
2929 _cleanup_fclose_ FILE *f = NULL;
2930 _cleanup_fdset_free_ FDSet *fds = NULL;
a16e1123
LP
2931
2932 assert(m);
2933
07719a21
LP
2934 r = manager_open_serialization(m, &f);
2935 if (r < 0)
a16e1123
LP
2936 return r;
2937
313cefa1 2938 m->n_reloading++;
718db961 2939 bus_manager_send_reloading(m, true);
38c52d46 2940
07719a21
LP
2941 fds = fdset_new();
2942 if (!fds) {
313cefa1 2943 m->n_reloading--;
51d122af 2944 return -ENOMEM;
a16e1123
LP
2945 }
2946
b3680f49 2947 r = manager_serialize(m, f, fds, false);
07719a21 2948 if (r < 0) {
313cefa1 2949 m->n_reloading--;
51d122af 2950 return r;
38c52d46 2951 }
a16e1123
LP
2952
2953 if (fseeko(f, 0, SEEK_SET) < 0) {
313cefa1 2954 m->n_reloading--;
51d122af 2955 return -errno;
a16e1123
LP
2956 }
2957
2958 /* From here on there is no way back. */
2959 manager_clear_jobs_and_units(m);
07a78643 2960 lookup_paths_flush_generator(&m->lookup_paths);
84e3543e 2961 lookup_paths_free(&m->lookup_paths);
29206d46 2962 dynamic_user_vacuum(m, false);
00d9ef85
LP
2963 m->uid_refs = hashmap_free(m->uid_refs);
2964 m->gid_refs = hashmap_free(m->gid_refs);
2ded0c04 2965
4943d143 2966 q = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
e801700e
ZJS
2967 if (q < 0 && r >= 0)
2968 r = q;
5a1e9937 2969
64691d20
ZJS
2970 q = manager_run_environment_generators(m);
2971 if (q < 0 && r >= 0)
2972 r = q;
2973
a3c4eb07
LP
2974 /* Find new unit paths */
2975 q = manager_run_generators(m);
e801700e 2976 if (q < 0 && r >= 0)
07719a21
LP
2977 r = q;
2978
a1453343 2979 lookup_paths_reduce(&m->lookup_paths);
5a1e9937
LP
2980 manager_build_unit_path_cache(m);
2981
a16e1123 2982 /* First, enumerate what we can from all config files */
ba64af90 2983 manager_enumerate(m);
a16e1123
LP
2984
2985 /* Second, deserialize our stored data */
07719a21 2986 q = manager_deserialize(m, f, fds);
07429866
ZJS
2987 if (q < 0) {
2988 log_error_errno(q, "Deserialization failed: %m");
2989
2990 if (r >= 0)
2991 r = q;
2992 }
a16e1123
LP
2993
2994 fclose(f);
2995 f = NULL;
2996
a2cc4a6c
ZJS
2997 /* Re-register notify_fd as event source */
2998 q = manager_setup_notify(m);
e801700e 2999 if (q < 0 && r >= 0)
a2cc4a6c
ZJS
3000 r = q;
3001
d8fdc620
LP
3002 q = manager_setup_cgroups_agent(m);
3003 if (q < 0 && r >= 0)
3004 r = q;
3005
00d9ef85
LP
3006 q = manager_setup_user_lookup_fd(m);
3007 if (q < 0 && r >= 0)
3008 r = q;
3009
a16e1123 3010 /* Third, fire things up! */
007c6337 3011 manager_coldplug(m);
a16e1123 3012
29206d46
LP
3013 /* Release any dynamic users no longer referenced */
3014 dynamic_user_vacuum(m, true);
3015
00d9ef85
LP
3016 /* Release any references to UIDs/GIDs no longer referenced, and destroy any IPC owned by them */
3017 manager_vacuum_uid_refs(m);
3018 manager_vacuum_gid_refs(m);
3019
8936a5e3
DM
3020 /* Sync current state of bus names with our set of listening units */
3021 if (m->api_bus)
3022 manager_sync_bus_names(m, m->api_bus);
3023
a7556052
LP
3024 assert(m->n_reloading > 0);
3025 m->n_reloading--;
9f611ad8 3026
71445ae7
LP
3027 m->send_reloading_done = true;
3028
a16e1123
LP
3029 return r;
3030}
3031
fdf20a31 3032void manager_reset_failed(Manager *m) {
5632e374
LP
3033 Unit *u;
3034 Iterator i;
3035
3036 assert(m);
3037
3038 HASHMAP_FOREACH(u, m->units, i)
fdf20a31 3039 unit_reset_failed(u);
5632e374
LP
3040}
3041
31afa0a4 3042bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
8f6df3fa
LP
3043 Unit *u;
3044
3045 assert(m);
3046 assert(name);
3047
3048 /* Returns true if the unit is inactive or going down */
bd0af849
ZJS
3049 u = manager_get_unit(m, name);
3050 if (!u)
8f6df3fa
LP
3051 return true;
3052
31afa0a4 3053 return unit_inactive_or_pending(u);
8f6df3fa
LP
3054}
3055
56dacdbc 3056static void manager_notify_finished(Manager *m) {
7ceba241 3057 char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
915b3753 3058 usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
b0c918b9 3059
e0a3da1f 3060 if (m->test_run_flags)
b0c918b9
LP
3061 return;
3062
463d0d15 3063 if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) {
e03ae661 3064
9f9f0342
LP
3065 /* Note that MANAGER_TIMESTAMP_KERNEL's monotonic value is always at 0, and
3066 * MANAGER_TIMESTAMP_FIRMWARE's and MANAGER_TIMESTAMP_LOADER's monotonic value should be considered
915b3753
LP
3067 * negative values. */
3068
9f9f0342
LP
3069 firmware_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic - m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic;
3070 loader_usec = m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
3071 userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
3072 total_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic + m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic;
18fa6b27 3073
9f9f0342 3074 if (dual_timestamp_is_set(&m->timestamps[MANAGER_TIMESTAMP_INITRD])) {
18fa6b27 3075
9f9f0342
LP
3076 /* The initrd case on bare-metal*/
3077 kernel_usec = m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
3078 initrd_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic;
18fa6b27 3079
e12919e8 3080 log_struct(LOG_INFO,
2b044526 3081 "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
e12919e8
LP
3082 "KERNEL_USEC="USEC_FMT, kernel_usec,
3083 "INITRD_USEC="USEC_FMT, initrd_usec,
3084 "USERSPACE_USEC="USEC_FMT, userspace_usec,
e2cc6eca
LP
3085 LOG_MESSAGE("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
3086 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
3087 format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
3088 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
3089 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
e12919e8 3090 NULL);
18fa6b27 3091 } else {
9f9f0342
LP
3092 /* The initrd-less case on bare-metal*/
3093
3094 kernel_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic;
18fa6b27
LP
3095 initrd_usec = 0;
3096
81270860 3097 log_struct(LOG_INFO,
2b044526 3098 "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR,
e12919e8 3099 "KERNEL_USEC="USEC_FMT, kernel_usec,
ccd06097 3100 "USERSPACE_USEC="USEC_FMT, userspace_usec,
e2cc6eca
LP
3101 LOG_MESSAGE("Startup finished in %s (kernel) + %s (userspace) = %s.",
3102 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
3103 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
3104 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
81270860 3105 NULL);
e12919e8
LP
3106 }
3107 } else {
9f9f0342 3108 /* The container case */
e12919e8 3109 firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
9f9f0342 3110 total_usec = userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
e12919e8
LP
3111
3112 log_struct(LOG_INFO,
2b044526 3113 "MESSAGE_ID=" SD_MESSAGE_USER_STARTUP_FINISHED_STR,
e12919e8 3114 "USERSPACE_USEC="USEC_FMT, userspace_usec,
e2cc6eca
LP
3115 LOG_MESSAGE("Startup finished in %s.",
3116 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
e12919e8 3117 NULL);
18fa6b27 3118 }
b0c918b9 3119
718db961 3120 bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
530345e7
LP
3121
3122 sd_notifyf(false,
0c2826c6
ZJS
3123 m->ready_sent ? "STATUS=Startup finished in %s."
3124 : "READY=1\n"
3125 "STATUS=Startup finished in %s.",
2fa4092c 3126 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
0c2826c6 3127 m->ready_sent = true;
b0c918b9
LP
3128}
3129
56dacdbc 3130void manager_check_finished(Manager *m) {
56dacdbc
ZJS
3131 assert(m);
3132
2c289ea8 3133 if (MANAGER_IS_RELOADING(m))
aad1976f
LP
3134 return;
3135
9771b62d
LP
3136 /* Verify that we are actually running currently. Initially
3137 * the exit code is set to invalid, and during operation it is
3138 * then set to MANAGER_OK */
3139 if (m->exit_code != MANAGER_OK)
3140 return;
3141
0c2826c6
ZJS
3142 /* For user managers, send out READY=1 as soon as we reach basic.target */
3143 if (MANAGER_IS_USER(m) && !m->ready_sent) {
3144 Unit *u;
3145
3146 u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
3147 if (u && !u->job) {
3148 sd_notifyf(false,
3149 "READY=1\n"
3150 "STATUS=Reached " SPECIAL_BASIC_TARGET ".");
3151 m->ready_sent = true;
3152 }
3153 }
3154
56dacdbc 3155 if (hashmap_size(m->jobs) > 0) {
56dacdbc 3156 if (m->jobs_in_progress_event_source)
2ae56591 3157 /* Ignore any failure, this is only for feedback */
e7ab4d1a 3158 (void) sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
56dacdbc
ZJS
3159
3160 return;
3161 }
3162
3163 manager_flip_auto_status(m, false);
3164
3165 /* Notify Type=idle units that we are done now */
56dacdbc
ZJS
3166 manager_close_idle_pipe(m);
3167
3168 /* Turn off confirm spawn now */
7d5ceb64 3169 m->confirm_spawn = NULL;
56dacdbc
ZJS
3170
3171 /* No need to update ask password status when we're going non-interactive */
3172 manager_close_ask_password(m);
3173
3174 /* This is no longer the first boot */
3175 manager_set_first_boot(m, false);
3176
49d5666c 3177 if (MANAGER_IS_FINISHED(m))
56dacdbc
ZJS
3178 return;
3179
9f9f0342 3180 dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH);
56dacdbc
ZJS
3181
3182 manager_notify_finished(m);
3183
e7ab4d1a 3184 manager_invalidate_startup_units(m);
56dacdbc
ZJS
3185}
3186
64691d20
ZJS
3187static bool generator_path_any(const char* const* paths) {
3188 char **path;
3189 bool found = false;
3190
3191 /* Optimize by skipping the whole process by not creating output directories
3192 * if no generators are found. */
3193 STRV_FOREACH(path, (char**) paths)
3194 if (access(*path, F_OK) == 0)
3195 found = true;
3196 else if (errno != ENOENT)
3197 log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
3198
3199 return found;
3200}
3201
3202static const char* system_env_generator_binary_paths[] = {
3203 "/run/systemd/system-environment-generators",
3204 "/etc/systemd/system-environment-generators",
3205 "/usr/local/lib/systemd/system-environment-generators",
3206 SYSTEM_ENV_GENERATOR_PATH,
3207 NULL
3208};
3209
3210static const char* user_env_generator_binary_paths[] = {
3211 "/run/systemd/user-environment-generators",
3212 "/etc/systemd/user-environment-generators",
3213 "/usr/local/lib/systemd/user-environment-generators",
3214 USER_ENV_GENERATOR_PATH,
3215 NULL
3216};
3217
3218static int manager_run_environment_generators(Manager *m) {
3219 char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
3220 const char **paths;
3221 void* args[] = {&tmp, &tmp, &m->environment};
3222
e0a3da1f
ZJS
3223 if (m->test_run_flags && !(m->test_run_flags & MANAGER_TEST_RUN_ENV_GENERATORS))
3224 return 0;
3225
64691d20
ZJS
3226 paths = MANAGER_IS_SYSTEM(m) ? system_env_generator_binary_paths : user_env_generator_binary_paths;
3227
3228 if (!generator_path_any(paths))
3229 return 0;
3230
3231 return execute_directories(paths, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL);
3232}
3233
e801700e 3234static int manager_run_generators(Manager *m) {
f42348ac 3235 _cleanup_strv_free_ char **paths = NULL;
07719a21 3236 const char *argv[5];
07719a21 3237 int r;
5a1e9937
LP
3238
3239 assert(m);
3240
e0a3da1f
ZJS
3241 if (m->test_run_flags && !(m->test_run_flags & MANAGER_TEST_RUN_GENERATORS))
3242 return 0;
3243
9183df70 3244 paths = generator_binary_paths(m->unit_file_scope);
e801700e
ZJS
3245 if (!paths)
3246 return log_oom();
5a1e9937 3247
64691d20
ZJS
3248 if (!generator_path_any((const char* const*) paths))
3249 return 0;
5a1e9937 3250
cd64fd56 3251 r = lookup_paths_mkdir_generator(&m->lookup_paths);
07719a21
LP
3252 if (r < 0)
3253 goto finish;
5a1e9937 3254
83cc030f 3255 argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
a3c4eb07
LP
3256 argv[1] = m->lookup_paths.generator;
3257 argv[2] = m->lookup_paths.generator_early;
3258 argv[3] = m->lookup_paths.generator_late;
07719a21 3259 argv[4] = NULL;
5a1e9937 3260
718db961 3261 RUN_WITH_UMASK(0022)
c6e47247
ZJS
3262 execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC,
3263 NULL, NULL, (char**) argv);
5a1e9937 3264
718db961 3265finish:
cd64fd56 3266 lookup_paths_trim_generator(&m->lookup_paths);
e801700e 3267 return r;
5a1e9937
LP
3268}
3269
718db961
LP
3270int manager_environment_add(Manager *m, char **minus, char **plus) {
3271 char **a = NULL, **b = NULL, **l;
97d0e5f8 3272 assert(m);
bcd8e6d1 3273
718db961 3274 l = m->environment;
bcd8e6d1 3275
718db961
LP
3276 if (!strv_isempty(minus)) {
3277 a = strv_env_delete(l, 1, minus);
3278 if (!a)
3279 return -ENOMEM;
3280
3281 l = a;
3282 }
3283
3284 if (!strv_isempty(plus)) {
3285 b = strv_env_merge(2, l, plus);
aa9f8a30
AH
3286 if (!b) {
3287 strv_free(a);
718db961 3288 return -ENOMEM;
aa9f8a30 3289 }
bcd8e6d1 3290
718db961
LP
3291 l = b;
3292 }
3293
3294 if (m->environment != l)
3295 strv_free(m->environment);
3296 if (a != l)
3297 strv_free(a);
3298 if (b != l)
3299 strv_free(b);
3300
f069efb4
LP
3301 m->environment = l;
3302 manager_clean_environment(m);
3303 strv_sort(m->environment);
3304
97d0e5f8
UTL
3305 return 0;
3306}
3307
c93ff2e9
FC
3308int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
3309 int i;
3310
3311 assert(m);
3312
517d56b1 3313 for (i = 0; i < _RLIMIT_MAX; i++) {
d9814c76
EV
3314 m->rlimit[i] = mfree(m->rlimit[i]);
3315
07719a21
LP
3316 if (!default_rlimit[i])
3317 continue;
c93ff2e9 3318
07719a21
LP
3319 m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
3320 if (!m->rlimit[i])
3ce40911 3321 return log_oom();
c93ff2e9
FC
3322 }
3323
3324 return 0;
3325}
3326
4cfa2c99 3327void manager_recheck_journal(Manager *m) {
f1dd0c3f
LP
3328 Unit *u;
3329
3330 assert(m);
3331
463d0d15 3332 if (!MANAGER_IS_SYSTEM(m))
f1dd0c3f
LP
3333 return;
3334
731a676c
LP
3335 u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
3336 if (u && SOCKET(u)->state != SOCKET_RUNNING) {
4cfa2c99 3337 log_close_journal();
731a676c 3338 return;
f1dd0c3f
LP
3339 }
3340
731a676c
LP
3341 u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
3342 if (u && SERVICE(u)->state != SERVICE_RUNNING) {
4cfa2c99 3343 log_close_journal();
731a676c
LP
3344 return;
3345 }
f1dd0c3f 3346
731a676c
LP
3347 /* Hmm, OK, so the socket is fully up and the service is up
3348 * too, then let's make use of the thing. */
f1dd0c3f
LP
3349 log_open();
3350}
3351
d450b6f2 3352void manager_set_show_status(Manager *m, ShowStatus mode) {
27d340c7 3353 assert(m);
d450b6f2 3354 assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY));
27d340c7 3355
463d0d15 3356 if (!MANAGER_IS_SYSTEM(m))
27d340c7
LP
3357 return;
3358
76b6f3f6
ZJS
3359 if (m->show_status != mode)
3360 log_debug("%s showing of status.",
3361 mode == SHOW_STATUS_NO ? "Disabling" : "Enabling");
d450b6f2 3362 m->show_status = mode;
27d340c7 3363
d450b6f2 3364 if (mode > 0)
ac5b0c13 3365 (void) touch("/run/systemd/show-status");
27d340c7 3366 else
ac5b0c13 3367 (void) unlink("/run/systemd/show-status");
27d340c7
LP
3368}
3369
127d5fd1 3370static bool manager_get_show_status(Manager *m, StatusType type) {
27d340c7
LP
3371 assert(m);
3372
463d0d15 3373 if (!MANAGER_IS_SYSTEM(m))
27d340c7
LP
3374 return false;
3375
31a7eb86
ZJS
3376 if (m->no_console_output)
3377 return false;
3378
d81afec1 3379 if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
08510627
LP
3380 return false;
3381
e46b13c8 3382 /* If we cannot find out the status properly, just proceed. */
ebc5788e 3383 if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
e46b13c8
ZJS
3384 return false;
3385
d450b6f2 3386 if (m->show_status > 0)
27d340c7
LP
3387 return true;
3388
031886ed 3389 return false;
27d340c7 3390}
68b29a9f 3391
7d5ceb64
FB
3392const char *manager_get_confirm_spawn(Manager *m) {
3393 static int last_errno = 0;
3394 const char *vc = m->confirm_spawn;
3395 struct stat st;
3396 int r;
3397
3398 /* Here's the deal: we want to test the validity of the console but don't want
3399 * PID1 to go through the whole console process which might block. But we also
3400 * want to warn the user only once if something is wrong with the console so we
3401 * cannot do the sanity checks after spawning our children. So here we simply do
3402 * really basic tests to hopefully trap common errors.
3403 *
3404 * If the console suddenly disappear at the time our children will really it
3405 * then they will simply fail to acquire it and a positive answer will be
3406 * assumed. New children will fallback to /dev/console though.
3407 *
3408 * Note: TTYs are devices that can come and go any time, and frequently aren't
3409 * available yet during early boot (consider a USB rs232 dongle...). If for any
3410 * reason the configured console is not ready, we fallback to the default
3411 * console. */
3412
3413 if (!vc || path_equal(vc, "/dev/console"))
3414 return vc;
3415
3416 r = stat(vc, &st);
3417 if (r < 0)
3418 goto fail;
3419
3420 if (!S_ISCHR(st.st_mode)) {
3421 errno = ENOTTY;
3422 goto fail;
3423 }
3424
3425 last_errno = 0;
3426 return vc;
3427fail:
3428 if (last_errno != errno) {
3429 last_errno = errno;
3430 log_warning_errno(errno, "Failed to open %s: %m, using default console", vc);
3431 }
3432 return "/dev/console";
3433}
3434
e2680723
LP
3435void manager_set_first_boot(Manager *m, bool b) {
3436 assert(m);
3437
463d0d15 3438 if (!MANAGER_IS_SYSTEM(m))
e2680723
LP
3439 return;
3440
ae2a2c53
LP
3441 if (m->first_boot != (int) b) {
3442 if (b)
3443 (void) touch("/run/systemd/first-boot");
3444 else
3445 (void) unlink("/run/systemd/first-boot");
3446 }
e2680723 3447
ae2a2c53 3448 m->first_boot = b;
e2680723
LP
3449}
3450
b0eb2944
FB
3451void manager_disable_confirm_spawn(void) {
3452 (void) touch("/run/systemd/confirm_spawn_disabled");
3453}
3454
3455bool manager_is_confirm_spawn_disabled(Manager *m) {
3456 if (!m->confirm_spawn)
3457 return true;
3458
3459 return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0;
3460}
3461
127d5fd1 3462void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
25cee550
MS
3463 va_list ap;
3464
cb6531be
ZJS
3465 /* If m is NULL, assume we're after shutdown and let the messages through. */
3466
3467 if (m && !manager_get_show_status(m, type))
25cee550
MS
3468 return;
3469
03b717a3
MS
3470 /* XXX We should totally drop the check for ephemeral here
3471 * and thus effectively make 'Type=idle' pointless. */
cb6531be 3472 if (type == STATUS_TYPE_EPHEMERAL && m && m->n_on_console > 0)
03b717a3
MS
3473 return;
3474
25cee550 3475 va_start(ap, format);
127d5fd1 3476 status_vprintf(status, true, type == STATUS_TYPE_EPHEMERAL, format, ap);
25cee550
MS
3477 va_end(ap);
3478}
3479
a57f7e2c
LP
3480Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
3481 char p[strlen(path)+1];
3482
3483 assert(m);
3484 assert(path);
3485
3486 strcpy(p, path);
3487 path_kill_slashes(p);
3488
3489 return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
3490}
e66cf1a3 3491
19bbdd98 3492void manager_set_exec_params(Manager *m, ExecParameters *p) {
f755e3b7 3493 assert(m);
3536f49e
YW
3494 assert(p);
3495
3496 p->environment = m->environment;
3497 p->confirm_spawn = manager_get_confirm_spawn(m);
3498 p->cgroup_supported = m->cgroup_supported;
3499 p->prefix = m->prefix;
e66cf1a3 3500
8679efde 3501 SET_FLAG(p->flags, EXEC_PASS_LOG_UNIT|EXEC_CHOWN_DIRECTORIES, MANAGER_IS_SYSTEM(m));
e66cf1a3 3502}
f755e3b7 3503
5269eb6b 3504int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
03455c28 3505 unsigned size;
5269eb6b 3506 int r;
03455c28
LDM
3507
3508 assert(m);
3509 assert(u->manager == m);
3510
3511 size = set_size(m->failed_units);
3512
9fff8981 3513 if (failed) {
5269eb6b
LP
3514 r = set_ensure_allocated(&m->failed_units, NULL);
3515 if (r < 0)
3516 return log_oom();
3517
9fff8981 3518 if (set_put(m->failed_units, u) < 0)
5269eb6b 3519 return log_oom();
9fff8981 3520 } else
5269eb6b 3521 (void) set_remove(m->failed_units, u);
03455c28
LDM
3522
3523 if (set_size(m->failed_units) != size)
3524 bus_manager_send_change_signal(m);
5269eb6b
LP
3525
3526 return 0;
03455c28
LDM
3527}
3528
f755e3b7
LP
3529ManagerState manager_state(Manager *m) {
3530 Unit *u;
3531
3532 assert(m);
3533
3534 /* Did we ever finish booting? If not then we are still starting up */
49d5666c 3535 if (!MANAGER_IS_FINISHED(m)) {
d81afec1
LP
3536
3537 u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
3538 if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
3539 return MANAGER_INITIALIZING;
3540
f755e3b7 3541 return MANAGER_STARTING;
d81afec1 3542 }
f755e3b7 3543
e68537f0 3544 /* Is the special shutdown target active or queued? If so, we are in shutdown state */
f755e3b7 3545 u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
706424c2 3546 if (u && unit_active_or_pending(u))
f755e3b7
LP
3547 return MANAGER_STOPPING;
3548
45a7b16b
LP
3549 if (MANAGER_IS_SYSTEM(m)) {
3550 /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
3551 u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
3552 if (u && unit_active_or_pending(u))
3553 return MANAGER_MAINTENANCE;
f755e3b7 3554
45a7b16b
LP
3555 u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
3556 if (u && unit_active_or_pending(u))
3557 return MANAGER_MAINTENANCE;
3558 }
f755e3b7
LP
3559
3560 /* Are there any failed units? If so, we are in degraded mode */
3561 if (set_size(m->failed_units) > 0)
3562 return MANAGER_DEGRADED;
3563
3564 return MANAGER_RUNNING;
3565}
3566
00d9ef85
LP
3567#define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
3568
3569static void manager_unref_uid_internal(
3570 Manager *m,
3571 Hashmap **uid_refs,
3572 uid_t uid,
3573 bool destroy_now,
3574 int (*_clean_ipc)(uid_t uid)) {
3575
3576 uint32_t c, n;
3577
3578 assert(m);
3579 assert(uid_refs);
3580 assert(uid_is_valid(uid));
3581 assert(_clean_ipc);
3582
3583 /* A generic implementation, covering both manager_unref_uid() and manager_unref_gid(), under the assumption
3584 * that uid_t and gid_t are actually defined the same way, with the same validity rules.
3585 *
3586 * We store a hashmap where the UID/GID is they key and the value is a 32bit reference counter, whose highest
3587 * bit is used as flag for marking UIDs/GIDs whose IPC objects to remove when the last reference to the UID/GID
3588 * is dropped. The flag is set to on, once at least one reference from a unit where RemoveIPC= is set is added
3589 * on a UID/GID. It is reset when the UID's/GID's reference counter drops to 0 again. */
3590
3591 assert_cc(sizeof(uid_t) == sizeof(gid_t));
3592 assert_cc(UID_INVALID == (uid_t) GID_INVALID);
3593
3594 if (uid == 0) /* We don't keep track of root, and will never destroy it */
3595 return;
3596
3597 c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
3598
3599 n = c & ~DESTROY_IPC_FLAG;
3600 assert(n > 0);
3601 n--;
3602
3603 if (destroy_now && n == 0) {
3604 hashmap_remove(*uid_refs, UID_TO_PTR(uid));
3605
3606 if (c & DESTROY_IPC_FLAG) {
3607 log_debug("%s " UID_FMT " is no longer referenced, cleaning up its IPC.",
3608 _clean_ipc == clean_ipc_by_uid ? "UID" : "GID",
3609 uid);
3610 (void) _clean_ipc(uid);
3611 }
3612 } else {
3613 c = n | (c & DESTROY_IPC_FLAG);
3614 assert_se(hashmap_update(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c)) >= 0);
3615 }
3616}
3617
3618void manager_unref_uid(Manager *m, uid_t uid, bool destroy_now) {
3619 manager_unref_uid_internal(m, &m->uid_refs, uid, destroy_now, clean_ipc_by_uid);
3620}
3621
3622void manager_unref_gid(Manager *m, gid_t gid, bool destroy_now) {
3623 manager_unref_uid_internal(m, &m->gid_refs, (uid_t) gid, destroy_now, clean_ipc_by_gid);
3624}
3625
3626static int manager_ref_uid_internal(
3627 Manager *m,
3628 Hashmap **uid_refs,
3629 uid_t uid,
3630 bool clean_ipc) {
3631
3632 uint32_t c, n;
3633 int r;
3634
3635 assert(m);
3636 assert(uid_refs);
3637 assert(uid_is_valid(uid));
3638
3639 /* A generic implementation, covering both manager_ref_uid() and manager_ref_gid(), under the assumption
3640 * that uid_t and gid_t are actually defined the same way, with the same validity rules. */
3641
3642 assert_cc(sizeof(uid_t) == sizeof(gid_t));
3643 assert_cc(UID_INVALID == (uid_t) GID_INVALID);
3644
3645 if (uid == 0) /* We don't keep track of root, and will never destroy it */
3646 return 0;
3647
3648 r = hashmap_ensure_allocated(uid_refs, &trivial_hash_ops);
3649 if (r < 0)
3650 return r;
3651
3652 c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
3653
3654 n = c & ~DESTROY_IPC_FLAG;
3655 n++;
3656
3657 if (n & DESTROY_IPC_FLAG) /* check for overflow */
3658 return -EOVERFLOW;
3659
3660 c = n | (c & DESTROY_IPC_FLAG) | (clean_ipc ? DESTROY_IPC_FLAG : 0);
3661
3662 return hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
3663}
3664
3665int manager_ref_uid(Manager *m, uid_t uid, bool clean_ipc) {
3666 return manager_ref_uid_internal(m, &m->uid_refs, uid, clean_ipc);
3667}
3668
3669int manager_ref_gid(Manager *m, gid_t gid, bool clean_ipc) {
3670 return manager_ref_uid_internal(m, &m->gid_refs, (uid_t) gid, clean_ipc);
3671}
3672
3673static void manager_vacuum_uid_refs_internal(
3674 Manager *m,
3675 Hashmap **uid_refs,
3676 int (*_clean_ipc)(uid_t uid)) {
3677
3678 Iterator i;
3679 void *p, *k;
3680
3681 assert(m);
3682 assert(uid_refs);
3683 assert(_clean_ipc);
3684
3685 HASHMAP_FOREACH_KEY(p, k, *uid_refs, i) {
3686 uint32_t c, n;
3687 uid_t uid;
3688
3689 uid = PTR_TO_UID(k);
3690 c = PTR_TO_UINT32(p);
3691
3692 n = c & ~DESTROY_IPC_FLAG;
3693 if (n > 0)
3694 continue;
3695
3696 if (c & DESTROY_IPC_FLAG) {
3697 log_debug("Found unreferenced %s " UID_FMT " after reload/reexec. Cleaning up.",
3698 _clean_ipc == clean_ipc_by_uid ? "UID" : "GID",
3699 uid);
3700 (void) _clean_ipc(uid);
3701 }
3702
3703 assert_se(hashmap_remove(*uid_refs, k) == p);
3704 }
3705}
3706
3707void manager_vacuum_uid_refs(Manager *m) {
3708 manager_vacuum_uid_refs_internal(m, &m->uid_refs, clean_ipc_by_uid);
3709}
3710
3711void manager_vacuum_gid_refs(Manager *m) {
3712 manager_vacuum_uid_refs_internal(m, &m->gid_refs, clean_ipc_by_gid);
3713}
3714
3715static void manager_serialize_uid_refs_internal(
3716 Manager *m,
3717 FILE *f,
3718 Hashmap **uid_refs,
3719 const char *field_name) {
3720
3721 Iterator i;
3722 void *p, *k;
3723
3724 assert(m);
3725 assert(f);
3726 assert(uid_refs);
3727 assert(field_name);
3728
3729 /* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as the actual counter
3730 * of it is better rebuild after a reload/reexec. */
3731
3732 HASHMAP_FOREACH_KEY(p, k, *uid_refs, i) {
3733 uint32_t c;
3734 uid_t uid;
3735
3736 uid = PTR_TO_UID(k);
3737 c = PTR_TO_UINT32(p);
3738
3739 if (!(c & DESTROY_IPC_FLAG))
3740 continue;
3741
3742 fprintf(f, "%s=" UID_FMT "\n", field_name, uid);
3743 }
3744}
3745
3746void manager_serialize_uid_refs(Manager *m, FILE *f) {
3747 manager_serialize_uid_refs_internal(m, f, &m->uid_refs, "destroy-ipc-uid");
3748}
3749
3750void manager_serialize_gid_refs(Manager *m, FILE *f) {
3751 manager_serialize_uid_refs_internal(m, f, &m->gid_refs, "destroy-ipc-gid");
3752}
3753
3754static void manager_deserialize_uid_refs_one_internal(
3755 Manager *m,
3756 Hashmap** uid_refs,
3757 const char *value) {
3758
3759 uid_t uid;
3760 uint32_t c;
3761 int r;
3762
3763 assert(m);
3764 assert(uid_refs);
3765 assert(value);
3766
3767 r = parse_uid(value, &uid);
3768 if (r < 0 || uid == 0) {
3769 log_debug("Unable to parse UID reference serialization");
3770 return;
3771 }
3772
3773 r = hashmap_ensure_allocated(uid_refs, &trivial_hash_ops);
3774 if (r < 0) {
3775 log_oom();
3776 return;
3777 }
3778
3779 c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
3780 if (c & DESTROY_IPC_FLAG)
3781 return;
3782
3783 c |= DESTROY_IPC_FLAG;
3784
3785 r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
3786 if (r < 0) {
3787 log_debug("Failed to add UID reference entry");
3788 return;
3789 }
3790}
3791
3792void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
3793 manager_deserialize_uid_refs_one_internal(m, &m->uid_refs, value);
3794}
3795
3796void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
3797 manager_deserialize_uid_refs_one_internal(m, &m->gid_refs, value);
3798}
3799
3800int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
3801 struct buffer {
3802 uid_t uid;
3803 gid_t gid;
3804 char unit_name[UNIT_NAME_MAX+1];
3805 } _packed_ buffer;
3806
3807 Manager *m = userdata;
3808 ssize_t l;
3809 size_t n;
3810 Unit *u;
3811
3812 assert_se(source);
3813 assert_se(m);
3814
3815 /* Invoked whenever a child process succeeded resolving its user/group to use and sent us the resulting UID/GID
3816 * in a datagram. We parse the datagram here and pass it off to the unit, so that it can add a reference to the
3817 * UID/GID so that it can destroy the UID/GID's IPC objects when the reference counter drops to 0. */
3818
3819 l = recv(fd, &buffer, sizeof(buffer), MSG_DONTWAIT);
3820 if (l < 0) {
4c701096 3821 if (IN_SET(errno, EINTR, EAGAIN))
00d9ef85
LP
3822 return 0;
3823
3824 return log_error_errno(errno, "Failed to read from user lookup fd: %m");
3825 }
3826
3827 if ((size_t) l <= offsetof(struct buffer, unit_name)) {
3828 log_warning("Received too short user lookup message, ignoring.");
3829 return 0;
3830 }
3831
3832 if ((size_t) l > offsetof(struct buffer, unit_name) + UNIT_NAME_MAX) {
3833 log_warning("Received too long user lookup message, ignoring.");
3834 return 0;
3835 }
3836
3837 if (!uid_is_valid(buffer.uid) && !gid_is_valid(buffer.gid)) {
3838 log_warning("Got user lookup message with invalid UID/GID pair, ignoring.");
3839 return 0;
3840 }
3841
3842 n = (size_t) l - offsetof(struct buffer, unit_name);
3843 if (memchr(buffer.unit_name, 0, n)) {
3844 log_warning("Received lookup message with embedded NUL character, ignoring.");
3845 return 0;
3846 }
3847
3848 buffer.unit_name[n] = 0;
3849 u = manager_get_unit(m, buffer.unit_name);
3850 if (!u) {
3851 log_debug("Got user lookup message but unit doesn't exist, ignoring.");
3852 return 0;
3853 }
3854
3855 log_unit_debug(u, "User lookup succeeded: uid=" UID_FMT " gid=" GID_FMT, buffer.uid, buffer.gid);
3856
3857 unit_notify_user_lookup(u, buffer.uid, buffer.gid);
3858 return 0;
3859}
3860
f755e3b7 3861static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
d81afec1 3862 [MANAGER_INITIALIZING] = "initializing",
f755e3b7
LP
3863 [MANAGER_STARTING] = "starting",
3864 [MANAGER_RUNNING] = "running",
3865 [MANAGER_DEGRADED] = "degraded",
3866 [MANAGER_MAINTENANCE] = "maintenance",
3867 [MANAGER_STOPPING] = "stopping",
3868};
3869
3870DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
9f9f0342
LP
3871
3872static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
3873 [MANAGER_TIMESTAMP_FIRMWARE] = "firmware",
3874 [MANAGER_TIMESTAMP_LOADER] = "loader",
3875 [MANAGER_TIMESTAMP_KERNEL] = "kernel",
3876 [MANAGER_TIMESTAMP_INITRD] = "initrd",
3877 [MANAGER_TIMESTAMP_USERSPACE] = "userspace",
3878 [MANAGER_TIMESTAMP_FINISH] = "finish",
3879 [MANAGER_TIMESTAMP_SECURITY_START] = "security-start",
3880 [MANAGER_TIMESTAMP_SECURITY_FINISH] = "security-finish",
3881 [MANAGER_TIMESTAMP_GENERATORS_START] = "generators-start",
3882 [MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish",
3883 [MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start",
3884 [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish",
3885};
3886
3887DEFINE_STRING_TABLE_LOOKUP(manager_timestamp, ManagerTimestamp);