]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/manager.c
treewide: use log_*_errno whenever %m is in the format string
[thirdparty/systemd.git] / src / core / manager.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
60918275 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
60918275
LP
22#include <assert.h>
23#include <errno.h>
87d1515d 24#include <string.h>
9152c765 25#include <signal.h>
9152c765
LP
26#include <sys/wait.h>
27#include <unistd.h>
e46b13c8
ZJS
28#include <sys/inotify.h>
29#include <sys/epoll.h>
9152c765 30#include <sys/poll.h>
e1414003
LP
31#include <sys/reboot.h>
32#include <sys/ioctl.h>
33#include <linux/kd.h>
80876c20
LP
34#include <termios.h>
35#include <fcntl.h>
a16e1123
LP
36#include <sys/types.h>
37#include <sys/stat.h>
fe51822e 38#include <dirent.h>
8742514c 39#include <sys/timerfd.h>
830f6caa
LP
40
41#ifdef HAVE_AUDIT
4927fcae 42#include <libaudit.h>
830f6caa 43#endif
60918275 44
718db961
LP
45#include "sd-daemon.h"
46#include "sd-id128.h"
47#include "sd-messages.h"
81527be1 48
60918275 49#include "manager.h"
75778e21 50#include "transaction.h"
60918275
LP
51#include "hashmap.h"
52#include "macro.h"
53#include "strv.h"
16354eff 54#include "log.h"
2a987ee8 55#include "util.h"
49e942b2 56#include "mkdir.h"
ea430986 57#include "ratelimit.h"
e21fea24 58#include "locale-setup.h"
8e274523 59#include "mount-setup.h"
9e2f7c11 60#include "unit-name.h"
1137a57c 61#include "missing.h"
84e3543e 62#include "path-lookup.h"
514f4ef5 63#include "special.h"
d06dacd0 64#include "exit-status.h"
5dc4c17f 65#include "virt.h"
e96d6be7 66#include "watchdog.h"
b59e2465 67#include "cgroup-util.h"
9eb977db 68#include "path-util.h"
c1165f82 69#include "audit-fd.h"
c51d84dc 70#include "boot-timestamps.h"
8b55b8c4 71#include "env-util.h"
718db961
LP
72#include "bus-errors.h"
73#include "bus-error.h"
74#include "bus-util.h"
75#include "dbus.h"
76#include "dbus-unit.h"
77#include "dbus-job.h"
78#include "dbus-manager.h"
e3dd987c 79#include "bus-kernel.h"
e4746b57 80#include "time-util.h"
60918275 81
03b717a3 82/* Initial delay and the interval for printing status messages about running jobs */
fd08a840
ZJS
83#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
84#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
03b717a3
MS
85#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
86
718db961
LP
87static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
88static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
89static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
90static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
91static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
752b5905 92static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
718db961 93
03b717a3 94static int manager_watch_jobs_in_progress(Manager *m) {
e5723c89
ZJS
95 usec_t next;
96
718db961 97 assert(m);
03b717a3 98
718db961 99 if (m->jobs_in_progress_event_source)
03b717a3
MS
100 return 0;
101
e5723c89 102 next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
6a0f1f6d
LP
103 return sd_event_add_time(
104 m->event,
105 &m->jobs_in_progress_event_source,
106 CLOCK_MONOTONIC,
107 next, 0,
108 manager_dispatch_jobs_in_progress, m);
03b717a3
MS
109}
110
718db961 111#define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
03b717a3 112
03b717a3
MS
113static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
114 char *p = buffer;
115
116 assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
117 assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
118
119 if (pos > 1) {
6282c859
MS
120 if (pos > 2)
121 p = mempset(p, ' ', pos-2);
5052495b 122 p = stpcpy(p, ANSI_RED_ON);
03b717a3
MS
123 *p++ = '*';
124 }
125
126 if (pos > 0 && pos <= width) {
5052495b 127 p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON);
03b717a3
MS
128 *p++ = '*';
129 }
130
5052495b 131 p = stpcpy(p, ANSI_HIGHLIGHT_OFF);
03b717a3
MS
132
133 if (pos < width) {
5052495b 134 p = stpcpy(p, ANSI_RED_ON);
03b717a3 135 *p++ = '*';
6282c859
MS
136 if (pos < width-1)
137 p = mempset(p, ' ', width-1-pos);
51d122af 138 strcpy(p, ANSI_HIGHLIGHT_OFF);
03b717a3 139 }
03b717a3
MS
140}
141
cb8ccb22 142void manager_flip_auto_status(Manager *m, bool enable) {
f755e3b7
LP
143 assert(m);
144
cb8ccb22
ZJS
145 if (enable) {
146 if (m->show_status == SHOW_STATUS_AUTO)
147 manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
148 } else {
149 if (m->show_status == SHOW_STATUS_TEMPORARY)
150 manager_set_show_status(m, SHOW_STATUS_AUTO);
151 }
152}
153
03b717a3 154static void manager_print_jobs_in_progress(Manager *m) {
718db961 155 _cleanup_free_ char *job_of_n = NULL;
03b717a3
MS
156 Iterator i;
157 Job *j;
03b717a3
MS
158 unsigned counter = 0, print_nr;
159 char cylon[6 + CYLON_BUFFER_EXTRA + 1];
160 unsigned cylon_pos;
8bb310c3
ZJS
161 char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
162 uint64_t x;
03b717a3 163
718db961
LP
164 assert(m);
165
cb8ccb22 166 manager_flip_auto_status(m, true);
d450b6f2 167
03b717a3
MS
168 print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
169
170 HASHMAP_FOREACH(j, m->jobs, i)
171 if (j->state == JOB_RUNNING && counter++ == print_nr)
172 break;
173
e970a72e
MS
174 /* m->n_running_jobs must be consistent with the contents of m->jobs,
175 * so the above loop must have succeeded in finding j. */
176 assert(counter == print_nr + 1);
51d122af 177 assert(j);
5a82a91a 178
03b717a3
MS
179 cylon_pos = m->jobs_in_progress_iteration % 14;
180 if (cylon_pos >= 8)
181 cylon_pos = 14 - cylon_pos;
182 draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
183
8bb310c3
ZJS
184 m->jobs_in_progress_iteration++;
185
03b717a3
MS
186 if (m->n_running_jobs > 1)
187 if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
188 job_of_n = NULL;
189
8bb310c3
ZJS
190 format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
191 if (job_get_timeout(j, &x) > 0)
192 format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
193
127d5fd1 194 manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
8bb310c3
ZJS
195 "%sA %s job is running for %s (%s / %s)",
196 strempty(job_of_n),
197 job_type_to_string(j->type),
198 unit_description(j->unit),
199 time, limit);
03b717a3 200
03b717a3
MS
201}
202
e46b13c8
ZJS
203static int have_ask_password(void) {
204 _cleanup_closedir_ DIR *dir;
205
206 dir = opendir("/run/systemd/ask-password");
207 if (!dir) {
208 if (errno == ENOENT)
209 return false;
210 else
211 return -errno;
212 }
213
214 for (;;) {
215 struct dirent *de;
216
217 errno = 0;
218 de = readdir(dir);
219 if (!de && errno != 0)
220 return -errno;
221 if (!de)
222 return false;
223
224 if (startswith(de->d_name, "ask."))
225 return true;
226 }
227}
228
229static int manager_dispatch_ask_password_fd(sd_event_source *source,
230 int fd, uint32_t revents, void *userdata) {
231 Manager *m = userdata;
232
233 assert(m);
234
235 flush_fd(fd);
236
237 m->have_ask_password = have_ask_password();
238 if (m->have_ask_password < 0)
239 /* Log error but continue. Negative have_ask_password
240 * is treated as unknown status. */
c33b3297 241 log_error_errno(m->have_ask_password, "Failed to list /run/systemd/ask-password: %m");
e46b13c8
ZJS
242
243 return 0;
244}
245
246static void manager_close_ask_password(Manager *m) {
247 assert(m);
248
249 m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
250 m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
251 m->have_ask_password = -EINVAL;
252}
253
254static int manager_check_ask_password(Manager *m) {
255 int r;
256
257 assert(m);
258
259 if (!m->ask_password_event_source) {
260 assert(m->ask_password_inotify_fd < 0);
261
262 mkdir_p_label("/run/systemd/ask-password", 0755);
263
264 m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
265 if (m->ask_password_inotify_fd < 0) {
56f64d95 266 log_error_errno(errno, "inotify_init1() failed: %m");
e46b13c8
ZJS
267 return -errno;
268 }
269
270 if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
56f64d95 271 log_error_errno(errno, "Failed to add watch on /run/systemd/ask-password: %m");
e46b13c8
ZJS
272 manager_close_ask_password(m);
273 return -errno;
274 }
275
276 r = sd_event_add_io(m->event, &m->ask_password_event_source,
277 m->ask_password_inotify_fd, EPOLLIN,
278 manager_dispatch_ask_password_fd, m);
279 if (r < 0) {
56f64d95 280 log_error_errno(errno, "Failed to add event source for /run/systemd/ask-password: %m");
e46b13c8
ZJS
281 manager_close_ask_password(m);
282 return -errno;
283 }
284
285 /* Queries might have been added meanwhile... */
286 manager_dispatch_ask_password_fd(m->ask_password_event_source,
287 m->ask_password_inotify_fd, EPOLLIN, m);
288 }
289
290 return m->have_ask_password;
291}
292
31a7eb86 293static int manager_watch_idle_pipe(Manager *m) {
31a7eb86
ZJS
294 int r;
295
718db961
LP
296 assert(m);
297
298 if (m->idle_pipe_event_source)
31a7eb86
ZJS
299 return 0;
300
301 if (m->idle_pipe[2] < 0)
302 return 0;
303
151b9b96 304 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
305 if (r < 0)
306 return log_error_errno(r, "Failed to watch idle pipe: %m");
31a7eb86 307
31a7eb86 308 return 0;
31a7eb86
ZJS
309}
310
718db961
LP
311static void manager_close_idle_pipe(Manager *m) {
312 assert(m);
31a7eb86 313
3d94f76c
LP
314 safe_close_pair(m->idle_pipe);
315 safe_close_pair(m->idle_pipe + 2);
31a7eb86
ZJS
316}
317
8742514c 318static int manager_setup_time_change(Manager *m) {
718db961 319 int r;
b92bea5d
ZJS
320
321 /* We only care for the cancellation event, hence we set the
322 * timeout to the latest possible value. */
323 struct itimerspec its = {
324 .it_value.tv_sec = TIME_T_MAX,
325 };
8742514c 326
718db961
LP
327 assert(m);
328 assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
8742514c 329
0d8c31ff
ZJS
330 if (m->test_run)
331 return 0;
332
8742514c
LP
333 /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
334 * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
335
718db961
LP
336 m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
337 if (m->time_change_fd < 0) {
56f64d95 338 log_error_errno(errno, "Failed to create timerfd: %m");
8742514c
LP
339 return -errno;
340 }
341
718db961 342 if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
56f64d95 343 log_debug_errno(errno, "Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
03e334a1 344 m->time_change_fd = safe_close(m->time_change_fd);
8742514c
LP
345 return 0;
346 }
347
151b9b96 348 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
349 if (r < 0)
350 return log_error_errno(r, "Failed to create time change event source: %m");
8742514c
LP
351
352 log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
353
354 return 0;
355}
356
80876c20 357static int enable_special_signals(Manager *m) {
718db961 358 _cleanup_close_ int fd = -1;
80876c20
LP
359
360 assert(m);
361
a41b539e 362 /* Enable that we get SIGINT on control-alt-del. In containers
c9999773
LP
363 * this will fail with EPERM (older) or EINVAL (newer), so
364 * ignore that. */
365 if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
56f64d95 366 log_warning_errno(errno, "Failed to enable ctrl-alt-del handling: %m");
80876c20 367
a41b539e
LP
368 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
369 if (fd < 0) {
370 /* Support systems without virtual console */
371 if (fd != -ENOENT)
56f64d95 372 log_warning_errno(errno, "Failed to open /dev/tty0: %m");
a41b539e 373 } else {
80876c20
LP
374 /* Enable that we get SIGWINCH on kbrequest */
375 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
56f64d95 376 log_warning_errno(errno, "Failed to enable kbrequest handling: %m");
80876c20
LP
377 }
378
379 return 0;
380}
381
ce578209 382static int manager_setup_signals(Manager *m) {
b92bea5d
ZJS
383 struct sigaction sa = {
384 .sa_handler = SIG_DFL,
385 .sa_flags = SA_NOCLDSTOP|SA_RESTART,
386 };
718db961
LP
387 sigset_t mask;
388 int r;
60918275 389
ce578209
LP
390 assert(m);
391
57c0c30e
LP
392 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
393
4dffec14
LP
394 /* We make liberal use of realtime signals here. On
395 * Linux/glibc we have 30 of them (with the exception of Linux
396 * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
397 * (aka SIGRTMAX). */
7d793605 398
4dffec14 399 assert_se(sigemptyset(&mask) == 0);
7d793605
LP
400 sigset_add_many(&mask,
401 SIGCHLD, /* Child died */
402 SIGTERM, /* Reexecute daemon */
403 SIGHUP, /* Reload configuration */
404 SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
405 SIGUSR2, /* systemd: dump status */
406 SIGINT, /* Kernel sends us this on control-alt-del */
407 SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
408 SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
4dffec14 409
7d793605 410 SIGRTMIN+0, /* systemd: start default.target */
0003d1ab 411 SIGRTMIN+1, /* systemd: isolate rescue.target */
7d793605
LP
412 SIGRTMIN+2, /* systemd: isolate emergency.target */
413 SIGRTMIN+3, /* systemd: start halt.target */
414 SIGRTMIN+4, /* systemd: start poweroff.target */
415 SIGRTMIN+5, /* systemd: start reboot.target */
0003d1ab 416 SIGRTMIN+6, /* systemd: start kexec.target */
4dffec14
LP
417
418 /* ... space for more special targets ... */
419
0003d1ab
LP
420 SIGRTMIN+13, /* systemd: Immediate halt */
421 SIGRTMIN+14, /* systemd: Immediate poweroff */
422 SIGRTMIN+15, /* systemd: Immediate reboot */
423 SIGRTMIN+16, /* systemd: Immediate kexec */
4dffec14
LP
424
425 /* ... space for more immediate system state changes ... */
426
0658666b
LP
427 SIGRTMIN+20, /* systemd: enable status messages */
428 SIGRTMIN+21, /* systemd: disable status messages */
253ee27a
LP
429 SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
430 SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
600b704e 431 SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
4dffec14
LP
432
433 /* .. one free signal here ... */
434
435#if !defined(__hppa64__) && !defined(__hppa__)
436 /* Apparently Linux on hppa has fewer RT
437 * signals (SIGRTMAX is SIGRTMIN+25 there),
438 * hence let's not try to make use of them
439 * here. Since these commands are accessible
440 * by different means and only really a safety
441 * net, the missing functionality on hppa
442 * shouldn't matter. */
443
4cfa2c99 444 SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
253ee27a
LP
445 SIGRTMIN+27, /* systemd: set log target to console */
446 SIGRTMIN+28, /* systemd: set log target to kmsg */
c1dc6153 447 SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete)*/
4dffec14
LP
448
449 /* ... one free signal here SIGRTMIN+30 ... */
450#endif
7d793605 451 -1);
ce578209
LP
452 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
453
718db961
LP
454 m->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
455 if (m->signal_fd < 0)
ce578209
LP
456 return -errno;
457
151b9b96 458 r = sd_event_add_io(m->event, &m->signal_event_source, m->signal_fd, EPOLLIN, manager_dispatch_signal_fd, m);
718db961
LP
459 if (r < 0)
460 return r;
ce578209 461
fa28bc2d 462 /* Process signals a bit earlier than the rest of things, but
46849c3f 463 * later than notify_fd processing, so that the notify
fa28bc2d
LP
464 * processing can still figure out to which process/service a
465 * message belongs, before we reap the process. */
29083707
LP
466 r = sd_event_source_set_priority(m->signal_event_source, -5);
467 if (r < 0)
468 return r;
469
67445f4e 470 if (m->running_as == SYSTEMD_SYSTEM)
80876c20 471 return enable_special_signals(m);
e1414003 472
ce578209
LP
473 return 0;
474}
475
f069efb4
LP
476static void manager_clean_environment(Manager *m) {
477 assert(m);
478
479 /* Let's remove some environment variables that we
480 * need ourselves to communicate with our clients */
481 strv_env_unset_many(
482 m->environment,
483 "NOTIFY_SOCKET",
484 "MAINPID",
485 "MANAGERPID",
486 "LISTEN_PID",
487 "LISTEN_FDS",
488 "WATCHDOG_PID",
489 "WATCHDOG_USEC",
490 NULL);
491}
492
e21fea24 493static int manager_default_environment(Manager *m) {
71ecc858
LP
494 assert(m);
495
e21fea24
KS
496 if (m->running_as == SYSTEMD_SYSTEM) {
497 /* The system manager always starts with a clean
498 * environment for its children. It does not import
499 * the kernel or the parents exported variables.
500 *
501 * The initial passed environ is untouched to keep
502 * /proc/self/environ valid; it is used for tagging
503 * the init process inside containers. */
43638332
ZJS
504 m->environment = strv_new("PATH=" DEFAULT_PATH,
505 NULL);
e21fea24
KS
506
507 /* Import locale variables LC_*= from configuration */
508 locale_setup(&m->environment);
43d03a83 509 } else {
e21fea24
KS
510 /* The user manager passes its own environment
511 * along to its children. */
512 m->environment = strv_copy(environ);
43d03a83
LP
513 }
514
e21fea24
KS
515 if (!m->environment)
516 return -ENOMEM;
8b55b8c4 517
f069efb4 518 manager_clean_environment(m);
9d5a3757
LP
519 strv_sort(m->environment);
520
e21fea24 521 return 0;
71ecc858
LP
522}
523
0d8c31ff 524int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
ce578209 525 Manager *m;
e3dd987c 526 int r;
8e274523
LP
527
528 assert(_m);
a5dab5ce 529 assert(running_as >= 0);
67445f4e 530 assert(running_as < _SYSTEMD_RUNNING_AS_MAX);
ce578209 531
915b3753
LP
532 m = new0(Manager, 1);
533 if (!m)
8e274523 534 return -ENOMEM;
60918275 535
4f8d551f 536#ifdef ENABLE_EFI
530a9662 537 if (running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0)
c51d84dc 538 boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
4f8d551f
ZC
539#endif
540
a5dab5ce 541 m->running_as = running_as;
a16e1123 542 m->exit_code = _MANAGER_EXIT_CODE_INVALID;
bd8f585b 543 m->default_timer_accuracy_usec = USEC_PER_MINUTE;
80876c20 544
718db961 545 m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
8742514c 546
e3dd987c 547 m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = -1;
ea430986 548 m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
9152c765 549
e46b13c8
ZJS
550 m->ask_password_inotify_fd = -1;
551 m->have_ask_password = -EINVAL; /* we don't know */
552
0d8c31ff
ZJS
553 m->test_run = test_run;
554
e21fea24
KS
555 r = manager_default_environment(m);
556 if (r < 0)
1137a57c
LP
557 goto fail;
558
d5099efc 559 r = hashmap_ensure_allocated(&m->units, &string_hash_ops);
718db961 560 if (r < 0)
60918275
LP
561 goto fail;
562
d5099efc 563 r = hashmap_ensure_allocated(&m->jobs, NULL);
718db961 564 if (r < 0)
60918275
LP
565 goto fail;
566
d5099efc 567 r = hashmap_ensure_allocated(&m->cgroup_unit, &string_hash_ops);
718db961 568 if (r < 0)
9152c765
LP
569 goto fail;
570
d5099efc 571 r = hashmap_ensure_allocated(&m->watch_bus, &string_hash_ops);
718db961 572 if (r < 0)
05e343b7
LP
573 goto fail;
574
d5099efc 575 r = set_ensure_allocated(&m->startup_units, NULL);
95ae05c0
WC
576 if (r < 0)
577 goto fail;
578
d5099efc 579 r = set_ensure_allocated(&m->failed_units, NULL);
f755e3b7
LP
580 if (r < 0)
581 goto fail;
582
718db961
LP
583 r = sd_event_default(&m->event);
584 if (r < 0)
8742514c
LP
585 goto fail;
586
151b9b96 587 r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
752b5905
LP
588 if (r < 0)
589 goto fail;
590
591 r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
592 if (r < 0)
593 goto fail;
594
595 r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
596 if (r < 0)
597 goto fail;
598
8742514c
LP
599 r = manager_setup_signals(m);
600 if (r < 0)
9152c765
LP
601 goto fail;
602
8742514c
LP
603 r = manager_setup_cgroup(m);
604 if (r < 0)
8e274523
LP
605 goto fail;
606
8742514c
LP
607 r = manager_setup_time_change(m);
608 if (r < 0)
8c47c732
LP
609 goto fail;
610
9670d583
LP
611 m->udev = udev_new();
612 if (!m->udev) {
613 r = -ENOMEM;
614 goto fail;
615 }
616
d86f9d52
LP
617 /* Note that we set up neither kdbus, nor the notify fd
618 * here. We do that after deserialization, since they might
619 * have gotten serialized across the reexec. */
620
72bc8d00
LP
621 m->taint_usr = dir_is_empty("/usr") > 0;
622
8e274523
LP
623 *_m = m;
624 return 0;
60918275
LP
625
626fail:
627 manager_free(m);
8e274523 628 return r;
60918275
LP
629}
630
d86f9d52 631static int manager_setup_notify(Manager *m) {
7181dbdb 632 int r;
d86f9d52 633
0d8c31ff
ZJS
634 if (m->test_run)
635 return 0;
636
d86f9d52
LP
637 if (m->notify_fd < 0) {
638 _cleanup_close_ int fd = -1;
55836941 639 union sockaddr_union sa = {
7181dbdb
LP
640 .sa.sa_family = AF_UNIX,
641 };
55836941 642 static const int one = 1;
d86f9d52
LP
643
644 /* First free all secondary fields */
645 free(m->notify_socket);
646 m->notify_socket = NULL;
647 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
648
649 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
650 if (fd < 0) {
56f64d95 651 log_error_errno(errno, "Failed to allocate notification socket: %m");
d86f9d52
LP
652 return -errno;
653 }
654
498e87d6 655 if (m->running_as == SYSTEMD_SYSTEM)
7181dbdb 656 m->notify_socket = strdup("/run/systemd/notify");
498e87d6 657 else {
7181dbdb 658 const char *e;
d86f9d52 659
7181dbdb
LP
660 e = getenv("XDG_RUNTIME_DIR");
661 if (!e) {
56f64d95 662 log_error_errno(errno, "XDG_RUNTIME_DIR is not set: %m");
7181dbdb
LP
663 return -EINVAL;
664 }
665
666 m->notify_socket = strappend(e, "/systemd/notify");
667 }
498e87d6
LP
668 if (!m->notify_socket)
669 return log_oom();
670
671 (void) mkdir_parents_label(m->notify_socket, 0755);
f0e62e89 672 (void) unlink(m->notify_socket);
7181dbdb
LP
673
674 strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
675 r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
d86f9d52 676 if (r < 0) {
56f64d95 677 log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
f0e62e89 678 return -errno;
d86f9d52
LP
679 }
680
681 r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
682 if (r < 0) {
56f64d95 683 log_error_errno(errno, "SO_PASSCRED failed: %m");
d86f9d52
LP
684 return -errno;
685 }
686
d86f9d52
LP
687 m->notify_fd = fd;
688 fd = -1;
689
690 log_debug("Using notification socket %s", m->notify_socket);
691 }
692
693 if (!m->notify_event_source) {
151b9b96 694 r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_dispatch_notify_fd, m);
895b3a7b
MS
695 if (r < 0)
696 return log_error_errno(r, "Failed to allocate notify event source: %m");
d86f9d52
LP
697
698 /* Process signals a bit earlier than SIGCHLD, so that we can
699 * still identify to which service an exit message belongs */
700 r = sd_event_source_set_priority(m->notify_event_source, -7);
23bbb0de
MS
701 if (r < 0)
702 return log_error_errno(r, "Failed to set priority of notify event source: %m");
d86f9d52
LP
703 }
704
705 return 0;
706}
707
708static int manager_setup_kdbus(Manager *m) {
5bf348d7 709#ifdef ENABLE_KDBUS
d86f9d52
LP
710 _cleanup_free_ char *p = NULL;
711
712 assert(m);
713
0d8c31ff 714 if (m->test_run || m->kdbus_fd >= 0)
d86f9d52
LP
715 return 0;
716
387eba00
LP
717 if (getpid() == 1)
718 bus_kernel_fix_attach_mask();
1a299299
LP
719
720 m->kdbus_fd = bus_kernel_create_bus(
721 m->running_as == SYSTEMD_SYSTEM ? "system" : "user",
722 m->running_as == SYSTEMD_SYSTEM, &p);
723
eb56eb9b
MS
724 if (m->kdbus_fd < 0)
725 return log_debug_errno(m->kdbus_fd, "Failed to set up kdbus: %m");
d86f9d52
LP
726
727 log_debug("Successfully set up kdbus on %s", p);
d86f9d52
LP
728#endif
729
730 return 0;
731}
732
733static int manager_connect_bus(Manager *m, bool reexecuting) {
734 bool try_bus_connect;
735
736 assert(m);
737
0d8c31ff
ZJS
738 if (m->test_run)
739 return 0;
740
d86f9d52
LP
741 try_bus_connect =
742 m->kdbus_fd >= 0 ||
743 reexecuting ||
744 (m->running_as == SYSTEMD_USER && getenv("DBUS_SESSION_BUS_ADDRESS"));
745
746 /* Try to connect to the busses, if possible. */
747 return bus_init(m, try_bus_connect);
748}
749
23a177ef 750static unsigned manager_dispatch_cleanup_queue(Manager *m) {
595ed347 751 Unit *u;
23a177ef
LP
752 unsigned n = 0;
753
754 assert(m);
755
595ed347
MS
756 while ((u = m->cleanup_queue)) {
757 assert(u->in_cleanup_queue);
23a177ef 758
595ed347 759 unit_free(u);
23a177ef
LP
760 n++;
761 }
762
763 return n;
764}
765
eced69b3 766enum {
35b8ca3a 767 GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
eced69b3
LP
768 GC_OFFSET_UNSURE, /* No clue */
769 GC_OFFSET_GOOD, /* We still need this unit */
770 GC_OFFSET_BAD, /* We don't need this unit anymore */
771 _GC_OFFSET_MAX
772};
773
774static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
701cc384
LP
775 Iterator i;
776 Unit *other;
eced69b3 777 bool is_bad;
701cc384
LP
778
779 assert(u);
780
ac155bb8
MS
781 if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
782 u->gc_marker == gc_marker + GC_OFFSET_BAD ||
783 u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
701cc384
LP
784 return;
785
ac155bb8 786 if (u->in_cleanup_queue)
701cc384
LP
787 goto bad;
788
789 if (unit_check_gc(u))
790 goto good;
791
ac155bb8 792 u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
eced69b3
LP
793
794 is_bad = true;
795
ac155bb8 796 SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
701cc384
LP
797 unit_gc_sweep(other, gc_marker);
798
ac155bb8 799 if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
701cc384 800 goto good;
eced69b3 801
ac155bb8 802 if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
eced69b3 803 is_bad = false;
701cc384
LP
804 }
805
eced69b3
LP
806 if (is_bad)
807 goto bad;
808
809 /* We were unable to find anything out about this entry, so
810 * let's investigate it later */
ac155bb8 811 u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
eced69b3
LP
812 unit_add_to_gc_queue(u);
813 return;
814
701cc384 815bad:
eced69b3
LP
816 /* We definitely know that this one is not useful anymore, so
817 * let's mark it for deletion */
ac155bb8 818 u->gc_marker = gc_marker + GC_OFFSET_BAD;
eced69b3 819 unit_add_to_cleanup_queue(u);
701cc384
LP
820 return;
821
822good:
ac155bb8 823 u->gc_marker = gc_marker + GC_OFFSET_GOOD;
701cc384
LP
824}
825
826static unsigned manager_dispatch_gc_queue(Manager *m) {
595ed347 827 Unit *u;
701cc384 828 unsigned n = 0;
eced69b3 829 unsigned gc_marker;
701cc384
LP
830
831 assert(m);
832
cf1265e1 833 /* log_debug("Running GC..."); */
701cc384 834
eced69b3
LP
835 m->gc_marker += _GC_OFFSET_MAX;
836 if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
c9c0cadb 837 m->gc_marker = 1;
701cc384 838
eced69b3
LP
839 gc_marker = m->gc_marker;
840
595ed347
MS
841 while ((u = m->gc_queue)) {
842 assert(u->in_gc_queue);
701cc384 843
595ed347 844 unit_gc_sweep(u, gc_marker);
eced69b3 845
71fda00f 846 LIST_REMOVE(gc_queue, m->gc_queue, u);
595ed347 847 u->in_gc_queue = false;
701cc384
LP
848
849 n++;
850
595ed347
MS
851 if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
852 u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
79008bdd 853 log_unit_debug(u->id, "Collecting %s", u->id);
595ed347
MS
854 u->gc_marker = gc_marker + GC_OFFSET_BAD;
855 unit_add_to_cleanup_queue(u);
701cc384
LP
856 }
857 }
858
859 m->n_in_gc_queue = 0;
701cc384
LP
860
861 return n;
862}
863
a16e1123 864static void manager_clear_jobs_and_units(Manager *m) {
a16e1123 865 Unit *u;
60918275
LP
866
867 assert(m);
868
87f0e418
LP
869 while ((u = hashmap_first(m->units)))
870 unit_free(u);
964e0949
LP
871
872 manager_dispatch_cleanup_queue(m);
873
874 assert(!m->load_queue);
875 assert(!m->run_queue);
876 assert(!m->dbus_unit_queue);
877 assert(!m->dbus_job_queue);
878 assert(!m->cleanup_queue);
879 assert(!m->gc_queue);
880
964e0949
LP
881 assert(hashmap_isempty(m->jobs));
882 assert(hashmap_isempty(m->units));
9e9e2b72
MS
883
884 m->n_on_console = 0;
885 m->n_running_jobs = 0;
a16e1123
LP
886}
887
06d8d842 888Manager* manager_free(Manager *m) {
a16e1123 889 UnitType c;
c93ff2e9 890 int i;
87f0e418 891
06d8d842
ZJS
892 if (!m)
893 return NULL;
a16e1123
LP
894
895 manager_clear_jobs_and_units(m);
23a177ef 896
7824bbeb
LP
897 for (c = 0; c < _UNIT_TYPE_MAX; c++)
898 if (unit_vtable[c]->shutdown)
899 unit_vtable[c]->shutdown(m);
900
a16e1123
LP
901 /* If we reexecute ourselves, we keep the root cgroup
902 * around */
c6c18be3 903 manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
8e274523 904
5a1e9937
LP
905 manager_undo_generators(m);
906
5e8d1c9a 907 bus_done(m);
ea430986 908
87f0e418 909 hashmap_free(m->units);
60918275 910 hashmap_free(m->jobs);
5ba6985b
LP
911 hashmap_free(m->watch_pids1);
912 hashmap_free(m->watch_pids2);
05e343b7 913 hashmap_free(m->watch_bus);
9152c765 914
95ae05c0 915 set_free(m->startup_units);
f755e3b7
LP
916 set_free(m->failed_units);
917
718db961
LP
918 sd_event_source_unref(m->signal_event_source);
919 sd_event_source_unref(m->notify_event_source);
920 sd_event_source_unref(m->time_change_event_source);
921 sd_event_source_unref(m->jobs_in_progress_event_source);
922 sd_event_source_unref(m->idle_pipe_event_source);
752b5905 923 sd_event_source_unref(m->run_queue_event_source);
718db961 924
03e334a1
LP
925 safe_close(m->signal_fd);
926 safe_close(m->notify_fd);
927 safe_close(m->time_change_fd);
928 safe_close(m->kdbus_fd);
718db961 929
e46b13c8
ZJS
930 manager_close_ask_password(m);
931
718db961
LP
932 manager_close_idle_pipe(m);
933
9670d583 934 udev_unref(m->udev);
718db961 935 sd_event_unref(m->event);
60918275 936
c952c6ec
LP
937 free(m->notify_socket);
938
84e3543e 939 lookup_paths_free(&m->lookup_paths);
1137a57c 940 strv_free(m->environment);
036643a2 941
4ad49000 942 hashmap_free(m->cgroup_unit);
c6c18be3 943 set_free_free(m->unit_path_cache);
33be102a 944
664f88a7
LP
945 free(m->switch_root);
946 free(m->switch_root_init);
947
517d56b1 948 for (i = 0; i < _RLIMIT_MAX; i++)
c93ff2e9
FC
949 free(m->rlimit[i]);
950
a57f7e2c
LP
951 assert(hashmap_isempty(m->units_requiring_mounts_for));
952 hashmap_free(m->units_requiring_mounts_for);
953
60918275 954 free(m);
06d8d842 955 return NULL;
60918275
LP
956}
957
a16e1123
LP
958int manager_enumerate(Manager *m) {
959 int r = 0, q;
f50e0a01 960 UnitType c;
f50e0a01
LP
961
962 assert(m);
963
a16e1123
LP
964 /* Let's ask every type to load all units from disk/kernel
965 * that it might know */
f50e0a01 966 for (c = 0; c < _UNIT_TYPE_MAX; c++)
a57f7e2c
LP
967 if (unit_vtable[c]->enumerate) {
968 q = unit_vtable[c]->enumerate(m);
969 if (q < 0)
a16e1123 970 r = q;
a57f7e2c 971 }
f50e0a01
LP
972
973 manager_dispatch_load_queue(m);
a16e1123
LP
974 return r;
975}
976
9588bc32 977static int manager_coldplug(Manager *m) {
8f8f05a9 978 int r = 0;
a16e1123
LP
979 Iterator i;
980 Unit *u;
981 char *k;
982
983 assert(m);
f50e0a01
LP
984
985 /* Then, let's set up their initial state. */
986 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
8f8f05a9 987 int q;
f50e0a01
LP
988
989 /* ignore aliases */
ac155bb8 990 if (u->id != k)
f50e0a01
LP
991 continue;
992
8f8f05a9
LP
993 q = unit_coldplug(u);
994 if (q < 0)
cca098b0 995 r = q;
f50e0a01
LP
996 }
997
a16e1123
LP
998 return r;
999}
1000
fe51822e
LP
1001static void manager_build_unit_path_cache(Manager *m) {
1002 char **i;
807d0cca 1003 _cleanup_closedir_ DIR *d = NULL;
fe51822e
LP
1004 int r;
1005
1006 assert(m);
1007
1008 set_free_free(m->unit_path_cache);
1009
d5099efc 1010 m->unit_path_cache = set_new(&string_hash_ops);
874310b7 1011 if (!m->unit_path_cache) {
fe51822e
LP
1012 log_error("Failed to allocate unit path cache.");
1013 return;
1014 }
1015
1016 /* This simply builds a list of files we know exist, so that
1017 * we don't always have to go to disk */
1018
1019 STRV_FOREACH(i, m->lookup_paths.unit_path) {
1020 struct dirent *de;
1021
bd0af849
ZJS
1022 d = opendir(*i);
1023 if (!d) {
874310b7 1024 if (errno != ENOENT)
56f64d95 1025 log_error_errno(errno, "Failed to open directory %s: %m", *i);
fe51822e
LP
1026 continue;
1027 }
1028
1029 while ((de = readdir(d))) {
1030 char *p;
1031
1032 if (ignore_file(de->d_name))
1033 continue;
1034
b7def684 1035 p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
44d91056 1036 if (!p) {
fe51822e
LP
1037 r = -ENOMEM;
1038 goto fail;
1039 }
1040
ef42202a
ZJS
1041 r = set_consume(m->unit_path_cache, p);
1042 if (r < 0)
fe51822e 1043 goto fail;
fe51822e
LP
1044 }
1045
1046 closedir(d);
1047 d = NULL;
1048 }
1049
1050 return;
1051
1052fail:
da927ba9 1053 log_error_errno(r, "Failed to build unit path cache: %m");
fe51822e
LP
1054
1055 set_free_free(m->unit_path_cache);
1056 m->unit_path_cache = NULL;
fe51822e
LP
1057}
1058
9588bc32
LP
1059
1060static int manager_distribute_fds(Manager *m, FDSet *fds) {
1061 Unit *u;
1062 Iterator i;
1063 int r;
1064
1065 assert(m);
1066
1067 HASHMAP_FOREACH(u, m->units, i) {
1068
1069 if (fdset_size(fds) <= 0)
1070 break;
1071
1072 if (UNIT_VTABLE(u)->distribute_fds) {
1073 r = UNIT_VTABLE(u)->distribute_fds(u, fds);
1074 if (r < 0)
1075 return r;
1076 }
1077 }
1078
1079 return 0;
1080}
1081
a16e1123
LP
1082int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
1083 int r, q;
1084
1085 assert(m);
1086
518d10e9 1087 dual_timestamp_get(&m->generators_start_timestamp);
5a1e9937 1088 manager_run_generators(m);
518d10e9 1089 dual_timestamp_get(&m->generators_finish_timestamp);
5a1e9937 1090
07719a21
LP
1091 r = lookup_paths_init(
1092 &m->lookup_paths, m->running_as, true,
12ed81d9 1093 NULL,
07719a21
LP
1094 m->generator_unit_path,
1095 m->generator_unit_path_early,
1096 m->generator_unit_path_late);
1097 if (r < 0)
1098 return r;
1099
fe51822e
LP
1100 manager_build_unit_path_cache(m);
1101
9f611ad8
LP
1102 /* If we will deserialize make sure that during enumeration
1103 * this is already known, so we increase the counter here
1104 * already */
1105 if (serialization)
a7556052 1106 m->n_reloading ++;
9f611ad8 1107
a16e1123 1108 /* First, enumerate what we can from all config files */
718db961 1109 dual_timestamp_get(&m->units_load_start_timestamp);
a16e1123 1110 r = manager_enumerate(m);
718db961 1111 dual_timestamp_get(&m->units_load_finish_timestamp);
a16e1123
LP
1112
1113 /* Second, deserialize if there is something to deserialize */
1cd974ed
ZJS
1114 if (serialization)
1115 r = manager_deserialize(m, serialization, fds);
a16e1123 1116
01e10de3
LP
1117 /* Any fds left? Find some unit which wants them. This is
1118 * useful to allow container managers to pass some file
1119 * descriptors to us pre-initialized. This enables
1120 * socket-based activation of entire containers. */
1121 if (fdset_size(fds) > 0) {
1122 q = manager_distribute_fds(m, fds);
1cd974ed 1123 if (q < 0 && r == 0)
01e10de3
LP
1124 r = q;
1125 }
1126
d86f9d52
LP
1127 /* We might have deserialized the notify fd, but if we didn't
1128 * then let's create the bus now */
1cd974ed
ZJS
1129 q = manager_setup_notify(m);
1130 if (q < 0 && r == 0)
1131 r = q;
d86f9d52 1132
e3dd987c
LP
1133 /* We might have deserialized the kdbus control fd, but if we
1134 * didn't, then let's create the bus now. */
1135 manager_setup_kdbus(m);
1136 manager_connect_bus(m, !!serialization);
8f8f05a9 1137 bus_track_coldplug(m, &m->subscribed, &m->deserialized_subscribed);
e3dd987c 1138
a16e1123 1139 /* Third, fire things up! */
07719a21 1140 q = manager_coldplug(m);
1cd974ed 1141 if (q < 0 && r == 0)
a16e1123
LP
1142 r = q;
1143
9f611ad8 1144 if (serialization) {
a7556052
LP
1145 assert(m->n_reloading > 0);
1146 m->n_reloading --;
71445ae7
LP
1147
1148 /* Let's wait for the UnitNew/JobNew messages being
1149 * sent, before we notify that the reload is
1150 * finished */
1151 m->send_reloading_done = true;
9f611ad8
LP
1152 }
1153
a16e1123 1154 return r;
f50e0a01
LP
1155}
1156
718db961 1157int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
e5b5ae50 1158 int r;
7527cb52 1159 Transaction *tr;
e5b5ae50
LP
1160
1161 assert(m);
1162 assert(type < _JOB_TYPE_MAX);
87f0e418 1163 assert(unit);
e5b5ae50 1164 assert(mode < _JOB_MODE_MAX);
60918275 1165
7358dc02
ZJS
1166 if (mode == JOB_ISOLATE && type != JOB_START)
1167 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start.");
c497c7a9 1168
7358dc02
ZJS
1169 if (mode == JOB_ISOLATE && !unit->allow_isolate)
1170 return sd_bus_error_setf(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
2528a7a6 1171
79008bdd 1172 log_unit_debug(unit->id,
66870f90
ZJS
1173 "Trying to enqueue job %s/%s/%s", unit->id,
1174 job_type_to_string(type), job_mode_to_string(mode));
9f04bd52 1175
e0209d83
MS
1176 job_type_collapse(&type, unit);
1177
23ade460 1178 tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
7527cb52
MS
1179 if (!tr)
1180 return -ENOMEM;
11dd41ce 1181
7527cb52
MS
1182 r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
1183 mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
b94fbd30 1184 mode == JOB_IGNORE_DEPENDENCIES, e);
7527cb52
MS
1185 if (r < 0)
1186 goto tr_abort;
c497c7a9 1187
7527cb52
MS
1188 if (mode == JOB_ISOLATE) {
1189 r = transaction_add_isolate_jobs(tr, m);
1190 if (r < 0)
1191 goto tr_abort;
1192 }
1193
1194 r = transaction_activate(tr, m, mode, e);
1195 if (r < 0)
1196 goto tr_abort;
e5b5ae50 1197
79008bdd 1198 log_unit_debug(unit->id,
66870f90
ZJS
1199 "Enqueued job %s/%s as %u", unit->id,
1200 job_type_to_string(type), (unsigned) tr->anchor_job->id);
f50e0a01 1201
e5b5ae50 1202 if (_ret)
b94fbd30 1203 *_ret = tr->anchor_job;
60918275 1204
7527cb52 1205 transaction_free(tr);
e5b5ae50 1206 return 0;
7527cb52
MS
1207
1208tr_abort:
1209 transaction_abort(tr);
1210 transaction_free(tr);
1211 return r;
e5b5ae50 1212}
60918275 1213
718db961 1214int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
28247076
LP
1215 Unit *unit;
1216 int r;
1217
1218 assert(m);
1219 assert(type < _JOB_TYPE_MAX);
1220 assert(name);
1221 assert(mode < _JOB_MODE_MAX);
1222
c3090674
LP
1223 r = manager_load_unit(m, name, NULL, NULL, &unit);
1224 if (r < 0)
28247076
LP
1225 return r;
1226
398ef8ba 1227 return manager_add_job(m, type, unit, mode, override, e, _ret);
28247076
LP
1228}
1229
60918275
LP
1230Job *manager_get_job(Manager *m, uint32_t id) {
1231 assert(m);
1232
1233 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
1234}
1235
87f0e418 1236Unit *manager_get_unit(Manager *m, const char *name) {
60918275
LP
1237 assert(m);
1238 assert(name);
1239
87f0e418 1240 return hashmap_get(m->units, name);
60918275
LP
1241}
1242
c1e1601e 1243unsigned manager_dispatch_load_queue(Manager *m) {
595ed347 1244 Unit *u;
c1e1601e 1245 unsigned n = 0;
60918275
LP
1246
1247 assert(m);
1248
223dabab
LP
1249 /* Make sure we are not run recursively */
1250 if (m->dispatching_load_queue)
c1e1601e 1251 return 0;
223dabab
LP
1252
1253 m->dispatching_load_queue = true;
1254
87f0e418 1255 /* Dispatches the load queue. Takes a unit from the queue and
60918275
LP
1256 * tries to load its data until the queue is empty */
1257
595ed347
MS
1258 while ((u = m->load_queue)) {
1259 assert(u->in_load_queue);
034c6ed7 1260
595ed347 1261 unit_load(u);
c1e1601e 1262 n++;
60918275
LP
1263 }
1264
223dabab 1265 m->dispatching_load_queue = false;
c1e1601e 1266 return n;
60918275
LP
1267}
1268
c2756a68
LP
1269int manager_load_unit_prepare(
1270 Manager *m,
1271 const char *name,
1272 const char *path,
718db961 1273 sd_bus_error *e,
c2756a68
LP
1274 Unit **_ret) {
1275
87f0e418 1276 Unit *ret;
7d17cfbc 1277 UnitType t;
60918275
LP
1278 int r;
1279
1280 assert(m);
9e2f7c11 1281 assert(name || path);
60918275 1282
db06e3b6
LP
1283 /* This will prepare the unit for loading, but not actually
1284 * load anything from disk. */
0301abf4 1285
718db961
LP
1286 if (path && !is_path(path))
1287 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
9e2f7c11
LP
1288
1289 if (!name)
2b6bf07d 1290 name = basename(path);
9e2f7c11 1291
7d17cfbc
MS
1292 t = unit_name_to_type(name);
1293
f78e6385 1294 if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, TEMPLATE_INVALID))
718db961 1295 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name);
60918275 1296
7d17cfbc
MS
1297 ret = manager_get_unit(m, name);
1298 if (ret) {
034c6ed7 1299 *_ret = ret;
413d6313 1300 return 1;
034c6ed7 1301 }
60918275 1302
7d17cfbc
MS
1303 ret = unit_new(m, unit_vtable[t]->object_size);
1304 if (!ret)
60918275
LP
1305 return -ENOMEM;
1306
7d17cfbc 1307 if (path) {
ac155bb8
MS
1308 ret->fragment_path = strdup(path);
1309 if (!ret->fragment_path) {
0301abf4
LP
1310 unit_free(ret);
1311 return -ENOMEM;
1312 }
7d17cfbc 1313 }
0301abf4 1314
1058cbf2
ZJS
1315 r = unit_add_name(ret, name);
1316 if (r < 0) {
87f0e418 1317 unit_free(ret);
1ffba6fe 1318 return r;
60918275
LP
1319 }
1320
87f0e418 1321 unit_add_to_load_queue(ret);
c1e1601e 1322 unit_add_to_dbus_queue(ret);
949061f0 1323 unit_add_to_gc_queue(ret);
c1e1601e 1324
db06e3b6
LP
1325 if (_ret)
1326 *_ret = ret;
1327
1328 return 0;
1329}
1330
c2756a68
LP
1331int manager_load_unit(
1332 Manager *m,
1333 const char *name,
1334 const char *path,
718db961 1335 sd_bus_error *e,
c2756a68
LP
1336 Unit **_ret) {
1337
db06e3b6
LP
1338 int r;
1339
1340 assert(m);
1341
1342 /* This will load the service information files, but not actually
1343 * start any services or anything. */
1344
c3090674
LP
1345 r = manager_load_unit_prepare(m, name, path, e, _ret);
1346 if (r != 0)
db06e3b6
LP
1347 return r;
1348
f50e0a01 1349 manager_dispatch_load_queue(m);
60918275 1350
9e2f7c11 1351 if (_ret)
413d6313 1352 *_ret = unit_follow_merge(*_ret);
9e2f7c11 1353
60918275
LP
1354 return 0;
1355}
a66d02c3 1356
cea8e32e 1357void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1358 Iterator i;
a66d02c3
LP
1359 Job *j;
1360
1361 assert(s);
1362 assert(f);
1363
034c6ed7 1364 HASHMAP_FOREACH(j, s->jobs, i)
cea8e32e 1365 job_dump(j, f, prefix);
a66d02c3
LP
1366}
1367
87f0e418 1368void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1369 Iterator i;
87f0e418 1370 Unit *u;
11dd41ce 1371 const char *t;
a66d02c3
LP
1372
1373 assert(s);
1374 assert(f);
1375
87f0e418 1376 HASHMAP_FOREACH_KEY(u, t, s->units, i)
ac155bb8 1377 if (u->id == t)
87f0e418 1378 unit_dump(u, f, prefix);
a66d02c3 1379}
7fad411c
LP
1380
1381void manager_clear_jobs(Manager *m) {
1382 Job *j;
1383
1384 assert(m);
1385
7fad411c 1386 while ((j = hashmap_first(m->jobs)))
5273510e
MS
1387 /* No need to recurse. We're cancelling all jobs. */
1388 job_finish_and_invalidate(j, JOB_CANCELED, false);
7fad411c 1389}
83c60c9f 1390
752b5905
LP
1391static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
1392 Manager *m = userdata;
83c60c9f 1393 Job *j;
034c6ed7 1394
752b5905
LP
1395 assert(source);
1396 assert(m);
9152c765 1397
034c6ed7 1398 while ((j = m->run_queue)) {
ac1135be 1399 assert(j->installed);
034c6ed7
LP
1400 assert(j->in_run_queue);
1401
1402 job_run_and_invalidate(j);
9152c765 1403 }
034c6ed7 1404
a0b64226 1405 if (m->n_running_jobs > 0)
03b717a3
MS
1406 manager_watch_jobs_in_progress(m);
1407
31a7eb86
ZJS
1408 if (m->n_on_console > 0)
1409 manager_watch_idle_pipe(m);
1410
752b5905 1411 return 1;
c1e1601e
LP
1412}
1413
9588bc32 1414static unsigned manager_dispatch_dbus_queue(Manager *m) {
c1e1601e 1415 Job *j;
595ed347 1416 Unit *u;
c1e1601e
LP
1417 unsigned n = 0;
1418
1419 assert(m);
1420
1421 if (m->dispatching_dbus_queue)
1422 return 0;
1423
1424 m->dispatching_dbus_queue = true;
1425
595ed347
MS
1426 while ((u = m->dbus_unit_queue)) {
1427 assert(u->in_dbus_queue);
c1e1601e 1428
595ed347 1429 bus_unit_send_change_signal(u);
c1e1601e
LP
1430 n++;
1431 }
1432
1433 while ((j = m->dbus_job_queue)) {
1434 assert(j->in_dbus_queue);
1435
1436 bus_job_send_change_signal(j);
1437 n++;
1438 }
1439
1440 m->dispatching_dbus_queue = false;
71445ae7
LP
1441
1442 if (m->send_reloading_done) {
1443 m->send_reloading_done = false;
1444
718db961 1445 bus_manager_send_reloading(m, false);
71445ae7
LP
1446 }
1447
718db961
LP
1448 if (m->queued_message)
1449 bus_send_queued_message(m);
1450
c1e1601e 1451 return n;
9152c765
LP
1452}
1453
5ba6985b
LP
1454static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, char *buf, size_t n) {
1455 _cleanup_strv_free_ char **tags = NULL;
1456
1457 assert(m);
1458 assert(u);
1459 assert(buf);
1460 assert(n > 0);
1461
1462 tags = strv_split(buf, "\n\r");
1463 if (!tags) {
1464 log_oom();
1465 return;
1466 }
1467
79008bdd 1468 log_unit_debug(u->id, "Got notification message for unit %s", u->id);
5ba6985b
LP
1469
1470 if (UNIT_VTABLE(u)->notify_message)
1471 UNIT_VTABLE(u)->notify_message(u, pid, tags);
1472}
1473
718db961
LP
1474static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1475 Manager *m = userdata;
8c47c732
LP
1476 ssize_t n;
1477
1478 assert(m);
718db961
LP
1479 assert(m->notify_fd == fd);
1480
1481 if (revents != EPOLLIN) {
1482 log_warning("Got unexpected poll event for notify fd.");
1483 return 0;
1484 }
8c47c732
LP
1485
1486 for (;;) {
1487 char buf[4096];
b92bea5d
ZJS
1488 struct iovec iovec = {
1489 .iov_base = buf,
1490 .iov_len = sizeof(buf)-1,
1491 };
5ba6985b 1492 bool found = false;
b92bea5d 1493
8c47c732
LP
1494 union {
1495 struct cmsghdr cmsghdr;
1496 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
b92bea5d
ZJS
1497 } control = {};
1498
1499 struct msghdr msghdr = {
1500 .msg_iov = &iovec,
1501 .msg_iovlen = 1,
1502 .msg_control = &control,
1503 .msg_controllen = sizeof(control),
1504 };
1505 struct ucred *ucred;
70af4d17 1506 Unit *u1, *u2, *u3;
8c47c732 1507
718db961 1508 n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT);
bd0af849 1509 if (n <= 0) {
b92bea5d 1510 if (n == 0)
8c47c732
LP
1511 return -EIO;
1512
f6144808 1513 if (errno == EAGAIN || errno == EINTR)
8c47c732
LP
1514 break;
1515
1516 return -errno;
1517 }
1518
1519 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
1520 control.cmsghdr.cmsg_level != SOL_SOCKET ||
1521 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
1522 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
1523 log_warning("Received notify message without credentials. Ignoring.");
1524 continue;
1525 }
1526
1527 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
1528
8c40acf7
LP
1529 assert((size_t) n < sizeof(buf));
1530 buf[n] = 0;
8c47c732 1531
70af4d17
LP
1532 /* Notify every unit that might be interested, but try
1533 * to avoid notifying the same one multiple times. */
1534 u1 = manager_get_unit_by_pid(m, ucred->pid);
1535 if (u1) {
1536 manager_invoke_notify_message(m, u1, ucred->pid, buf, n);
5ba6985b
LP
1537 found = true;
1538 }
1539
70af4d17
LP
1540 u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(ucred->pid));
1541 if (u2 && u2 != u1) {
1542 manager_invoke_notify_message(m, u2, ucred->pid, buf, n);
5ba6985b
LP
1543 found = true;
1544 }
1545
70af4d17
LP
1546 u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(ucred->pid));
1547 if (u3 && u3 != u2 && u3 != u1) {
1548 manager_invoke_notify_message(m, u3, ucred->pid, buf, n);
5ba6985b
LP
1549 found = true;
1550 }
8c47c732 1551
5ba6985b
LP
1552 if (!found)
1553 log_warning("Cannot find unit for notify message of PID "PID_FMT".", ucred->pid);
8c47c732
LP
1554 }
1555
1556 return 0;
1557}
1558
5ba6985b
LP
1559static void invoke_sigchld_event(Manager *m, Unit *u, siginfo_t *si) {
1560 assert(m);
1561 assert(u);
1562 assert(si);
1563
79008bdd 1564 log_unit_debug(u->id, "Child "PID_FMT" belongs to %s", si->si_pid, u->id);
5ba6985b
LP
1565
1566 unit_unwatch_pid(u, si->si_pid);
1567 UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
1568}
1569
034c6ed7 1570static int manager_dispatch_sigchld(Manager *m) {
9152c765
LP
1571 assert(m);
1572
1573 for (;;) {
b92bea5d 1574 siginfo_t si = {};
9152c765 1575
4112df16
LP
1576 /* First we call waitd() for a PID and do not reap the
1577 * zombie. That way we can still access /proc/$PID for
1578 * it while it is a zombie. */
1579 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
acbb0225
LP
1580
1581 if (errno == ECHILD)
1582 break;
1583
4112df16
LP
1584 if (errno == EINTR)
1585 continue;
1586
9152c765 1587 return -errno;
acbb0225 1588 }
9152c765 1589
4112df16 1590 if (si.si_pid <= 0)
9152c765
LP
1591 break;
1592
15d5d9d9 1593 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
7fd1b19b 1594 _cleanup_free_ char *name = NULL;
70af4d17 1595 Unit *u1, *u2, *u3;
4112df16 1596
87d2c1ff 1597 get_process_comm(si.si_pid, &name);
4112df16 1598
5ba6985b
LP
1599 log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)",
1600 si.si_pid, strna(name),
1601 sigchld_code_to_string(si.si_code),
1602 si.si_status,
1603 strna(si.si_code == CLD_EXITED
1604 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
1605 : signal_to_string(si.si_status)));
1606
1607 /* And now figure out the unit this belongs
1608 * to, it might be multiple... */
70af4d17
LP
1609 u1 = manager_get_unit_by_pid(m, si.si_pid);
1610 if (u1)
1611 invoke_sigchld_event(m, u1, &si);
1612 u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(si.si_pid));
1613 if (u2 && u2 != u1)
1614 invoke_sigchld_event(m, u2, &si);
1615 u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(si.si_pid));
1616 if (u3 && u3 != u2 && u3 != u1)
1617 invoke_sigchld_event(m, u3, &si);
5ba6985b 1618 }
8c47c732 1619
4112df16
LP
1620 /* And now, we actually reap the zombie. */
1621 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
1622 if (errno == EINTR)
1623 continue;
1624
1625 return -errno;
1626 }
9152c765
LP
1627 }
1628
1629 return 0;
1630}
1631
7d793605 1632static int manager_start_target(Manager *m, const char *name, JobMode mode) {
718db961 1633 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
28247076 1634 int r;
398ef8ba 1635
79008bdd 1636 log_unit_debug(name, "Activating special unit %s", name);
1e001f52 1637
bd0af849
ZJS
1638 r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL);
1639 if (r < 0)
79008bdd 1640 log_unit_error(name, "Failed to enqueue %s job: %s", name, bus_error_message(&error, r));
a1b256b0
LP
1641
1642 return r;
28247076
LP
1643}
1644
718db961
LP
1645static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1646 Manager *m = userdata;
9152c765
LP
1647 ssize_t n;
1648 struct signalfd_siginfo sfsi;
1649 bool sigchld = false;
1650
1651 assert(m);
718db961
LP
1652 assert(m->signal_fd == fd);
1653
1654 if (revents != EPOLLIN) {
1655 log_warning("Got unexpected events from signal file descriptor.");
1656 return 0;
1657 }
9152c765
LP
1658
1659 for (;;) {
718db961 1660 n = read(m->signal_fd, &sfsi, sizeof(sfsi));
57cb4adf 1661 if (n != sizeof(sfsi)) {
9152c765
LP
1662
1663 if (n >= 0)
1664 return -EIO;
1665
63090775 1666 if (errno == EINTR || errno == EAGAIN)
acbb0225 1667 break;
9152c765
LP
1668
1669 return -errno;
1670 }
1671
4daf54a8
ZJS
1672 log_received_signal(sfsi.ssi_signo == SIGCHLD ||
1673 (sfsi.ssi_signo == SIGTERM && m->running_as == SYSTEMD_USER)
1674 ? LOG_DEBUG : LOG_INFO,
1675 &sfsi);
1e001f52 1676
b9cd2ec1
LP
1677 switch (sfsi.ssi_signo) {
1678
4112df16 1679 case SIGCHLD:
9152c765 1680 sigchld = true;
b9cd2ec1
LP
1681 break;
1682
6632c602 1683 case SIGTERM:
67445f4e 1684 if (m->running_as == SYSTEMD_SYSTEM) {
db06e3b6
LP
1685 /* This is for compatibility with the
1686 * original sysvinit */
e11dc4a2 1687 m->exit_code = MANAGER_REEXECUTE;
a1b256b0
LP
1688 break;
1689 }
84e9af1e 1690
a1b256b0 1691 /* Fall through */
e11dc4a2
LP
1692
1693 case SIGINT:
67445f4e 1694 if (m->running_as == SYSTEMD_SYSTEM) {
f49fd1d5 1695 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
84e9af1e
LP
1696 break;
1697 }
1698
a1b256b0 1699 /* Run the exit target if there is one, if not, just exit. */
0003d1ab 1700 if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
a1b256b0
LP
1701 m->exit_code = MANAGER_EXIT;
1702 return 0;
1703 }
1704
1705 break;
84e9af1e 1706
28247076 1707 case SIGWINCH:
67445f4e 1708 if (m->running_as == SYSTEMD_SYSTEM)
7d793605 1709 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
84e9af1e 1710
28247076
LP
1711 /* This is a nop on non-init */
1712 break;
84e9af1e 1713
28247076 1714 case SIGPWR:
67445f4e 1715 if (m->running_as == SYSTEMD_SYSTEM)
7d793605 1716 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
84e9af1e 1717
28247076 1718 /* This is a nop on non-init */
84e9af1e 1719 break;
6632c602 1720
1005d14f 1721 case SIGUSR1: {
57ee42ce
LP
1722 Unit *u;
1723
1724 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
1725
1726 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
1727 log_info("Trying to reconnect to bus...");
3996fbe2 1728 bus_init(m, true);
57ee42ce
LP
1729 }
1730
1731 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
1732 log_info("Loading D-Bus service...");
7d793605 1733 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
57ee42ce
LP
1734 }
1735
1736 break;
1737 }
1738
2149e37c 1739 case SIGUSR2: {
718db961
LP
1740 _cleanup_free_ char *dump = NULL;
1741 _cleanup_fclose_ FILE *f = NULL;
2149e37c
LP
1742 size_t size;
1743
718db961
LP
1744 f = open_memstream(&dump, &size);
1745 if (!f) {
2149e37c
LP
1746 log_warning("Failed to allocate memory stream.");
1747 break;
1748 }
1749
1750 manager_dump_units(m, f, "\t");
1751 manager_dump_jobs(m, f, "\t");
1752
1753 if (ferror(f)) {
2149e37c
LP
1754 log_warning("Failed to write status stream");
1755 break;
1756 }
1757
b2cdc666
DM
1758 if (fflush(f)) {
1759 log_warning("Failed to flush status stream");
1760 break;
1761 }
1762
2149e37c 1763 log_dump(LOG_INFO, dump);
1005d14f 1764 break;
2149e37c 1765 }
1005d14f 1766
a16e1123
LP
1767 case SIGHUP:
1768 m->exit_code = MANAGER_RELOAD;
1769 break;
1770
7d793605 1771 default: {
253ee27a 1772
0003d1ab
LP
1773 /* Starting SIGRTMIN+0 */
1774 static const char * const target_table[] = {
7d793605
LP
1775 [0] = SPECIAL_DEFAULT_TARGET,
1776 [1] = SPECIAL_RESCUE_TARGET,
f057408c 1777 [2] = SPECIAL_EMERGENCY_TARGET,
7d793605
LP
1778 [3] = SPECIAL_HALT_TARGET,
1779 [4] = SPECIAL_POWEROFF_TARGET,
0003d1ab
LP
1780 [5] = SPECIAL_REBOOT_TARGET,
1781 [6] = SPECIAL_KEXEC_TARGET
1782 };
1783
1784 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
1785 static const ManagerExitCode code_table[] = {
1786 [0] = MANAGER_HALT,
1787 [1] = MANAGER_POWEROFF,
1788 [2] = MANAGER_REBOOT,
1789 [3] = MANAGER_KEXEC
7d793605
LP
1790 };
1791
1792 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
0003d1ab 1793 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
764e9b5f
MS
1794 int idx = (int) sfsi.ssi_signo - SIGRTMIN;
1795 manager_start_target(m, target_table[idx],
1796 (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
7d793605
LP
1797 break;
1798 }
1799
0003d1ab
LP
1800 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
1801 (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
1802 m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
1803 break;
1804 }
1805
0658666b
LP
1806 switch (sfsi.ssi_signo - SIGRTMIN) {
1807
1808 case 20:
1809 log_debug("Enabling showing of status.");
d450b6f2 1810 manager_set_show_status(m, SHOW_STATUS_YES);
0658666b
LP
1811 break;
1812
1813 case 21:
1814 log_debug("Disabling showing of status.");
d450b6f2 1815 manager_set_show_status(m, SHOW_STATUS_NO);
0658666b
LP
1816 break;
1817
253ee27a
LP
1818 case 22:
1819 log_set_max_level(LOG_DEBUG);
1820 log_notice("Setting log level to debug.");
1821 break;
1822
1823 case 23:
1824 log_set_max_level(LOG_INFO);
1825 log_notice("Setting log level to info.");
1826 break;
1827
600b704e
LP
1828 case 24:
1829 if (m->running_as == SYSTEMD_USER) {
1830 m->exit_code = MANAGER_EXIT;
1831 return 0;
1832 }
1833
1834 /* This is a nop on init */
1835 break;
1836
4cfa2c99 1837 case 26:
c1dc6153 1838 case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
4cfa2c99
LP
1839 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1840 log_notice("Setting log target to journal-or-kmsg.");
1841 break;
1842
253ee27a
LP
1843 case 27:
1844 log_set_target(LOG_TARGET_CONSOLE);
1845 log_notice("Setting log target to console.");
1846 break;
1847
1848 case 28:
1849 log_set_target(LOG_TARGET_KMSG);
1850 log_notice("Setting log target to kmsg.");
1851 break;
1852
0658666b 1853 default:
4e240ab0 1854 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
0658666b 1855 }
b9cd2ec1 1856 }
7d793605 1857 }
9152c765
LP
1858 }
1859
1860 if (sigchld)
7b77ed8c 1861 manager_dispatch_sigchld(m);
034c6ed7
LP
1862
1863 return 0;
1864}
1865
718db961
LP
1866static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1867 Manager *m = userdata;
1868 Iterator i;
1869 Unit *u;
034c6ed7
LP
1870
1871 assert(m);
718db961 1872 assert(m->time_change_fd == fd);
034c6ed7 1873
718db961 1874 log_struct(LOG_INFO,
e2cc6eca
LP
1875 LOG_MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
1876 LOG_MESSAGE("Time has been changed"),
718db961 1877 NULL);
034c6ed7 1878
718db961
LP
1879 /* Restart the watch */
1880 m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
03e334a1 1881 m->time_change_fd = safe_close(m->time_change_fd);
ef734fd6 1882
718db961 1883 manager_setup_time_change(m);
4e434314 1884
718db961
LP
1885 HASHMAP_FOREACH(u, m->units, i)
1886 if (UNIT_VTABLE(u)->time_change)
1887 UNIT_VTABLE(u)->time_change(u);
ea430986 1888
718db961
LP
1889 return 0;
1890}
ea430986 1891
718db961
LP
1892static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1893 Manager *m = userdata;
8742514c 1894
718db961
LP
1895 assert(m);
1896 assert(m->idle_pipe[2] == fd);
8742514c 1897
718db961 1898 m->no_console_output = m->n_on_console > 0;
03b717a3 1899
718db961
LP
1900 m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
1901 manager_close_idle_pipe(m);
03b717a3 1902
718db961
LP
1903 return 0;
1904}
31a7eb86 1905
718db961
LP
1906static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
1907 Manager *m = userdata;
fd08a840
ZJS
1908 int r;
1909 uint64_t next;
31a7eb86 1910
718db961 1911 assert(m);
fd08a840 1912 assert(source);
9152c765 1913
718db961 1914 manager_print_jobs_in_progress(m);
fd08a840
ZJS
1915
1916 next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
1917 r = sd_event_source_set_time(source, next);
1918 if (r < 0)
1919 return r;
1920
1921 return sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
9152c765
LP
1922}
1923
1924int manager_loop(Manager *m) {
1925 int r;
9152c765 1926
fac9f8df 1927 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
ea430986 1928
9152c765 1929 assert(m);
f755e3b7 1930 m->exit_code = MANAGER_OK;
9152c765 1931
fe51822e
LP
1932 /* Release the path cache */
1933 set_free_free(m->unit_path_cache);
1934 m->unit_path_cache = NULL;
1935
b0c918b9
LP
1936 manager_check_finished(m);
1937
a4312405 1938 /* There might still be some zombies hanging around from
f3669545 1939 * before we were exec()'ed. Let's reap them. */
e96d6be7
LP
1940 r = manager_dispatch_sigchld(m);
1941 if (r < 0)
a4312405
LP
1942 return r;
1943
f755e3b7 1944 while (m->exit_code == MANAGER_OK) {
718db961 1945 usec_t wait_usec;
9152c765 1946
67445f4e 1947 if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
e96d6be7
LP
1948 watchdog_ping();
1949
ea430986
LP
1950 if (!ratelimit_test(&rl)) {
1951 /* Yay, something is going seriously wrong, pause a little */
1952 log_warning("Looping too fast. Throttling execution a little.");
1953 sleep(1);
e96d6be7 1954 continue;
ea430986
LP
1955 }
1956
37a8e683 1957 if (manager_dispatch_load_queue(m) > 0)
23a177ef
LP
1958 continue;
1959
cf1265e1 1960 if (manager_dispatch_gc_queue(m) > 0)
701cc384
LP
1961 continue;
1962
cf1265e1 1963 if (manager_dispatch_cleanup_queue(m) > 0)
c1e1601e 1964 continue;
034c6ed7 1965
cf1265e1 1966 if (manager_dispatch_cgroup_queue(m) > 0)
c1e1601e
LP
1967 continue;
1968
c1e1601e 1969 if (manager_dispatch_dbus_queue(m) > 0)
ea430986 1970 continue;
ea430986 1971
c757a65b 1972 /* Sleep for half the watchdog time */
67445f4e 1973 if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM) {
718db961
LP
1974 wait_usec = m->runtime_watchdog / 2;
1975 if (wait_usec <= 0)
1976 wait_usec = 1;
c757a65b 1977 } else
3a43da28 1978 wait_usec = USEC_INFINITY;
9152c765 1979
718db961 1980 r = sd_event_run(m->event, wait_usec);
23bbb0de
MS
1981 if (r < 0)
1982 return log_error_errno(r, "Failed to run event loop: %m");
a16e1123 1983 }
957ca890 1984
a16e1123 1985 return m->exit_code;
83c60c9f 1986}
ea430986 1987
718db961 1988int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u) {
ede3a796 1989 _cleanup_free_ char *n = NULL;
ea430986 1990 Unit *u;
80fbf05e 1991 int r;
ea430986
LP
1992
1993 assert(m);
1994 assert(s);
1995 assert(_u);
1996
ede3a796
LP
1997 r = unit_name_from_dbus_path(s, &n);
1998 if (r < 0)
1999 return r;
ea430986 2000
80fbf05e 2001 r = manager_load_unit(m, n, NULL, e, &u);
80fbf05e
MS
2002 if (r < 0)
2003 return r;
ea430986
LP
2004
2005 *_u = u;
2006
2007 return 0;
2008}
86fbf370
LP
2009
2010int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
718db961 2011 const char *p;
86fbf370 2012 unsigned id;
718db961 2013 Job *j;
86fbf370
LP
2014 int r;
2015
2016 assert(m);
2017 assert(s);
2018 assert(_j);
2019
718db961
LP
2020 p = startswith(s, "/org/freedesktop/systemd1/job/");
2021 if (!p)
86fbf370
LP
2022 return -EINVAL;
2023
718db961 2024 r = safe_atou(p, &id);
8742514c 2025 if (r < 0)
86fbf370
LP
2026 return r;
2027
8742514c
LP
2028 j = manager_get_job(m, id);
2029 if (!j)
86fbf370
LP
2030 return -ENOENT;
2031
2032 *_j = j;
2033
2034 return 0;
2035}
dfcd764e 2036
4927fcae 2037void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
e537352b 2038
4927fcae 2039#ifdef HAVE_AUDIT
2ba11090 2040 _cleanup_free_ char *p = NULL;
0aa281df 2041 const char *msg;
c1165f82 2042 int audit_fd;
e537352b 2043
c1165f82
LP
2044 audit_fd = get_audit_fd();
2045 if (audit_fd < 0)
e537352b
LP
2046 return;
2047
bbd3a7ba
LP
2048 /* Don't generate audit events if the service was already
2049 * started and we're just deserializing */
a7556052 2050 if (m->n_reloading > 0)
bbd3a7ba
LP
2051 return;
2052
67445f4e 2053 if (m->running_as != SYSTEMD_SYSTEM)
f1dd0c3f
LP
2054 return;
2055
ac155bb8 2056 if (u->type != UNIT_SERVICE)
f1dd0c3f
LP
2057 return;
2058
bd0af849
ZJS
2059 p = unit_name_to_prefix_and_instance(u->id);
2060 if (!p) {
0aa281df 2061 log_oom();
e537352b
LP
2062 return;
2063 }
2064
0aa281df
LP
2065 msg = strappenda("unit=", p);
2066
2067 if (audit_log_user_comm_message(audit_fd, type, msg, "systemd", NULL, NULL, NULL, success) < 0) {
2068 if (errno == EPERM)
391ade86 2069 /* We aren't allowed to send audit messages?
44785992 2070 * Then let's not retry again. */
c1165f82 2071 close_audit_fd();
0aa281df 2072 else
56f64d95 2073 log_warning_errno(errno, "Failed to send audit message: %m");
391ade86 2074 }
4927fcae 2075#endif
e537352b 2076
e537352b
LP
2077}
2078
e983b760 2079void manager_send_unit_plymouth(Manager *m, Unit *u) {
1d749d04 2080 union sockaddr_union sa = PLYMOUTH_SOCKET;
2ba11090 2081
e983b760 2082 int n = 0;
2ba11090
ZJS
2083 _cleanup_free_ char *message = NULL;
2084 _cleanup_close_ int fd = -1;
e983b760
LP
2085
2086 /* Don't generate plymouth events if the service was already
2087 * started and we're just deserializing */
a7556052 2088 if (m->n_reloading > 0)
e983b760
LP
2089 return;
2090
67445f4e 2091 if (m->running_as != SYSTEMD_SYSTEM)
e983b760
LP
2092 return;
2093
3772995a
LP
2094 if (detect_container(NULL) > 0)
2095 return;
2096
ac155bb8
MS
2097 if (u->type != UNIT_SERVICE &&
2098 u->type != UNIT_MOUNT &&
2099 u->type != UNIT_SWAP)
e983b760
LP
2100 return;
2101
2102 /* We set SOCK_NONBLOCK here so that we rather drop the
2103 * message then wait for plymouth */
e62d8c39
ZJS
2104 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
2105 if (fd < 0) {
56f64d95 2106 log_error_errno(errno, "socket() failed: %m");
e983b760
LP
2107 return;
2108 }
2109
96707269 2110 if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
e983b760 2111
2ba11090 2112 if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
56f64d95 2113 log_error_errno(errno, "connect() failed: %m");
2ba11090 2114 return;
e983b760
LP
2115 }
2116
ac155bb8 2117 if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
0d0f0c50 2118 log_oom();
2ba11090 2119 return;
e983b760
LP
2120 }
2121
2122 errno = 0;
2ba11090
ZJS
2123 if (write(fd, message, n + 1) != n + 1)
2124 if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
56f64d95 2125 log_error_errno(errno, "Failed to write Plymouth message: %m");
e983b760
LP
2126}
2127
05e343b7
LP
2128void manager_dispatch_bus_name_owner_changed(
2129 Manager *m,
2130 const char *name,
2131 const char* old_owner,
2132 const char *new_owner) {
2133
2134 Unit *u;
2135
2136 assert(m);
2137 assert(name);
2138
718db961
LP
2139 u = hashmap_get(m->watch_bus, name);
2140 if (!u)
05e343b7
LP
2141 return;
2142
2143 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
2144}
2145
d8d5ab98 2146int manager_open_serialization(Manager *m, FILE **_f) {
8e33886e 2147 const char *path;
df28bc08 2148 int fd = -1;
a16e1123
LP
2149 FILE *f;
2150
2151 assert(_f);
2152
8e33886e
ZJS
2153 path = m->running_as == SYSTEMD_SYSTEM ? "/run/systemd" : "/tmp";
2154 fd = open_tmpfile(path, O_RDWR|O_CLOEXEC);
d86f9d52 2155 if (fd < 0)
a16e1123 2156 return -errno;
a16e1123 2157
a16e1123 2158 log_debug("Serializing state to %s", path);
a16e1123 2159
01e10de3 2160 f = fdopen(fd, "w+");
d86f9d52 2161 if (!f) {
03e334a1 2162 safe_close(fd);
a16e1123 2163 return -errno;
d86f9d52 2164 }
a16e1123
LP
2165
2166 *_f = f;
2167
2168 return 0;
2169}
2170
b3680f49 2171int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
a16e1123
LP
2172 Iterator i;
2173 Unit *u;
2174 const char *t;
4a9fd066 2175 char **e;
a16e1123
LP
2176 int r;
2177
2178 assert(m);
2179 assert(f);
2180 assert(fds);
2181
a7556052 2182 m->n_reloading ++;
38c52d46 2183
01d67b43
LP
2184 fprintf(f, "current-job-id=%i\n", m->current_job_id);
2185 fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
33c5fae9
LP
2186 fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
2187 fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
01d67b43 2188
915b3753 2189 dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp);
915b3753 2190 dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp);
718db961 2191 dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp);
e9ddabc2 2192 dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
f38ed060 2193
26a1efdf 2194 if (!in_initrd()) {
915b3753 2195 dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp);
f38ed060 2196 dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
718db961
LP
2197 dual_timestamp_serialize(f, "security-start-timestamp", &m->security_start_timestamp);
2198 dual_timestamp_serialize(f, "security-finish-timestamp", &m->security_finish_timestamp);
2199 dual_timestamp_serialize(f, "generators-start-timestamp", &m->generators_start_timestamp);
2200 dual_timestamp_serialize(f, "generators-finish-timestamp", &m->generators_finish_timestamp);
2201 dual_timestamp_serialize(f, "units-load-start-timestamp", &m->units_load_start_timestamp);
2202 dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp);
f38ed060 2203 }
47a483a1 2204
b3680f49
HH
2205 if (!switching_root) {
2206 STRV_FOREACH(e, m->environment) {
2207 _cleanup_free_ char *ce;
4a9fd066 2208
b3680f49 2209 ce = cescape(*e);
e3dd987c
LP
2210 if (!ce)
2211 return -ENOMEM;
2212
2213 fprintf(f, "env=%s\n", *e);
b3680f49 2214 }
4a9fd066
OS
2215 }
2216
d86f9d52
LP
2217 if (m->notify_fd >= 0) {
2218 int copy;
2219
2220 copy = fdset_put_dup(fds, m->notify_fd);
2221 if (copy < 0)
2222 return copy;
2223
2224 fprintf(f, "notify-fd=%i\n", copy);
2225 fprintf(f, "notify-socket=%s\n", m->notify_socket);
2226 }
2227
e3dd987c
LP
2228 if (m->kdbus_fd >= 0) {
2229 int copy;
2230
2231 copy = fdset_put_dup(fds, m->kdbus_fd);
2232 if (copy < 0)
2233 return copy;
2234
2235 fprintf(f, "kdbus-fd=%i\n", copy);
2236 }
2237
8f8f05a9 2238 bus_track_serialize(m->subscribed, f);
6fa48533 2239
f2382a94
LP
2240 fputc('\n', f);
2241
a16e1123 2242 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
ac155bb8 2243 if (u->id != t)
a16e1123
LP
2244 continue;
2245
a16e1123 2246 /* Start marker */
ac155bb8 2247 fputs(u->id, f);
a16e1123
LP
2248 fputc('\n', f);
2249
6fa48533
LP
2250 r = unit_serialize(u, f, fds, !switching_root);
2251 if (r < 0) {
a7556052 2252 m->n_reloading --;
a16e1123 2253 return r;
38c52d46 2254 }
a16e1123
LP
2255 }
2256
a7556052
LP
2257 assert(m->n_reloading > 0);
2258 m->n_reloading --;
38c52d46 2259
a16e1123
LP
2260 if (ferror(f))
2261 return -EIO;
2262
b23de6af
LP
2263 r = bus_fdset_add_all(m, fds);
2264 if (r < 0)
2265 return r;
2266
a16e1123
LP
2267 return 0;
2268}
2269
2270int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
2271 int r = 0;
2272
2273 assert(m);
2274 assert(f);
2275
2276 log_debug("Deserializing state...");
2277
a7556052 2278 m->n_reloading ++;
82c64bf5 2279
10f8e83c 2280 for (;;) {
20c03b7b 2281 char line[LINE_MAX], *l;
10f8e83c
LP
2282
2283 if (!fgets(line, sizeof(line), f)) {
2284 if (feof(f))
2285 r = 0;
2286 else
2287 r = -errno;
2288
2289 goto finish;
2290 }
2291
2292 char_array_0(line);
2293 l = strstrip(line);
2294
2295 if (l[0] == 0)
2296 break;
2297
01d67b43
LP
2298 if (startswith(l, "current-job-id=")) {
2299 uint32_t id;
2300
2301 if (safe_atou32(l+15, &id) < 0)
46849c3f 2302 log_warning("Failed to parse current job id value %s", l+15);
01d67b43
LP
2303 else
2304 m->current_job_id = MAX(m->current_job_id, id);
718db961 2305
33c5fae9
LP
2306 } else if (startswith(l, "n-installed-jobs=")) {
2307 uint32_t n;
2308
2309 if (safe_atou32(l+17, &n) < 0)
46849c3f 2310 log_warning("Failed to parse installed jobs counter %s", l+17);
33c5fae9
LP
2311 else
2312 m->n_installed_jobs += n;
718db961 2313
33c5fae9
LP
2314 } else if (startswith(l, "n-failed-jobs=")) {
2315 uint32_t n;
2316
2317 if (safe_atou32(l+14, &n) < 0)
46849c3f 2318 log_warning("Failed to parse failed jobs counter %s", l+14);
33c5fae9
LP
2319 else
2320 m->n_failed_jobs += n;
718db961 2321
01d67b43
LP
2322 } else if (startswith(l, "taint-usr=")) {
2323 int b;
2324
e3dd987c
LP
2325 b = parse_boolean(l+10);
2326 if (b < 0)
46849c3f 2327 log_warning("Failed to parse taint /usr flag %s", l+10);
01d67b43
LP
2328 else
2329 m->taint_usr = m->taint_usr || b;
718db961 2330
915b3753
LP
2331 } else if (startswith(l, "firmware-timestamp="))
2332 dual_timestamp_deserialize(l+19, &m->firmware_timestamp);
2333 else if (startswith(l, "loader-timestamp="))
2334 dual_timestamp_deserialize(l+17, &m->loader_timestamp);
2335 else if (startswith(l, "kernel-timestamp="))
2336 dual_timestamp_deserialize(l+17, &m->kernel_timestamp);
2337 else if (startswith(l, "initrd-timestamp="))
e9ddabc2 2338 dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
915b3753
LP
2339 else if (startswith(l, "userspace-timestamp="))
2340 dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
10717a1a 2341 else if (startswith(l, "finish-timestamp="))
799fd0fd 2342 dual_timestamp_deserialize(l+17, &m->finish_timestamp);
718db961
LP
2343 else if (startswith(l, "security-start-timestamp="))
2344 dual_timestamp_deserialize(l+25, &m->security_start_timestamp);
2345 else if (startswith(l, "security-finish-timestamp="))
2346 dual_timestamp_deserialize(l+26, &m->security_finish_timestamp);
2347 else if (startswith(l, "generators-start-timestamp="))
2348 dual_timestamp_deserialize(l+27, &m->generators_start_timestamp);
2349 else if (startswith(l, "generators-finish-timestamp="))
2350 dual_timestamp_deserialize(l+28, &m->generators_finish_timestamp);
2351 else if (startswith(l, "units-load-start-timestamp="))
2352 dual_timestamp_deserialize(l+27, &m->units_load_start_timestamp);
2353 else if (startswith(l, "units-load-finish-timestamp="))
2354 dual_timestamp_deserialize(l+28, &m->units_load_finish_timestamp);
4a9fd066
OS
2355 else if (startswith(l, "env=")) {
2356 _cleanup_free_ char *uce = NULL;
2357 char **e;
2358
2359 uce = cunescape(l+4);
2360 if (!uce) {
2361 r = -ENOMEM;
2362 goto finish;
2363 }
2364
2365 e = strv_env_set(m->environment, uce);
2366 if (!e) {
2367 r = -ENOMEM;
2368 goto finish;
2369 }
2370
2371 strv_free(m->environment);
2372 m->environment = e;
e3dd987c 2373
d86f9d52
LP
2374 } else if (startswith(l, "notify-fd=")) {
2375 int fd;
2376
2377 if (safe_atoi(l + 10, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
46849c3f 2378 log_warning("Failed to parse notify fd: %s", l + 10);
d86f9d52 2379 else {
03e334a1
LP
2380 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
2381 safe_close(m->notify_fd);
d86f9d52
LP
2382 m->notify_fd = fdset_remove(fds, fd);
2383 }
2384
2385 } else if (startswith(l, "notify-socket=")) {
2386 char *n;
2387
2388 n = strdup(l+14);
2389 if (!n) {
2390 r = -ENOMEM;
2391 goto finish;
2392 }
2393
2394 free(m->notify_socket);
2395 m->notify_socket = n;
2396
e3dd987c
LP
2397 } else if (startswith(l, "kdbus-fd=")) {
2398 int fd;
2399
8bf9fcf4 2400 if (safe_atoi(l + 9, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
46849c3f 2401 log_warning("Failed to parse kdbus fd: %s", l + 9);
e3dd987c 2402 else {
03e334a1 2403 safe_close(m->kdbus_fd);
e3dd987c
LP
2404 m->kdbus_fd = fdset_remove(fds, fd);
2405 }
2406
f44b9efc 2407 } else if (bus_track_deserialize_item(&m->deserialized_subscribed, l) < 0)
46849c3f 2408 log_warning("Unknown serialization item '%s'", l);
10f8e83c
LP
2409 }
2410
a16e1123
LP
2411 for (;;) {
2412 Unit *u;
2413 char name[UNIT_NAME_MAX+2];
2414
2415 /* Start marker */
2416 if (!fgets(name, sizeof(name), f)) {
2417 if (feof(f))
10f8e83c
LP
2418 r = 0;
2419 else
2420 r = -errno;
a16e1123 2421
82c64bf5 2422 goto finish;
a16e1123
LP
2423 }
2424
2425 char_array_0(name);
2426
bd0af849
ZJS
2427 r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
2428 if (r < 0)
82c64bf5 2429 goto finish;
a16e1123 2430
01e10de3
LP
2431 r = unit_deserialize(u, f, fds);
2432 if (r < 0)
82c64bf5 2433 goto finish;
a16e1123
LP
2434 }
2435
10f8e83c 2436finish:
145b1f79 2437 if (ferror(f))
82c64bf5 2438 r = -EIO;
a16e1123 2439
a7556052
LP
2440 assert(m->n_reloading > 0);
2441 m->n_reloading --;
82c64bf5
LP
2442
2443 return r;
a16e1123
LP
2444}
2445
2446int manager_reload(Manager *m) {
2447 int r, q;
51d122af
ZJS
2448 _cleanup_fclose_ FILE *f = NULL;
2449 _cleanup_fdset_free_ FDSet *fds = NULL;
a16e1123
LP
2450
2451 assert(m);
2452
07719a21
LP
2453 r = manager_open_serialization(m, &f);
2454 if (r < 0)
a16e1123
LP
2455 return r;
2456
a7556052 2457 m->n_reloading ++;
718db961 2458 bus_manager_send_reloading(m, true);
38c52d46 2459
07719a21
LP
2460 fds = fdset_new();
2461 if (!fds) {
a7556052 2462 m->n_reloading --;
51d122af 2463 return -ENOMEM;
a16e1123
LP
2464 }
2465
b3680f49 2466 r = manager_serialize(m, f, fds, false);
07719a21 2467 if (r < 0) {
a7556052 2468 m->n_reloading --;
51d122af 2469 return r;
38c52d46 2470 }
a16e1123
LP
2471
2472 if (fseeko(f, 0, SEEK_SET) < 0) {
a7556052 2473 m->n_reloading --;
51d122af 2474 return -errno;
a16e1123
LP
2475 }
2476
2477 /* From here on there is no way back. */
2478 manager_clear_jobs_and_units(m);
5a1e9937 2479 manager_undo_generators(m);
84e3543e 2480 lookup_paths_free(&m->lookup_paths);
2ded0c04 2481
07719a21 2482 /* Find new unit paths */
5a1e9937
LP
2483 manager_run_generators(m);
2484
07719a21
LP
2485 q = lookup_paths_init(
2486 &m->lookup_paths, m->running_as, true,
12ed81d9 2487 NULL,
07719a21
LP
2488 m->generator_unit_path,
2489 m->generator_unit_path_early,
2490 m->generator_unit_path_late);
2491 if (q < 0)
2492 r = q;
2493
5a1e9937
LP
2494 manager_build_unit_path_cache(m);
2495
a16e1123 2496 /* First, enumerate what we can from all config files */
07719a21
LP
2497 q = manager_enumerate(m);
2498 if (q < 0)
a16e1123
LP
2499 r = q;
2500
2501 /* Second, deserialize our stored data */
07719a21
LP
2502 q = manager_deserialize(m, f, fds);
2503 if (q < 0)
a16e1123
LP
2504 r = q;
2505
2506 fclose(f);
2507 f = NULL;
2508
a2cc4a6c
ZJS
2509 /* Re-register notify_fd as event source */
2510 q = manager_setup_notify(m);
2511 if (q < 0)
2512 r = q;
2513
a16e1123 2514 /* Third, fire things up! */
07719a21
LP
2515 q = manager_coldplug(m);
2516 if (q < 0)
a16e1123
LP
2517 r = q;
2518
a7556052
LP
2519 assert(m->n_reloading > 0);
2520 m->n_reloading--;
9f611ad8 2521
71445ae7
LP
2522 m->send_reloading_done = true;
2523
a16e1123
LP
2524 return r;
2525}
2526
c17ec25e
MS
2527bool manager_is_reloading_or_reexecuting(Manager *m) {
2528 assert(m);
2529
2530 return m->n_reloading != 0;
2531}
2532
fdf20a31 2533void manager_reset_failed(Manager *m) {
5632e374
LP
2534 Unit *u;
2535 Iterator i;
2536
2537 assert(m);
2538
2539 HASHMAP_FOREACH(u, m->units, i)
fdf20a31 2540 unit_reset_failed(u);
5632e374
LP
2541}
2542
31afa0a4 2543bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
8f6df3fa
LP
2544 Unit *u;
2545
2546 assert(m);
2547 assert(name);
2548
2549 /* Returns true if the unit is inactive or going down */
bd0af849
ZJS
2550 u = manager_get_unit(m, name);
2551 if (!u)
8f6df3fa
LP
2552 return true;
2553
31afa0a4 2554 return unit_inactive_or_pending(u);
8f6df3fa
LP
2555}
2556
56dacdbc 2557static void manager_notify_finished(Manager *m) {
7ceba241 2558 char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
915b3753 2559 usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
b0c918b9 2560
56dacdbc 2561 if (m->test_run)
b0c918b9
LP
2562 return;
2563
67445f4e 2564 if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
e03ae661 2565
915b3753
LP
2566 /* Note that m->kernel_usec.monotonic is always at 0,
2567 * and m->firmware_usec.monotonic and
2568 * m->loader_usec.monotonic should be considered
2569 * negative values. */
2570
7ceba241
LP
2571 firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic;
2572 loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic;
915b3753 2573 userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
7ceba241 2574 total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic;
18fa6b27 2575
e9ddabc2 2576 if (dual_timestamp_is_set(&m->initrd_timestamp)) {
18fa6b27 2577
915b3753
LP
2578 kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
2579 initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
18fa6b27 2580
e12919e8 2581 log_struct(LOG_INFO,
e2cc6eca 2582 LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
e12919e8
LP
2583 "KERNEL_USEC="USEC_FMT, kernel_usec,
2584 "INITRD_USEC="USEC_FMT, initrd_usec,
2585 "USERSPACE_USEC="USEC_FMT, userspace_usec,
e2cc6eca
LP
2586 LOG_MESSAGE("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
2587 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2588 format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
2589 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2590 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
e12919e8 2591 NULL);
18fa6b27 2592 } else {
915b3753 2593 kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
18fa6b27
LP
2594 initrd_usec = 0;
2595
81270860 2596 log_struct(LOG_INFO,
e2cc6eca 2597 LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
e12919e8 2598 "KERNEL_USEC="USEC_FMT, kernel_usec,
ccd06097 2599 "USERSPACE_USEC="USEC_FMT, userspace_usec,
e2cc6eca
LP
2600 LOG_MESSAGE("Startup finished in %s (kernel) + %s (userspace) = %s.",
2601 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2602 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2603 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
81270860 2604 NULL);
e12919e8
LP
2605 }
2606 } else {
2607 firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
2608 total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
2609
2610 log_struct(LOG_INFO,
e2cc6eca 2611 LOG_MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
e12919e8 2612 "USERSPACE_USEC="USEC_FMT, userspace_usec,
e2cc6eca
LP
2613 LOG_MESSAGE("Startup finished in %s.",
2614 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)),
e12919e8 2615 NULL);
18fa6b27 2616 }
b0c918b9 2617
718db961 2618 bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
530345e7
LP
2619
2620 sd_notifyf(false,
af4ec430
LP
2621 "READY=1\n"
2622 "STATUS=Startup finished in %s.",
2fa4092c 2623 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
b0c918b9
LP
2624}
2625
56dacdbc
ZJS
2626void manager_check_finished(Manager *m) {
2627 Unit *u = NULL;
2628 Iterator i;
2629
2630 assert(m);
2631
2632 if (m->n_running_jobs == 0)
2633 m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
2634
2635 if (hashmap_size(m->jobs) > 0) {
2636
2637 if (m->jobs_in_progress_event_source)
2638 sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
2639
2640 return;
2641 }
2642
2643 manager_flip_auto_status(m, false);
2644
2645 /* Notify Type=idle units that we are done now */
2646 m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
2647 manager_close_idle_pipe(m);
2648
2649 /* Turn off confirm spawn now */
2650 m->confirm_spawn = false;
2651
2652 /* No need to update ask password status when we're going non-interactive */
2653 manager_close_ask_password(m);
2654
2655 /* This is no longer the first boot */
2656 manager_set_first_boot(m, false);
2657
2658 if (dual_timestamp_is_set(&m->finish_timestamp))
2659 return;
2660
2661 dual_timestamp_get(&m->finish_timestamp);
2662
2663 manager_notify_finished(m);
2664
2665 SET_FOREACH(u, m->startup_units, i)
2666 if (u->cgroup_path)
2667 cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
2668}
2669
07719a21
LP
2670static int create_generator_dir(Manager *m, char **generator, const char *name) {
2671 char *p;
2672 int r;
2673
2674 assert(m);
2675 assert(generator);
2676 assert(name);
2677
2678 if (*generator)
2679 return 0;
2680
67445f4e 2681 if (m->running_as == SYSTEMD_SYSTEM && getpid() == 1) {
fcc81ea3 2682 /* systemd --system, not running --test */
07719a21
LP
2683
2684 p = strappend("/run/systemd/", name);
0d0f0c50
SL
2685 if (!p)
2686 return log_oom();
07719a21 2687
fcc81ea3
KS
2688 r = mkdir_p_label(p, 0755);
2689 if (r < 0) {
c33b3297 2690 log_error_errno(r, "Failed to create generator directory %s: %m", p);
fcc81ea3
KS
2691 free(p);
2692 return r;
2693 }
2694 } else if (m->running_as == SYSTEMD_USER) {
2695 const char *s = NULL;
2696
2697 s = getenv("XDG_RUNTIME_DIR");
2698 if (!s)
2699 return -EINVAL;
2700 p = strjoin(s, "/systemd/", name, NULL);
2701 if (!p)
2702 return log_oom();
2703
d2e54fae 2704 r = mkdir_p_label(p, 0755);
07719a21 2705 if (r < 0) {
c33b3297 2706 log_error_errno(r, "Failed to create generator directory %s: %m", p);
07719a21
LP
2707 free(p);
2708 return r;
2709 }
2710 } else {
fcc81ea3
KS
2711 /* systemd --system --test */
2712
b7def684 2713 p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL);
0d0f0c50
SL
2714 if (!p)
2715 return log_oom();
07719a21
LP
2716
2717 if (!mkdtemp(p)) {
56f64d95 2718 log_error_errno(errno, "Failed to create generator directory %s: %m",
7ad94c71 2719 p);
34bf0281 2720 free(p);
07719a21
LP
2721 return -errno;
2722 }
2723 }
2724
2725 *generator = p;
2726 return 0;
2727}
2728
2729static void trim_generator_dir(Manager *m, char **generator) {
2730 assert(m);
2731 assert(generator);
2732
2733 if (!*generator)
2734 return;
2735
2736 if (rmdir(*generator) >= 0) {
2737 free(*generator);
2738 *generator = NULL;
2739 }
2740
2741 return;
2742}
2743
5a1e9937 2744void manager_run_generators(Manager *m) {
718db961 2745 _cleanup_closedir_ DIR *d = NULL;
5a1e9937 2746 const char *generator_path;
07719a21 2747 const char *argv[5];
07719a21 2748 int r;
5a1e9937
LP
2749
2750 assert(m);
2751
0d8c31ff
ZJS
2752 if (m->test_run)
2753 return;
2754
67445f4e 2755 generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
07719a21
LP
2756 d = opendir(generator_path);
2757 if (!d) {
5a1e9937
LP
2758 if (errno == ENOENT)
2759 return;
2760
56f64d95 2761 log_error_errno(errno, "Failed to enumerate generator directory %s: %m",
7ad94c71 2762 generator_path);
5a1e9937
LP
2763 return;
2764 }
2765
07719a21
LP
2766 r = create_generator_dir(m, &m->generator_unit_path, "generator");
2767 if (r < 0)
2768 goto finish;
f1d19aa4 2769
07719a21
LP
2770 r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early");
2771 if (r < 0)
2772 goto finish;
5a1e9937 2773
07719a21
LP
2774 r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late");
2775 if (r < 0)
2776 goto finish;
5a1e9937 2777
83cc030f
LP
2778 argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
2779 argv[1] = m->generator_unit_path;
07719a21
LP
2780 argv[2] = m->generator_unit_path_early;
2781 argv[3] = m->generator_unit_path_late;
2782 argv[4] = NULL;
5a1e9937 2783
718db961 2784 RUN_WITH_UMASK(0022)
e2680723 2785 execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv);
5a1e9937 2786
718db961 2787finish:
07719a21
LP
2788 trim_generator_dir(m, &m->generator_unit_path);
2789 trim_generator_dir(m, &m->generator_unit_path_early);
2790 trim_generator_dir(m, &m->generator_unit_path_late);
5a1e9937
LP
2791}
2792
07719a21 2793static void remove_generator_dir(Manager *m, char **generator) {
5a1e9937 2794 assert(m);
07719a21 2795 assert(generator);
5a1e9937 2796
07719a21 2797 if (!*generator)
5a1e9937
LP
2798 return;
2799
07719a21
LP
2800 strv_remove(m->lookup_paths.unit_path, *generator);
2801 rm_rf(*generator, false, true, false);
5a1e9937 2802
07719a21
LP
2803 free(*generator);
2804 *generator = NULL;
2805}
2806
2807void manager_undo_generators(Manager *m) {
2808 assert(m);
2809
2810 remove_generator_dir(m, &m->generator_unit_path);
2811 remove_generator_dir(m, &m->generator_unit_path_early);
2812 remove_generator_dir(m, &m->generator_unit_path_late);
5a1e9937
LP
2813}
2814
718db961
LP
2815int manager_environment_add(Manager *m, char **minus, char **plus) {
2816 char **a = NULL, **b = NULL, **l;
97d0e5f8 2817 assert(m);
bcd8e6d1 2818
718db961 2819 l = m->environment;
bcd8e6d1 2820
718db961
LP
2821 if (!strv_isempty(minus)) {
2822 a = strv_env_delete(l, 1, minus);
2823 if (!a)
2824 return -ENOMEM;
2825
2826 l = a;
2827 }
2828
2829 if (!strv_isempty(plus)) {
2830 b = strv_env_merge(2, l, plus);
aa9f8a30
AH
2831 if (!b) {
2832 strv_free(a);
718db961 2833 return -ENOMEM;
aa9f8a30 2834 }
bcd8e6d1 2835
718db961
LP
2836 l = b;
2837 }
2838
2839 if (m->environment != l)
2840 strv_free(m->environment);
2841 if (a != l)
2842 strv_free(a);
2843 if (b != l)
2844 strv_free(b);
2845
f069efb4
LP
2846 m->environment = l;
2847 manager_clean_environment(m);
2848 strv_sort(m->environment);
2849
97d0e5f8
UTL
2850 return 0;
2851}
2852
c93ff2e9
FC
2853int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
2854 int i;
2855
2856 assert(m);
2857
517d56b1 2858 for (i = 0; i < _RLIMIT_MAX; i++) {
07719a21
LP
2859 if (!default_rlimit[i])
2860 continue;
c93ff2e9 2861
07719a21
LP
2862 m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
2863 if (!m->rlimit[i])
2864 return -ENOMEM;
c93ff2e9
FC
2865 }
2866
2867 return 0;
2868}
2869
4cfa2c99 2870void manager_recheck_journal(Manager *m) {
f1dd0c3f
LP
2871 Unit *u;
2872
2873 assert(m);
2874
67445f4e 2875 if (m->running_as != SYSTEMD_SYSTEM)
f1dd0c3f
LP
2876 return;
2877
731a676c
LP
2878 u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
2879 if (u && SOCKET(u)->state != SOCKET_RUNNING) {
4cfa2c99 2880 log_close_journal();
731a676c 2881 return;
f1dd0c3f
LP
2882 }
2883
731a676c
LP
2884 u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
2885 if (u && SERVICE(u)->state != SERVICE_RUNNING) {
4cfa2c99 2886 log_close_journal();
731a676c
LP
2887 return;
2888 }
f1dd0c3f 2889
731a676c
LP
2890 /* Hmm, OK, so the socket is fully up and the service is up
2891 * too, then let's make use of the thing. */
f1dd0c3f
LP
2892 log_open();
2893}
2894
d450b6f2 2895void manager_set_show_status(Manager *m, ShowStatus mode) {
27d340c7 2896 assert(m);
d450b6f2 2897 assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY));
27d340c7 2898
67445f4e 2899 if (m->running_as != SYSTEMD_SYSTEM)
27d340c7
LP
2900 return;
2901
d450b6f2 2902 m->show_status = mode;
27d340c7 2903
d450b6f2 2904 if (mode > 0)
27d340c7
LP
2905 touch("/run/systemd/show-status");
2906 else
2907 unlink("/run/systemd/show-status");
2908}
2909
127d5fd1 2910static bool manager_get_show_status(Manager *m, StatusType type) {
27d340c7
LP
2911 assert(m);
2912
67445f4e 2913 if (m->running_as != SYSTEMD_SYSTEM)
27d340c7
LP
2914 return false;
2915
31a7eb86
ZJS
2916 if (m->no_console_output)
2917 return false;
2918
d81afec1 2919 if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
08510627
LP
2920 return false;
2921
e46b13c8 2922 /* If we cannot find out the status properly, just proceed. */
ebc5788e 2923 if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
e46b13c8
ZJS
2924 return false;
2925
d450b6f2 2926 if (m->show_status > 0)
27d340c7
LP
2927 return true;
2928
2929 /* If Plymouth is running make sure we show the status, so
2930 * that there's something nice to see when people press Esc */
27d340c7
LP
2931 return plymouth_running();
2932}
68b29a9f 2933
e2680723
LP
2934void manager_set_first_boot(Manager *m, bool b) {
2935 assert(m);
2936
2937 if (m->running_as != SYSTEMD_SYSTEM)
2938 return;
2939
2940 m->first_boot = b;
2941
2942 if (m->first_boot)
2943 touch("/run/systemd/first-boot");
2944 else
2945 unlink("/run/systemd/first-boot");
2946}
2947
127d5fd1 2948void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
25cee550
MS
2949 va_list ap;
2950
cb6531be
ZJS
2951 /* If m is NULL, assume we're after shutdown and let the messages through. */
2952
2953 if (m && !manager_get_show_status(m, type))
25cee550
MS
2954 return;
2955
03b717a3
MS
2956 /* XXX We should totally drop the check for ephemeral here
2957 * and thus effectively make 'Type=idle' pointless. */
cb6531be 2958 if (type == STATUS_TYPE_EPHEMERAL && m && m->n_on_console > 0)
03b717a3
MS
2959 return;
2960
25cee550 2961 va_start(ap, format);
127d5fd1 2962 status_vprintf(status, true, type == STATUS_TYPE_EPHEMERAL, format, ap);
25cee550
MS
2963 va_end(ap);
2964}
2965
a57f7e2c
LP
2966int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, Unit **_found) {
2967 _cleanup_free_ char *p = NULL;
2968 Unit *found;
2969
2970 assert(m);
2971 assert(path);
2972 assert(suffix);
2973 assert(_found);
2974
2975 p = unit_name_from_path(path, suffix);
2976 if (!p)
2977 return -ENOMEM;
2978
2979 found = manager_get_unit(m, p);
2980 if (!found) {
2981 *_found = NULL;
2982 return 0;
2983 }
2984
2985 *_found = found;
2986 return 1;
2987}
2988
2989Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
2990 char p[strlen(path)+1];
2991
2992 assert(m);
2993 assert(path);
2994
2995 strcpy(p, path);
2996 path_kill_slashes(p);
2997
2998 return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
2999}
e66cf1a3
LP
3000
3001const char *manager_get_runtime_prefix(Manager *m) {
f755e3b7 3002 assert(m);
e66cf1a3
LP
3003
3004 return m->running_as == SYSTEMD_SYSTEM ?
3005 "/run" :
3006 getenv("XDG_RUNTIME_DIR");
3007}
f755e3b7
LP
3008
3009ManagerState manager_state(Manager *m) {
3010 Unit *u;
3011
3012 assert(m);
3013
3014 /* Did we ever finish booting? If not then we are still starting up */
d81afec1
LP
3015 if (!dual_timestamp_is_set(&m->finish_timestamp)) {
3016
3017 u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
3018 if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
3019 return MANAGER_INITIALIZING;
3020
f755e3b7 3021 return MANAGER_STARTING;
d81afec1 3022 }
f755e3b7
LP
3023
3024 /* Is the special shutdown target queued? If so, we are in shutdown state */
3025 u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
3026 if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))
3027 return MANAGER_STOPPING;
3028
3029 /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
3030 u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
3031 if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
3032 (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
3033 return MANAGER_MAINTENANCE;
3034
3035 u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
3036 if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
3037 (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
3038 return MANAGER_MAINTENANCE;
3039
3040 /* Are there any failed units? If so, we are in degraded mode */
3041 if (set_size(m->failed_units) > 0)
3042 return MANAGER_DEGRADED;
3043
3044 return MANAGER_RUNNING;
3045}
3046
3047static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
d81afec1 3048 [MANAGER_INITIALIZING] = "initializing",
f755e3b7
LP
3049 [MANAGER_STARTING] = "starting",
3050 [MANAGER_RUNNING] = "running",
3051 [MANAGER_DEGRADED] = "degraded",
3052 [MANAGER_MAINTENANCE] = "maintenance",
3053 [MANAGER_STOPPING] = "stopping",
3054};
3055
3056DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);