]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/manager.c
util: make time formatting a bit smarter
[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
LP
25#include <sys/epoll.h>
26#include <signal.h>
27#include <sys/signalfd.h>
28#include <sys/wait.h>
29#include <unistd.h>
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
877d54e9
LP
45#include "systemd/sd-daemon.h"
46#include "systemd/sd-id128.h"
47#include "systemd/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"
8e274523
LP
58#include "cgroup.h"
59#include "mount-setup.h"
9e2f7c11 60#include "unit-name.h"
4139c1b2
LP
61#include "dbus-unit.h"
62#include "dbus-job.h"
1137a57c 63#include "missing.h"
84e3543e 64#include "path-lookup.h"
514f4ef5 65#include "special.h"
398ef8ba 66#include "bus-errors.h"
d06dacd0 67#include "exit-status.h"
5dc4c17f 68#include "virt.h"
e96d6be7 69#include "watchdog.h"
b59e2465 70#include "cgroup-util.h"
9eb977db 71#include "path-util.h"
c1165f82 72#include "audit-fd.h"
2e3d0692 73#include "efivars.h"
8b55b8c4 74#include "env-util.h"
60918275 75
701cc384
LP
76/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
77#define GC_QUEUE_ENTRIES_MAX 16
78
79/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
94b6dfa2 80#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
701cc384 81
03b717a3
MS
82/* Initial delay and the interval for printing status messages about running jobs */
83#define JOBS_IN_PROGRESS_WAIT_SEC 5
84#define JOBS_IN_PROGRESS_PERIOD_SEC 1
85#define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
86
8c47c732 87/* Where clients shall send notification messages to */
29252e9e 88#define NOTIFY_SOCKET "@/org/freedesktop/systemd1/notify"
8c47c732 89
c3e31c7b
ZJS
90#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
91
8c47c732
LP
92static int manager_setup_notify(Manager *m) {
93 union {
94 struct sockaddr sa;
95 struct sockaddr_un un;
96 } sa;
97 struct epoll_event ev;
e62d8c39 98 int one = 1, r;
8c47c732
LP
99
100 assert(m);
101
102 m->notify_watch.type = WATCH_NOTIFY;
29252e9e
LP
103 m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
104 if (m->notify_watch.fd < 0) {
8c47c732
LP
105 log_error("Failed to allocate notification socket: %m");
106 return -errno;
107 }
108
109 zero(sa);
110 sa.sa.sa_family = AF_UNIX;
111
31f92a7d 112 if (getpid() != 1 || detect_container(NULL) > 0)
29252e9e
LP
113 snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET "/%llu", random_ull());
114 else
115 strncpy(sa.un.sun_path, NOTIFY_SOCKET, sizeof(sa.un.sun_path));
8c47c732 116
29252e9e 117 sa.un.sun_path[0] = 0;
1d6702e8 118
e62d8c39
ZJS
119 r = bind(m->notify_watch.fd, &sa.sa,
120 offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
121 if (r < 0) {
8c47c732
LP
122 log_error("bind() failed: %m");
123 return -errno;
124 }
125
e62d8c39
ZJS
126 r = setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
127 if (r < 0) {
8c47c732
LP
128 log_error("SO_PASSCRED failed: %m");
129 return -errno;
130 }
131
132 zero(ev);
133 ev.events = EPOLLIN;
134 ev.data.ptr = &m->notify_watch;
135
e62d8c39
ZJS
136 r = epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev);
137 if (r < 0) {
28137202 138 log_error("Failed to add notification socket fd to epoll: %m");
8c47c732 139 return -errno;
8742514c 140 }
8c47c732 141
29252e9e
LP
142 sa.un.sun_path[0] = '@';
143 m->notify_socket = strdup(sa.un.sun_path);
144 if (!m->notify_socket)
8742514c 145 return log_oom();
8c47c732 146
b2bb3dbe
LP
147 log_debug("Using notification socket %s", m->notify_socket);
148
8c47c732
LP
149 return 0;
150}
151
03b717a3
MS
152static int manager_jobs_in_progress_mod_timer(Manager *m) {
153 struct itimerspec its;
154
5b176ee0
MS
155 if (m->jobs_in_progress_watch.type != WATCH_JOBS_IN_PROGRESS)
156 return 0;
157
03b717a3
MS
158 zero(its);
159
160 its.it_value.tv_sec = JOBS_IN_PROGRESS_WAIT_SEC;
161 its.it_interval.tv_sec = JOBS_IN_PROGRESS_PERIOD_SEC;
162
163 if (timerfd_settime(m->jobs_in_progress_watch.fd, 0, &its, NULL) < 0)
164 return -errno;
165
166 return 0;
167}
168
169static int manager_watch_jobs_in_progress(Manager *m) {
170 struct epoll_event ev;
171 int r;
172
173 assert(m);
174
175 if (m->jobs_in_progress_watch.type != WATCH_INVALID)
176 return 0;
177
178 m->jobs_in_progress_watch.type = WATCH_JOBS_IN_PROGRESS;
179 m->jobs_in_progress_watch.fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
180 if (m->jobs_in_progress_watch.fd < 0) {
181 log_error("Failed to create timerfd: %m");
182 r = -errno;
183 goto err;
184 }
185
186 r = manager_jobs_in_progress_mod_timer(m);
187 if (r < 0) {
188 log_error("Failed to set up timer for jobs progress watch: %s", strerror(-r));
189 goto err;
190 }
191
192 zero(ev);
193 ev.events = EPOLLIN;
194 ev.data.ptr = &m->jobs_in_progress_watch;
195
196 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->jobs_in_progress_watch.fd, &ev) < 0) {
197 log_error("Failed to add jobs progress timer fd to epoll: %m");
198 r = -errno;
199 goto err;
200 }
201
202 log_debug("Set up jobs progress timerfd.");
203
204 return 0;
205
206err:
207 if (m->jobs_in_progress_watch.fd >= 0)
208 close_nointr_nofail(m->jobs_in_progress_watch.fd);
209 watch_init(&m->jobs_in_progress_watch);
210 return r;
211}
212
213static void manager_unwatch_jobs_in_progress(Manager *m) {
214 if (m->jobs_in_progress_watch.type != WATCH_JOBS_IN_PROGRESS)
215 return;
216
217 assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, m->jobs_in_progress_watch.fd, NULL) >= 0);
218 close_nointr_nofail(m->jobs_in_progress_watch.fd);
219 watch_init(&m->jobs_in_progress_watch);
220 m->jobs_in_progress_iteration = 0;
221
222 log_debug("Closed jobs progress timerfd.");
223}
224
225#define CYLON_BUFFER_EXTRA (2*strlen(ANSI_RED_ON) + strlen(ANSI_HIGHLIGHT_RED_ON) + 2*strlen(ANSI_HIGHLIGHT_OFF))
226static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
227 char *p = buffer;
228
229 assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
230 assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
231
232 if (pos > 1) {
6282c859
MS
233 if (pos > 2)
234 p = mempset(p, ' ', pos-2);
5052495b 235 p = stpcpy(p, ANSI_RED_ON);
03b717a3
MS
236 *p++ = '*';
237 }
238
239 if (pos > 0 && pos <= width) {
5052495b 240 p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON);
03b717a3
MS
241 *p++ = '*';
242 }
243
5052495b 244 p = stpcpy(p, ANSI_HIGHLIGHT_OFF);
03b717a3
MS
245
246 if (pos < width) {
5052495b 247 p = stpcpy(p, ANSI_RED_ON);
03b717a3 248 *p++ = '*';
6282c859
MS
249 if (pos < width-1)
250 p = mempset(p, ' ', width-1-pos);
5052495b 251 p = stpcpy(p, ANSI_HIGHLIGHT_OFF);
03b717a3 252 }
03b717a3
MS
253}
254
255static void manager_print_jobs_in_progress(Manager *m) {
256 Iterator i;
257 Job *j;
258 char *job_of_n = NULL;
259 unsigned counter = 0, print_nr;
260 char cylon[6 + CYLON_BUFFER_EXTRA + 1];
261 unsigned cylon_pos;
262
263 print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
264
265 HASHMAP_FOREACH(j, m->jobs, i)
266 if (j->state == JOB_RUNNING && counter++ == print_nr)
267 break;
268
e970a72e
MS
269 /* m->n_running_jobs must be consistent with the contents of m->jobs,
270 * so the above loop must have succeeded in finding j. */
271 assert(counter == print_nr + 1);
5a82a91a 272
03b717a3
MS
273 cylon_pos = m->jobs_in_progress_iteration % 14;
274 if (cylon_pos >= 8)
275 cylon_pos = 14 - cylon_pos;
276 draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
277
278 if (m->n_running_jobs > 1)
279 if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
280 job_of_n = NULL;
281
282 manager_status_printf(m, true, cylon, "%sA %s job is running for %s",
283 strempty(job_of_n), job_type_to_string(j->type), unit_description(j->unit));
284 free(job_of_n);
285
286 m->jobs_in_progress_iteration++;
287}
288
8742514c
LP
289static int manager_setup_time_change(Manager *m) {
290 struct epoll_event ev;
291 struct itimerspec its;
292
293 assert(m);
294 assert(m->time_change_watch.type == WATCH_INVALID);
295
296 /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
297 * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
298
299 m->time_change_watch.type = WATCH_TIME_CHANGE;
300 m->time_change_watch.fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
301 if (m->time_change_watch.fd < 0) {
302 log_error("Failed to create timerfd: %m");
303 return -errno;
304 }
305
306 zero(its);
8a3a1704
LP
307
308 /* We only care for the cancellation event, hence we set the
309 * timeout to the latest possible value. */
d6a195a3
ZJS
310 assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
311 its.it_value.tv_sec = TIME_T_MAX;
8a3a1704 312
8742514c
LP
313 if (timerfd_settime(m->time_change_watch.fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
314 log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
315 close_nointr_nofail(m->time_change_watch.fd);
316 watch_init(&m->time_change_watch);
317 return 0;
318 }
319
320 zero(ev);
321 ev.events = EPOLLIN;
322 ev.data.ptr = &m->time_change_watch;
323
324 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->time_change_watch.fd, &ev) < 0) {
325 log_error("Failed to add timer change fd to epoll: %m");
326 return -errno;
327 }
328
329 log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
330
331 return 0;
332}
333
80876c20 334static int enable_special_signals(Manager *m) {
4466ee6a 335 int fd;
80876c20
LP
336
337 assert(m);
338
a41b539e 339 /* Enable that we get SIGINT on control-alt-del. In containers
c9999773
LP
340 * this will fail with EPERM (older) or EINVAL (newer), so
341 * ignore that. */
342 if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
80876c20
LP
343 log_warning("Failed to enable ctrl-alt-del handling: %m");
344
a41b539e
LP
345 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
346 if (fd < 0) {
347 /* Support systems without virtual console */
348 if (fd != -ENOENT)
349 log_warning("Failed to open /dev/tty0: %m");
350 } else {
80876c20
LP
351 /* Enable that we get SIGWINCH on kbrequest */
352 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
353 log_warning("Failed to enable kbrequest handling: %s", strerror(errno));
354
355 close_nointr_nofail(fd);
356 }
357
358 return 0;
359}
360
ce578209 361static int manager_setup_signals(Manager *m) {
9152c765
LP
362 sigset_t mask;
363 struct epoll_event ev;
57c0c30e 364 struct sigaction sa;
60918275 365
ce578209
LP
366 assert(m);
367
57c0c30e
LP
368 /* We are not interested in SIGSTOP and friends. */
369 zero(sa);
370 sa.sa_handler = SIG_DFL;
371 sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
372 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
373
ce578209 374 assert_se(sigemptyset(&mask) == 0);
7d793605
LP
375
376 sigset_add_many(&mask,
377 SIGCHLD, /* Child died */
378 SIGTERM, /* Reexecute daemon */
379 SIGHUP, /* Reload configuration */
380 SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
381 SIGUSR2, /* systemd: dump status */
382 SIGINT, /* Kernel sends us this on control-alt-del */
383 SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
384 SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
385 SIGRTMIN+0, /* systemd: start default.target */
0003d1ab 386 SIGRTMIN+1, /* systemd: isolate rescue.target */
7d793605
LP
387 SIGRTMIN+2, /* systemd: isolate emergency.target */
388 SIGRTMIN+3, /* systemd: start halt.target */
389 SIGRTMIN+4, /* systemd: start poweroff.target */
390 SIGRTMIN+5, /* systemd: start reboot.target */
0003d1ab
LP
391 SIGRTMIN+6, /* systemd: start kexec.target */
392 SIGRTMIN+13, /* systemd: Immediate halt */
393 SIGRTMIN+14, /* systemd: Immediate poweroff */
394 SIGRTMIN+15, /* systemd: Immediate reboot */
395 SIGRTMIN+16, /* systemd: Immediate kexec */
0658666b
LP
396 SIGRTMIN+20, /* systemd: enable status messages */
397 SIGRTMIN+21, /* systemd: disable status messages */
253ee27a
LP
398 SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
399 SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
600b704e 400 SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
4cfa2c99 401 SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
253ee27a
LP
402 SIGRTMIN+27, /* systemd: set log target to console */
403 SIGRTMIN+28, /* systemd: set log target to kmsg */
404 SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */
7d793605 405 -1);
ce578209
LP
406 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
407
ef734fd6 408 m->signal_watch.type = WATCH_SIGNAL;
8742514c
LP
409 m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
410 if (m->signal_watch.fd < 0)
ce578209
LP
411 return -errno;
412
413 zero(ev);
414 ev.events = EPOLLIN;
415 ev.data.ptr = &m->signal_watch;
416
417 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
418 return -errno;
419
67445f4e 420 if (m->running_as == SYSTEMD_SYSTEM)
80876c20 421 return enable_special_signals(m);
e1414003 422
ce578209
LP
423 return 0;
424}
425
71ecc858
LP
426static void manager_strip_environment(Manager *m) {
427 assert(m);
428
429 /* Remove variables from the inherited set that are part of
430 * the container interface:
431 * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */
432 strv_remove_prefix(m->environment, "container=");
433 strv_remove_prefix(m->environment, "container_");
434
435 /* Remove variables from the inherited set that are part of
436 * the initrd interface:
437 * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
438 strv_remove_prefix(m->environment, "RD_");
8b55b8c4
LP
439
440 /* Drop invalid entries */
441 strv_env_clean(m->environment);
71ecc858
LP
442}
443
67445f4e 444int manager_new(SystemdRunningAs running_as, Manager **_m) {
ce578209 445 Manager *m;
8e274523
LP
446 int r = -ENOMEM;
447
448 assert(_m);
a5dab5ce 449 assert(running_as >= 0);
67445f4e 450 assert(running_as < _SYSTEMD_RUNNING_AS_MAX);
ce578209 451
915b3753
LP
452 m = new0(Manager, 1);
453 if (!m)
8e274523 454 return -ENOMEM;
60918275 455
915b3753 456 dual_timestamp_get(&m->userspace_timestamp);
cae0c5e0 457 dual_timestamp_from_monotonic(&m->kernel_timestamp, 0);
b872e9a0 458#ifdef ENABLE_EFI
2e3d0692 459 efi_get_boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
b872e9a0 460#endif
e537352b 461
a5dab5ce 462 m->running_as = running_as;
cbd37330 463 m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
a16e1123 464 m->exit_code = _MANAGER_EXIT_CODE_INVALID;
33be102a 465 m->pin_cgroupfs_fd = -1;
f2b68789 466 m->idle_pipe[0] = m->idle_pipe[1] = -1;
80876c20 467
8742514c
LP
468 watch_init(&m->signal_watch);
469 watch_init(&m->mount_watch);
470 watch_init(&m->swap_watch);
471 watch_init(&m->udev_watch);
472 watch_init(&m->time_change_watch);
03b717a3 473 watch_init(&m->jobs_in_progress_watch);
8742514c
LP
474
475 m->epoll_fd = m->dev_autofs_fd = -1;
ea430986 476 m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
9152c765 477
71ecc858
LP
478 m->environment = strv_copy(environ);
479 if (!m->environment)
1137a57c
LP
480 goto fail;
481
71ecc858
LP
482 manager_strip_environment(m);
483
67445f4e 484 if (running_as == SYSTEMD_SYSTEM) {
88f06645
LP
485 m->default_controllers = strv_new("cpu", NULL);
486 if (!m->default_controllers)
487 goto fail;
488 }
06d4c99a 489
87f0e418 490 if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
60918275
LP
491 goto fail;
492
493 if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
494 goto fail;
495
9152c765
LP
496 if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func)))
497 goto fail;
498
8e274523
LP
499 if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func)))
500 goto fail;
501
05e343b7
LP
502 if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func)))
503 goto fail;
504
8742514c
LP
505 m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
506 if (m->epoll_fd < 0)
507 goto fail;
508
509 r = manager_setup_signals(m);
510 if (r < 0)
9152c765
LP
511 goto fail;
512
8742514c
LP
513 r = manager_setup_cgroup(m);
514 if (r < 0)
8e274523
LP
515 goto fail;
516
8742514c
LP
517 r = manager_setup_notify(m);
518 if (r < 0)
9152c765
LP
519 goto fail;
520
8742514c
LP
521 r = manager_setup_time_change(m);
522 if (r < 0)
8c47c732
LP
523 goto fail;
524
f278026d 525 /* Try to connect to the busses, if possible. */
8742514c
LP
526 r = bus_init(m, running_as != SYSTEMD_SYSTEM);
527 if (r < 0)
ea430986
LP
528 goto fail;
529
72bc8d00
LP
530 m->taint_usr = dir_is_empty("/usr") > 0;
531
8e274523
LP
532 *_m = m;
533 return 0;
60918275
LP
534
535fail:
536 manager_free(m);
8e274523 537 return r;
60918275
LP
538}
539
23a177ef 540static unsigned manager_dispatch_cleanup_queue(Manager *m) {
595ed347 541 Unit *u;
23a177ef
LP
542 unsigned n = 0;
543
544 assert(m);
545
595ed347
MS
546 while ((u = m->cleanup_queue)) {
547 assert(u->in_cleanup_queue);
23a177ef 548
595ed347 549 unit_free(u);
23a177ef
LP
550 n++;
551 }
552
553 return n;
554}
555
eced69b3 556enum {
35b8ca3a 557 GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
eced69b3
LP
558 GC_OFFSET_UNSURE, /* No clue */
559 GC_OFFSET_GOOD, /* We still need this unit */
560 GC_OFFSET_BAD, /* We don't need this unit anymore */
561 _GC_OFFSET_MAX
562};
563
564static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
701cc384
LP
565 Iterator i;
566 Unit *other;
eced69b3 567 bool is_bad;
701cc384
LP
568
569 assert(u);
570
ac155bb8
MS
571 if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
572 u->gc_marker == gc_marker + GC_OFFSET_BAD ||
573 u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
701cc384
LP
574 return;
575
ac155bb8 576 if (u->in_cleanup_queue)
701cc384
LP
577 goto bad;
578
579 if (unit_check_gc(u))
580 goto good;
581
ac155bb8 582 u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
eced69b3
LP
583
584 is_bad = true;
585
ac155bb8 586 SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
701cc384
LP
587 unit_gc_sweep(other, gc_marker);
588
ac155bb8 589 if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
701cc384 590 goto good;
eced69b3 591
ac155bb8 592 if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
eced69b3 593 is_bad = false;
701cc384
LP
594 }
595
eced69b3
LP
596 if (is_bad)
597 goto bad;
598
599 /* We were unable to find anything out about this entry, so
600 * let's investigate it later */
ac155bb8 601 u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
eced69b3
LP
602 unit_add_to_gc_queue(u);
603 return;
604
701cc384 605bad:
eced69b3
LP
606 /* We definitely know that this one is not useful anymore, so
607 * let's mark it for deletion */
ac155bb8 608 u->gc_marker = gc_marker + GC_OFFSET_BAD;
eced69b3 609 unit_add_to_cleanup_queue(u);
701cc384
LP
610 return;
611
612good:
ac155bb8 613 u->gc_marker = gc_marker + GC_OFFSET_GOOD;
701cc384
LP
614}
615
616static unsigned manager_dispatch_gc_queue(Manager *m) {
595ed347 617 Unit *u;
701cc384 618 unsigned n = 0;
eced69b3 619 unsigned gc_marker;
701cc384
LP
620
621 assert(m);
622
623 if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) &&
624 (m->gc_queue_timestamp <= 0 ||
625 (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC)))
626 return 0;
627
628 log_debug("Running GC...");
629
eced69b3
LP
630 m->gc_marker += _GC_OFFSET_MAX;
631 if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
c9c0cadb 632 m->gc_marker = 1;
701cc384 633
eced69b3
LP
634 gc_marker = m->gc_marker;
635
595ed347
MS
636 while ((u = m->gc_queue)) {
637 assert(u->in_gc_queue);
701cc384 638
595ed347 639 unit_gc_sweep(u, gc_marker);
eced69b3 640
595ed347
MS
641 LIST_REMOVE(Unit, gc_queue, m->gc_queue, u);
642 u->in_gc_queue = false;
701cc384
LP
643
644 n++;
645
595ed347
MS
646 if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
647 u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
66870f90 648 log_debug_unit(u->id, "Collecting %s", u->id);
595ed347
MS
649 u->gc_marker = gc_marker + GC_OFFSET_BAD;
650 unit_add_to_cleanup_queue(u);
701cc384
LP
651 }
652 }
653
654 m->n_in_gc_queue = 0;
655 m->gc_queue_timestamp = 0;
656
657 return n;
658}
659
a16e1123 660static void manager_clear_jobs_and_units(Manager *m) {
a16e1123 661 Unit *u;
60918275
LP
662
663 assert(m);
664
87f0e418
LP
665 while ((u = hashmap_first(m->units)))
666 unit_free(u);
964e0949
LP
667
668 manager_dispatch_cleanup_queue(m);
669
670 assert(!m->load_queue);
671 assert(!m->run_queue);
672 assert(!m->dbus_unit_queue);
673 assert(!m->dbus_job_queue);
674 assert(!m->cleanup_queue);
675 assert(!m->gc_queue);
676
964e0949
LP
677 assert(hashmap_isempty(m->jobs));
678 assert(hashmap_isempty(m->units));
9e9e2b72
MS
679
680 m->n_on_console = 0;
681 m->n_running_jobs = 0;
a16e1123
LP
682}
683
684void manager_free(Manager *m) {
685 UnitType c;
c93ff2e9 686 int i;
87f0e418 687
a16e1123
LP
688 assert(m);
689
690 manager_clear_jobs_and_units(m);
23a177ef 691
7824bbeb
LP
692 for (c = 0; c < _UNIT_TYPE_MAX; c++)
693 if (unit_vtable[c]->shutdown)
694 unit_vtable[c]->shutdown(m);
695
a16e1123
LP
696 /* If we reexecute ourselves, we keep the root cgroup
697 * around */
c6c18be3 698 manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
8e274523 699
5a1e9937
LP
700 manager_undo_generators(m);
701
5e8d1c9a 702 bus_done(m);
ea430986 703
87f0e418 704 hashmap_free(m->units);
60918275 705 hashmap_free(m->jobs);
9152c765 706 hashmap_free(m->watch_pids);
05e343b7 707 hashmap_free(m->watch_bus);
9152c765
LP
708
709 if (m->epoll_fd >= 0)
a16e1123 710 close_nointr_nofail(m->epoll_fd);
acbb0225 711 if (m->signal_watch.fd >= 0)
a16e1123 712 close_nointr_nofail(m->signal_watch.fd);
8c47c732
LP
713 if (m->notify_watch.fd >= 0)
714 close_nointr_nofail(m->notify_watch.fd);
8742514c
LP
715 if (m->time_change_watch.fd >= 0)
716 close_nointr_nofail(m->time_change_watch.fd);
03b717a3
MS
717 if (m->jobs_in_progress_watch.fd >= 0)
718 close_nointr_nofail(m->jobs_in_progress_watch.fd);
60918275 719
c952c6ec
LP
720 free(m->notify_socket);
721
84e3543e 722 lookup_paths_free(&m->lookup_paths);
1137a57c 723 strv_free(m->environment);
036643a2 724
06d4c99a
LP
725 strv_free(m->default_controllers);
726
8e274523 727 hashmap_free(m->cgroup_bondings);
c6c18be3 728 set_free_free(m->unit_path_cache);
33be102a 729
f2b68789
LP
730 close_pipe(m->idle_pipe);
731
664f88a7
LP
732 free(m->switch_root);
733 free(m->switch_root_init);
734
c93ff2e9
FC
735 for (i = 0; i < RLIMIT_NLIMITS; i++)
736 free(m->rlimit[i]);
737
60918275
LP
738 free(m);
739}
740
a16e1123
LP
741int manager_enumerate(Manager *m) {
742 int r = 0, q;
f50e0a01 743 UnitType c;
f50e0a01
LP
744
745 assert(m);
746
a16e1123
LP
747 /* Let's ask every type to load all units from disk/kernel
748 * that it might know */
f50e0a01
LP
749 for (c = 0; c < _UNIT_TYPE_MAX; c++)
750 if (unit_vtable[c]->enumerate)
a16e1123
LP
751 if ((q = unit_vtable[c]->enumerate(m)) < 0)
752 r = q;
f50e0a01
LP
753
754 manager_dispatch_load_queue(m);
a16e1123
LP
755 return r;
756}
757
758int manager_coldplug(Manager *m) {
759 int r = 0, q;
760 Iterator i;
761 Unit *u;
762 char *k;
763
764 assert(m);
f50e0a01
LP
765
766 /* Then, let's set up their initial state. */
767 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
768
769 /* ignore aliases */
ac155bb8 770 if (u->id != k)
f50e0a01
LP
771 continue;
772
cca098b0
LP
773 if ((q = unit_coldplug(u)) < 0)
774 r = q;
f50e0a01
LP
775 }
776
a16e1123
LP
777 return r;
778}
779
fe51822e
LP
780static void manager_build_unit_path_cache(Manager *m) {
781 char **i;
874310b7 782 DIR _cleanup_free_ *d = NULL;
fe51822e
LP
783 int r;
784
785 assert(m);
786
787 set_free_free(m->unit_path_cache);
788
874310b7
ZJS
789 m->unit_path_cache = set_new(string_hash_func, string_compare_func);
790 if (!m->unit_path_cache) {
fe51822e
LP
791 log_error("Failed to allocate unit path cache.");
792 return;
793 }
794
795 /* This simply builds a list of files we know exist, so that
796 * we don't always have to go to disk */
797
798 STRV_FOREACH(i, m->lookup_paths.unit_path) {
799 struct dirent *de;
800
bd0af849
ZJS
801 d = opendir(*i);
802 if (!d) {
874310b7
ZJS
803 if (errno != ENOENT)
804 log_error("Failed to open directory %s: %m", *i);
fe51822e
LP
805 continue;
806 }
807
808 while ((de = readdir(d))) {
809 char *p;
810
811 if (ignore_file(de->d_name))
812 continue;
813
b7def684 814 p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
44d91056 815 if (!p) {
fe51822e
LP
816 r = -ENOMEM;
817 goto fail;
818 }
819
874310b7
ZJS
820 r = set_put(m->unit_path_cache, p);
821 if (r < 0) {
fe51822e
LP
822 free(p);
823 goto fail;
824 }
825 }
826
827 closedir(d);
828 d = NULL;
829 }
830
831 return;
832
833fail:
834 log_error("Failed to build unit path cache: %s", strerror(-r));
835
836 set_free_free(m->unit_path_cache);
837 m->unit_path_cache = NULL;
fe51822e
LP
838}
839
a16e1123
LP
840int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
841 int r, q;
842
843 assert(m);
844
5a1e9937
LP
845 manager_run_generators(m);
846
07719a21
LP
847 r = lookup_paths_init(
848 &m->lookup_paths, m->running_as, true,
849 m->generator_unit_path,
850 m->generator_unit_path_early,
851 m->generator_unit_path_late);
852 if (r < 0)
853 return r;
854
fe51822e
LP
855 manager_build_unit_path_cache(m);
856
9f611ad8
LP
857 /* If we will deserialize make sure that during enumeration
858 * this is already known, so we increase the counter here
859 * already */
860 if (serialization)
a7556052 861 m->n_reloading ++;
9f611ad8 862
a16e1123
LP
863 /* First, enumerate what we can from all config files */
864 r = manager_enumerate(m);
865
866 /* Second, deserialize if there is something to deserialize */
07719a21
LP
867 if (serialization) {
868 q = manager_deserialize(m, serialization, fds);
869 if (q < 0)
a16e1123 870 r = q;
07719a21 871 }
a16e1123 872
01e10de3
LP
873 /* Any fds left? Find some unit which wants them. This is
874 * useful to allow container managers to pass some file
875 * descriptors to us pre-initialized. This enables
876 * socket-based activation of entire containers. */
877 if (fdset_size(fds) > 0) {
878 q = manager_distribute_fds(m, fds);
879 if (q < 0)
880 r = q;
881 }
882
a16e1123 883 /* Third, fire things up! */
07719a21
LP
884 q = manager_coldplug(m);
885 if (q < 0)
a16e1123
LP
886 r = q;
887
9f611ad8 888 if (serialization) {
a7556052
LP
889 assert(m->n_reloading > 0);
890 m->n_reloading --;
9f611ad8
LP
891 }
892
a16e1123 893 return r;
f50e0a01
LP
894}
895
398ef8ba 896int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) {
e5b5ae50 897 int r;
7527cb52 898 Transaction *tr;
e5b5ae50
LP
899
900 assert(m);
901 assert(type < _JOB_TYPE_MAX);
87f0e418 902 assert(unit);
e5b5ae50 903 assert(mode < _JOB_MODE_MAX);
60918275 904
398ef8ba
LP
905 if (mode == JOB_ISOLATE && type != JOB_START) {
906 dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start.");
c497c7a9 907 return -EINVAL;
398ef8ba 908 }
c497c7a9 909
ac155bb8 910 if (mode == JOB_ISOLATE && !unit->allow_isolate) {
2528a7a6
LP
911 dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
912 return -EPERM;
913 }
914
66870f90
ZJS
915 log_debug_unit(unit->id,
916 "Trying to enqueue job %s/%s/%s", unit->id,
917 job_type_to_string(type), job_mode_to_string(mode));
9f04bd52 918
e0209d83
MS
919 job_type_collapse(&type, unit);
920
23ade460 921 tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
7527cb52
MS
922 if (!tr)
923 return -ENOMEM;
11dd41ce 924
7527cb52
MS
925 r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
926 mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
b94fbd30 927 mode == JOB_IGNORE_DEPENDENCIES, e);
7527cb52
MS
928 if (r < 0)
929 goto tr_abort;
c497c7a9 930
7527cb52
MS
931 if (mode == JOB_ISOLATE) {
932 r = transaction_add_isolate_jobs(tr, m);
933 if (r < 0)
934 goto tr_abort;
935 }
936
937 r = transaction_activate(tr, m, mode, e);
938 if (r < 0)
939 goto tr_abort;
e5b5ae50 940
66870f90
ZJS
941 log_debug_unit(unit->id,
942 "Enqueued job %s/%s as %u", unit->id,
943 job_type_to_string(type), (unsigned) tr->anchor_job->id);
f50e0a01 944
e5b5ae50 945 if (_ret)
b94fbd30 946 *_ret = tr->anchor_job;
60918275 947
7527cb52 948 transaction_free(tr);
e5b5ae50 949 return 0;
7527cb52
MS
950
951tr_abort:
952 transaction_abort(tr);
953 transaction_free(tr);
954 return r;
e5b5ae50 955}
60918275 956
398ef8ba 957int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) {
28247076
LP
958 Unit *unit;
959 int r;
960
961 assert(m);
962 assert(type < _JOB_TYPE_MAX);
963 assert(name);
964 assert(mode < _JOB_MODE_MAX);
965
c3090674
LP
966 r = manager_load_unit(m, name, NULL, NULL, &unit);
967 if (r < 0)
28247076
LP
968 return r;
969
398ef8ba 970 return manager_add_job(m, type, unit, mode, override, e, _ret);
28247076
LP
971}
972
60918275
LP
973Job *manager_get_job(Manager *m, uint32_t id) {
974 assert(m);
975
976 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
977}
978
87f0e418 979Unit *manager_get_unit(Manager *m, const char *name) {
60918275
LP
980 assert(m);
981 assert(name);
982
87f0e418 983 return hashmap_get(m->units, name);
60918275
LP
984}
985
c1e1601e 986unsigned manager_dispatch_load_queue(Manager *m) {
595ed347 987 Unit *u;
c1e1601e 988 unsigned n = 0;
60918275
LP
989
990 assert(m);
991
223dabab
LP
992 /* Make sure we are not run recursively */
993 if (m->dispatching_load_queue)
c1e1601e 994 return 0;
223dabab
LP
995
996 m->dispatching_load_queue = true;
997
87f0e418 998 /* Dispatches the load queue. Takes a unit from the queue and
60918275
LP
999 * tries to load its data until the queue is empty */
1000
595ed347
MS
1001 while ((u = m->load_queue)) {
1002 assert(u->in_load_queue);
034c6ed7 1003
595ed347 1004 unit_load(u);
c1e1601e 1005 n++;
60918275
LP
1006 }
1007
223dabab 1008 m->dispatching_load_queue = false;
c1e1601e 1009 return n;
60918275
LP
1010}
1011
398ef8ba 1012int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
87f0e418 1013 Unit *ret;
7d17cfbc 1014 UnitType t;
60918275
LP
1015 int r;
1016
1017 assert(m);
9e2f7c11 1018 assert(name || path);
60918275 1019
db06e3b6
LP
1020 /* This will prepare the unit for loading, but not actually
1021 * load anything from disk. */
0301abf4 1022
398ef8ba
LP
1023 if (path && !is_path(path)) {
1024 dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path);
9e2f7c11 1025 return -EINVAL;
398ef8ba 1026 }
9e2f7c11
LP
1027
1028 if (!name)
9eb977db 1029 name = path_get_file_name(path);
9e2f7c11 1030
7d17cfbc
MS
1031 t = unit_name_to_type(name);
1032
5f739699 1033 if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, false)) {
398ef8ba 1034 dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
9e2f7c11 1035 return -EINVAL;
398ef8ba 1036 }
60918275 1037
7d17cfbc
MS
1038 ret = manager_get_unit(m, name);
1039 if (ret) {
034c6ed7 1040 *_ret = ret;
413d6313 1041 return 1;
034c6ed7 1042 }
60918275 1043
7d17cfbc
MS
1044 ret = unit_new(m, unit_vtable[t]->object_size);
1045 if (!ret)
60918275
LP
1046 return -ENOMEM;
1047
7d17cfbc 1048 if (path) {
ac155bb8
MS
1049 ret->fragment_path = strdup(path);
1050 if (!ret->fragment_path) {
0301abf4
LP
1051 unit_free(ret);
1052 return -ENOMEM;
1053 }
7d17cfbc 1054 }
0301abf4 1055
87f0e418
LP
1056 if ((r = unit_add_name(ret, name)) < 0) {
1057 unit_free(ret);
1ffba6fe 1058 return r;
60918275
LP
1059 }
1060
87f0e418 1061 unit_add_to_load_queue(ret);
c1e1601e 1062 unit_add_to_dbus_queue(ret);
949061f0 1063 unit_add_to_gc_queue(ret);
c1e1601e 1064
db06e3b6
LP
1065 if (_ret)
1066 *_ret = ret;
1067
1068 return 0;
1069}
1070
398ef8ba 1071int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
db06e3b6
LP
1072 int r;
1073
1074 assert(m);
1075
1076 /* This will load the service information files, but not actually
1077 * start any services or anything. */
1078
c3090674
LP
1079 r = manager_load_unit_prepare(m, name, path, e, _ret);
1080 if (r != 0)
db06e3b6
LP
1081 return r;
1082
f50e0a01 1083 manager_dispatch_load_queue(m);
60918275 1084
9e2f7c11 1085 if (_ret)
413d6313 1086 *_ret = unit_follow_merge(*_ret);
9e2f7c11 1087
60918275
LP
1088 return 0;
1089}
a66d02c3 1090
cea8e32e 1091void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1092 Iterator i;
a66d02c3
LP
1093 Job *j;
1094
1095 assert(s);
1096 assert(f);
1097
034c6ed7 1098 HASHMAP_FOREACH(j, s->jobs, i)
cea8e32e 1099 job_dump(j, f, prefix);
a66d02c3
LP
1100}
1101
87f0e418 1102void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
034c6ed7 1103 Iterator i;
87f0e418 1104 Unit *u;
11dd41ce 1105 const char *t;
a66d02c3
LP
1106
1107 assert(s);
1108 assert(f);
1109
87f0e418 1110 HASHMAP_FOREACH_KEY(u, t, s->units, i)
ac155bb8 1111 if (u->id == t)
87f0e418 1112 unit_dump(u, f, prefix);
a66d02c3 1113}
7fad411c
LP
1114
1115void manager_clear_jobs(Manager *m) {
1116 Job *j;
1117
1118 assert(m);
1119
7fad411c 1120 while ((j = hashmap_first(m->jobs)))
5273510e
MS
1121 /* No need to recurse. We're cancelling all jobs. */
1122 job_finish_and_invalidate(j, JOB_CANCELED, false);
7fad411c 1123}
83c60c9f 1124
c1e1601e 1125unsigned manager_dispatch_run_queue(Manager *m) {
83c60c9f 1126 Job *j;
c1e1601e 1127 unsigned n = 0;
83c60c9f 1128
034c6ed7 1129 if (m->dispatching_run_queue)
c1e1601e 1130 return 0;
034c6ed7
LP
1131
1132 m->dispatching_run_queue = true;
9152c765 1133
034c6ed7 1134 while ((j = m->run_queue)) {
ac1135be 1135 assert(j->installed);
034c6ed7
LP
1136 assert(j->in_run_queue);
1137
1138 job_run_and_invalidate(j);
c1e1601e 1139 n++;
9152c765 1140 }
034c6ed7
LP
1141
1142 m->dispatching_run_queue = false;
03b717a3 1143
a0b64226 1144 if (m->n_running_jobs > 0)
03b717a3
MS
1145 manager_watch_jobs_in_progress(m);
1146
c1e1601e
LP
1147 return n;
1148}
1149
1150unsigned manager_dispatch_dbus_queue(Manager *m) {
1151 Job *j;
595ed347 1152 Unit *u;
c1e1601e
LP
1153 unsigned n = 0;
1154
1155 assert(m);
1156
1157 if (m->dispatching_dbus_queue)
1158 return 0;
1159
1160 m->dispatching_dbus_queue = true;
1161
595ed347
MS
1162 while ((u = m->dbus_unit_queue)) {
1163 assert(u->in_dbus_queue);
c1e1601e 1164
595ed347 1165 bus_unit_send_change_signal(u);
c1e1601e
LP
1166 n++;
1167 }
1168
1169 while ((j = m->dbus_job_queue)) {
1170 assert(j->in_dbus_queue);
1171
1172 bus_job_send_change_signal(j);
1173 n++;
1174 }
1175
1176 m->dispatching_dbus_queue = false;
1177 return n;
9152c765
LP
1178}
1179
8c47c732
LP
1180static int manager_process_notify_fd(Manager *m) {
1181 ssize_t n;
1182
1183 assert(m);
1184
1185 for (;;) {
1186 char buf[4096];
1187 struct msghdr msghdr;
1188 struct iovec iovec;
1189 struct ucred *ucred;
1190 union {
1191 struct cmsghdr cmsghdr;
1192 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
1193 } control;
1194 Unit *u;
e62d8c39 1195 char _cleanup_strv_free_ **tags = NULL;
8c47c732
LP
1196
1197 zero(iovec);
1198 iovec.iov_base = buf;
1199 iovec.iov_len = sizeof(buf)-1;
1200
1201 zero(control);
1202 zero(msghdr);
1203 msghdr.msg_iov = &iovec;
1204 msghdr.msg_iovlen = 1;
1205 msghdr.msg_control = &control;
1206 msghdr.msg_controllen = sizeof(control);
1207
bd0af849
ZJS
1208 n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT);
1209 if (n <= 0) {
8c47c732
LP
1210 if (n >= 0)
1211 return -EIO;
1212
f6144808 1213 if (errno == EAGAIN || errno == EINTR)
8c47c732
LP
1214 break;
1215
1216 return -errno;
1217 }
1218
1219 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
1220 control.cmsghdr.cmsg_level != SOL_SOCKET ||
1221 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
1222 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
1223 log_warning("Received notify message without credentials. Ignoring.");
1224 continue;
1225 }
1226
1227 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
1228
bd0af849
ZJS
1229 u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid));
1230 if (!u) {
1231 u = cgroup_unit_by_pid(m, ucred->pid);
1232 if (!u) {
7989e1f2 1233 log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid);
8c47c732
LP
1234 continue;
1235 }
bd0af849 1236 }
8c47c732 1237
8c40acf7
LP
1238 assert((size_t) n < sizeof(buf));
1239 buf[n] = 0;
bd0af849
ZJS
1240 tags = strv_split(buf, "\n\r");
1241 if (!tags)
1242 return log_oom();
8c47c732 1243
66870f90 1244 log_debug_unit(u->id, "Got notification message for unit %s", u->id);
8c47c732
LP
1245
1246 if (UNIT_VTABLE(u)->notify_message)
c952c6ec 1247 UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
8c47c732
LP
1248 }
1249
1250 return 0;
1251}
1252
034c6ed7 1253static int manager_dispatch_sigchld(Manager *m) {
9152c765
LP
1254 assert(m);
1255
1256 for (;;) {
1257 siginfo_t si;
87f0e418 1258 Unit *u;
8c47c732 1259 int r;
9152c765
LP
1260
1261 zero(si);
4112df16
LP
1262
1263 /* First we call waitd() for a PID and do not reap the
1264 * zombie. That way we can still access /proc/$PID for
1265 * it while it is a zombie. */
1266 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
acbb0225
LP
1267
1268 if (errno == ECHILD)
1269 break;
1270
4112df16
LP
1271 if (errno == EINTR)
1272 continue;
1273
9152c765 1274 return -errno;
acbb0225 1275 }
9152c765 1276
4112df16 1277 if (si.si_pid <= 0)
9152c765
LP
1278 break;
1279
15d5d9d9 1280 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
bd0af849 1281 char _cleanup_free_ *name = NULL;
4112df16 1282
87d2c1ff 1283 get_process_comm(si.si_pid, &name);
bb00e604 1284 log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
4112df16
LP
1285 }
1286
8c47c732
LP
1287 /* Let's flush any message the dying child might still
1288 * have queued for us. This ensures that the process
1289 * still exists in /proc so that we can figure out
1290 * which cgroup and hence unit it belongs to. */
bd0af849
ZJS
1291 r = manager_process_notify_fd(m);
1292 if (r < 0)
8c47c732
LP
1293 return r;
1294
1295 /* And now figure out the unit this belongs to */
bd0af849
ZJS
1296 u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid));
1297 if (!u)
8c47c732
LP
1298 u = cgroup_unit_by_pid(m, si.si_pid);
1299
4112df16
LP
1300 /* And now, we actually reap the zombie. */
1301 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
1302 if (errno == EINTR)
1303 continue;
1304
1305 return -errno;
1306 }
1307
034c6ed7
LP
1308 if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
1309 continue;
1310
bb00e604
LP
1311 log_debug("Child %lu died (code=%s, status=%i/%s)",
1312 (long unsigned) si.si_pid,
4112df16
LP
1313 sigchld_code_to_string(si.si_code),
1314 si.si_status,
d06dacd0
LP
1315 strna(si.si_code == CLD_EXITED
1316 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
1317 : signal_to_string(si.si_status)));
acbb0225 1318
8c47c732 1319 if (!u)
9152c765
LP
1320 continue;
1321
66870f90
ZJS
1322 log_debug_unit(u->id,
1323 "Child %lu belongs to %s", (long unsigned) si.si_pid, u->id);
6c1a0478 1324
c6c18be3 1325 hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid));
87f0e418 1326 UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
9152c765
LP
1327 }
1328
1329 return 0;
1330}
1331
7d793605 1332static int manager_start_target(Manager *m, const char *name, JobMode mode) {
28247076 1333 int r;
398ef8ba
LP
1334 DBusError error;
1335
1336 dbus_error_init(&error);
1337
66870f90 1338 log_debug_unit(name, "Activating special unit %s", name);
1e001f52 1339
bd0af849
ZJS
1340 r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL);
1341 if (r < 0)
66870f90
ZJS
1342 log_error_unit(name,
1343 "Failed to enqueue %s job: %s", name, bus_error(&error, r));
28247076 1344
398ef8ba 1345 dbus_error_free(&error);
a1b256b0
LP
1346
1347 return r;
28247076
LP
1348}
1349
a16e1123 1350static int manager_process_signal_fd(Manager *m) {
9152c765
LP
1351 ssize_t n;
1352 struct signalfd_siginfo sfsi;
1353 bool sigchld = false;
1354
1355 assert(m);
1356
1357 for (;;) {
57cb4adf
LP
1358 n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi));
1359 if (n != sizeof(sfsi)) {
9152c765
LP
1360
1361 if (n >= 0)
1362 return -EIO;
1363
63090775 1364 if (errno == EINTR || errno == EAGAIN)
acbb0225 1365 break;
9152c765
LP
1366
1367 return -errno;
1368 }
1369
67370238
LP
1370 if (sfsi.ssi_pid > 0) {
1371 char *p = NULL;
1372
87d2c1ff 1373 get_process_comm(sfsi.ssi_pid, &p);
dfa7f7e1 1374
67370238 1375 log_debug("Received SIG%s from PID %lu (%s).",
4e240ab0 1376 signal_to_string(sfsi.ssi_signo),
67370238
LP
1377 (unsigned long) sfsi.ssi_pid, strna(p));
1378 free(p);
1379 } else
4e240ab0 1380 log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo));
1e001f52 1381
b9cd2ec1
LP
1382 switch (sfsi.ssi_signo) {
1383
4112df16 1384 case SIGCHLD:
9152c765 1385 sigchld = true;
b9cd2ec1
LP
1386 break;
1387
6632c602 1388 case SIGTERM:
67445f4e 1389 if (m->running_as == SYSTEMD_SYSTEM) {
db06e3b6
LP
1390 /* This is for compatibility with the
1391 * original sysvinit */
e11dc4a2 1392 m->exit_code = MANAGER_REEXECUTE;
a1b256b0
LP
1393 break;
1394 }
84e9af1e 1395
a1b256b0 1396 /* Fall through */
e11dc4a2
LP
1397
1398 case SIGINT:
67445f4e 1399 if (m->running_as == SYSTEMD_SYSTEM) {
7d793605 1400 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
84e9af1e
LP
1401 break;
1402 }
1403
a1b256b0 1404 /* Run the exit target if there is one, if not, just exit. */
0003d1ab 1405 if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
a1b256b0
LP
1406 m->exit_code = MANAGER_EXIT;
1407 return 0;
1408 }
1409
1410 break;
84e9af1e 1411
28247076 1412 case SIGWINCH:
67445f4e 1413 if (m->running_as == SYSTEMD_SYSTEM)
7d793605 1414 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
84e9af1e 1415
28247076
LP
1416 /* This is a nop on non-init */
1417 break;
84e9af1e 1418
28247076 1419 case SIGPWR:
67445f4e 1420 if (m->running_as == SYSTEMD_SYSTEM)
7d793605 1421 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
84e9af1e 1422
28247076 1423 /* This is a nop on non-init */
84e9af1e 1424 break;
6632c602 1425
1005d14f 1426 case SIGUSR1: {
57ee42ce
LP
1427 Unit *u;
1428
1429 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
1430
1431 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
1432 log_info("Trying to reconnect to bus...");
3996fbe2 1433 bus_init(m, true);
57ee42ce
LP
1434 }
1435
1436 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
1437 log_info("Loading D-Bus service...");
7d793605 1438 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
57ee42ce
LP
1439 }
1440
1441 break;
1442 }
1443
2149e37c
LP
1444 case SIGUSR2: {
1445 FILE *f;
1446 char *dump = NULL;
1447 size_t size;
1448
1449 if (!(f = open_memstream(&dump, &size))) {
1450 log_warning("Failed to allocate memory stream.");
1451 break;
1452 }
1453
1454 manager_dump_units(m, f, "\t");
1455 manager_dump_jobs(m, f, "\t");
1456
1457 if (ferror(f)) {
1458 fclose(f);
1459 free(dump);
1460 log_warning("Failed to write status stream");
1461 break;
1462 }
1463
1464 fclose(f);
1465 log_dump(LOG_INFO, dump);
1466 free(dump);
1467
1005d14f 1468 break;
2149e37c 1469 }
1005d14f 1470
a16e1123
LP
1471 case SIGHUP:
1472 m->exit_code = MANAGER_RELOAD;
1473 break;
1474
7d793605 1475 default: {
253ee27a 1476
0003d1ab
LP
1477 /* Starting SIGRTMIN+0 */
1478 static const char * const target_table[] = {
7d793605
LP
1479 [0] = SPECIAL_DEFAULT_TARGET,
1480 [1] = SPECIAL_RESCUE_TARGET,
f057408c 1481 [2] = SPECIAL_EMERGENCY_TARGET,
7d793605
LP
1482 [3] = SPECIAL_HALT_TARGET,
1483 [4] = SPECIAL_POWEROFF_TARGET,
0003d1ab
LP
1484 [5] = SPECIAL_REBOOT_TARGET,
1485 [6] = SPECIAL_KEXEC_TARGET
1486 };
1487
1488 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
1489 static const ManagerExitCode code_table[] = {
1490 [0] = MANAGER_HALT,
1491 [1] = MANAGER_POWEROFF,
1492 [2] = MANAGER_REBOOT,
1493 [3] = MANAGER_KEXEC
7d793605
LP
1494 };
1495
1496 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
0003d1ab 1497 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
764e9b5f
MS
1498 int idx = (int) sfsi.ssi_signo - SIGRTMIN;
1499 manager_start_target(m, target_table[idx],
1500 (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
7d793605
LP
1501 break;
1502 }
1503
0003d1ab
LP
1504 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
1505 (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
1506 m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
1507 break;
1508 }
1509
0658666b
LP
1510 switch (sfsi.ssi_signo - SIGRTMIN) {
1511
1512 case 20:
1513 log_debug("Enabling showing of status.");
27d340c7 1514 manager_set_show_status(m, true);
0658666b
LP
1515 break;
1516
1517 case 21:
1518 log_debug("Disabling showing of status.");
27d340c7 1519 manager_set_show_status(m, false);
0658666b
LP
1520 break;
1521
253ee27a
LP
1522 case 22:
1523 log_set_max_level(LOG_DEBUG);
1524 log_notice("Setting log level to debug.");
1525 break;
1526
1527 case 23:
1528 log_set_max_level(LOG_INFO);
1529 log_notice("Setting log level to info.");
1530 break;
1531
600b704e
LP
1532 case 24:
1533 if (m->running_as == SYSTEMD_USER) {
1534 m->exit_code = MANAGER_EXIT;
1535 return 0;
1536 }
1537
1538 /* This is a nop on init */
1539 break;
1540
4cfa2c99
LP
1541 case 26:
1542 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1543 log_notice("Setting log target to journal-or-kmsg.");
1544 break;
1545
253ee27a
LP
1546 case 27:
1547 log_set_target(LOG_TARGET_CONSOLE);
1548 log_notice("Setting log target to console.");
1549 break;
1550
1551 case 28:
1552 log_set_target(LOG_TARGET_KMSG);
1553 log_notice("Setting log target to kmsg.");
1554 break;
1555
1556 case 29:
1557 log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
1558 log_notice("Setting log target to syslog-or-kmsg.");
1559 break;
1560
0658666b 1561 default:
4e240ab0 1562 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
0658666b 1563 }
b9cd2ec1 1564 }
7d793605 1565 }
9152c765
LP
1566 }
1567
1568 if (sigchld)
034c6ed7
LP
1569 return manager_dispatch_sigchld(m);
1570
1571 return 0;
1572}
1573
a16e1123 1574static int process_event(Manager *m, struct epoll_event *ev) {
034c6ed7 1575 int r;
acbb0225 1576 Watch *w;
034c6ed7
LP
1577
1578 assert(m);
1579 assert(ev);
1580
3df5bf61 1581 assert_se(w = ev->data.ptr);
034c6ed7 1582
40dde66f
LP
1583 if (w->type == WATCH_INVALID)
1584 return 0;
1585
acbb0225 1586 switch (w->type) {
034c6ed7 1587
ef734fd6 1588 case WATCH_SIGNAL:
034c6ed7 1589
acbb0225 1590 /* An incoming signal? */
f94ea366 1591 if (ev->events != EPOLLIN)
acbb0225 1592 return -EINVAL;
034c6ed7 1593
a16e1123 1594 if ((r = manager_process_signal_fd(m)) < 0)
acbb0225 1595 return r;
034c6ed7 1596
acbb0225 1597 break;
034c6ed7 1598
8c47c732
LP
1599 case WATCH_NOTIFY:
1600
1601 /* An incoming daemon notification event? */
1602 if (ev->events != EPOLLIN)
1603 return -EINVAL;
1604
1605 if ((r = manager_process_notify_fd(m)) < 0)
1606 return r;
1607
1608 break;
1609
acbb0225 1610 case WATCH_FD:
034c6ed7 1611
acbb0225 1612 /* Some fd event, to be dispatched to the units */
ea430986 1613 UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w);
acbb0225 1614 break;
034c6ed7 1615
faf919f1
LP
1616 case WATCH_UNIT_TIMER:
1617 case WATCH_JOB_TIMER: {
acbb0225
LP
1618 uint64_t v;
1619 ssize_t k;
034c6ed7 1620
acbb0225 1621 /* Some timer event, to be dispatched to the units */
68b29a9f
LP
1622 k = read(w->fd, &v, sizeof(v));
1623 if (k != sizeof(v)) {
034c6ed7 1624
acbb0225
LP
1625 if (k < 0 && (errno == EINTR || errno == EAGAIN))
1626 break;
034c6ed7 1627
8742514c 1628 log_error("Failed to read timer event counter: %s", k < 0 ? strerror(-k) : "Short read");
acbb0225 1629 return k < 0 ? -errno : -EIO;
034c6ed7
LP
1630 }
1631
faf919f1
LP
1632 if (w->type == WATCH_UNIT_TIMER)
1633 UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w);
1634 else
1635 job_timer_event(w->data.job, v, w);
acbb0225
LP
1636 break;
1637 }
1638
ef734fd6
LP
1639 case WATCH_MOUNT:
1640 /* Some mount table change, intended for the mount subsystem */
1641 mount_fd_event(m, ev->events);
1642 break;
1643
4e434314
LP
1644 case WATCH_SWAP:
1645 /* Some swap table change, intended for the swap subsystem */
1646 swap_fd_event(m, ev->events);
1647 break;
1648
f94ea366
LP
1649 case WATCH_UDEV:
1650 /* Some notification from udev, intended for the device subsystem */
1651 device_fd_event(m, ev->events);
1652 break;
1653
ea430986
LP
1654 case WATCH_DBUS_WATCH:
1655 bus_watch_event(m, w, ev->events);
1656 break;
1657
1658 case WATCH_DBUS_TIMEOUT:
1659 bus_timeout_event(m, w, ev->events);
1660 break;
1661
8742514c
LP
1662 case WATCH_TIME_CHANGE: {
1663 Unit *u;
1664 Iterator i;
1665
1666 log_struct(LOG_INFO,
1667 MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
1668 "MESSAGE=Time has been changed",
1669 NULL);
1670
1671 /* Restart the watch */
f1324eaa
ES
1672 epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, m->time_change_watch.fd,
1673 NULL);
8742514c
LP
1674 close_nointr_nofail(m->time_change_watch.fd);
1675 watch_init(&m->time_change_watch);
1676 manager_setup_time_change(m);
1677
1678 HASHMAP_FOREACH(u, m->units, i) {
1679 if (UNIT_VTABLE(u)->time_change)
1680 UNIT_VTABLE(u)->time_change(u);
1681 }
1682
1683 break;
1684 }
1685
03b717a3
MS
1686 case WATCH_JOBS_IN_PROGRESS: {
1687 uint64_t v;
1688
1689 /* not interested in the data */
1690 read(w->fd, &v, sizeof(v));
1691
1692 manager_print_jobs_in_progress(m);
1693 break;
1694 }
1695
acbb0225 1696 default:
c5fd1e57 1697 log_error("event type=%i", w->type);
acbb0225 1698 assert_not_reached("Unknown epoll event type.");
034c6ed7 1699 }
9152c765
LP
1700
1701 return 0;
1702}
1703
1704int manager_loop(Manager *m) {
1705 int r;
9152c765 1706
fac9f8df 1707 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
ea430986 1708
9152c765 1709 assert(m);
a16e1123 1710 m->exit_code = MANAGER_RUNNING;
9152c765 1711
fe51822e
LP
1712 /* Release the path cache */
1713 set_free_free(m->unit_path_cache);
1714 m->unit_path_cache = NULL;
1715
b0c918b9
LP
1716 manager_check_finished(m);
1717
a4312405
LP
1718 /* There might still be some zombies hanging around from
1719 * before we were exec()'ed. Leat's reap them */
e96d6be7
LP
1720 r = manager_dispatch_sigchld(m);
1721 if (r < 0)
a4312405
LP
1722 return r;
1723
a16e1123 1724 while (m->exit_code == MANAGER_RUNNING) {
957ca890
LP
1725 struct epoll_event event;
1726 int n;
c757a65b 1727 int wait_msec = -1;
9152c765 1728
67445f4e 1729 if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
e96d6be7
LP
1730 watchdog_ping();
1731
ea430986
LP
1732 if (!ratelimit_test(&rl)) {
1733 /* Yay, something is going seriously wrong, pause a little */
1734 log_warning("Looping too fast. Throttling execution a little.");
1735 sleep(1);
e96d6be7 1736 continue;
ea430986
LP
1737 }
1738
37a8e683 1739 if (manager_dispatch_load_queue(m) > 0)
23a177ef
LP
1740 continue;
1741
37a8e683 1742 if (manager_dispatch_run_queue(m) > 0)
701cc384
LP
1743 continue;
1744
37a8e683 1745 if (bus_dispatch(m) > 0)
c1e1601e 1746 continue;
034c6ed7 1747
37a8e683 1748 if (manager_dispatch_cleanup_queue(m) > 0)
c1e1601e
LP
1749 continue;
1750
37a8e683 1751 if (manager_dispatch_gc_queue(m) > 0)
c1e1601e
LP
1752 continue;
1753
1754 if (manager_dispatch_dbus_queue(m) > 0)
ea430986 1755 continue;
ea430986 1756
e04aad61
LP
1757 if (swap_dispatch_reload(m) > 0)
1758 continue;
1759
c757a65b 1760 /* Sleep for half the watchdog time */
67445f4e 1761 if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM) {
c757a65b
LP
1762 wait_msec = (int) (m->runtime_watchdog / 2 / USEC_PER_MSEC);
1763 if (wait_msec <= 0)
1764 wait_msec = 1;
1765 } else
1766 wait_msec = -1;
1767
e96d6be7
LP
1768 n = epoll_wait(m->epoll_fd, &event, 1, wait_msec);
1769 if (n < 0) {
9152c765 1770
6089f4a9 1771 if (errno == EINTR)
9152c765
LP
1772 continue;
1773
1774 return -errno;
e96d6be7
LP
1775 } else if (n == 0)
1776 continue;
9152c765 1777
957ca890 1778 assert(n == 1);
b9cd2ec1 1779
e96d6be7
LP
1780 r = process_event(m, &event);
1781 if (r < 0)
957ca890 1782 return r;
a16e1123 1783 }
957ca890 1784
a16e1123 1785 return m->exit_code;
83c60c9f 1786}
ea430986 1787
80fbf05e 1788int manager_load_unit_from_dbus_path(Manager *m, const char *s, DBusError *e, Unit **_u) {
ea430986
LP
1789 char *n;
1790 Unit *u;
80fbf05e 1791 int r;
ea430986
LP
1792
1793 assert(m);
1794 assert(s);
1795 assert(_u);
1796
1797 if (!startswith(s, "/org/freedesktop/systemd1/unit/"))
1798 return -EINVAL;
1799
80fbf05e
MS
1800 n = bus_path_unescape(s+31);
1801 if (!n)
ea430986
LP
1802 return -ENOMEM;
1803
80fbf05e 1804 r = manager_load_unit(m, n, NULL, e, &u);
ea430986
LP
1805 free(n);
1806
80fbf05e
MS
1807 if (r < 0)
1808 return r;
ea430986
LP
1809
1810 *_u = u;
1811
1812 return 0;
1813}
86fbf370
LP
1814
1815int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
1816 Job *j;
1817 unsigned id;
1818 int r;
1819
1820 assert(m);
1821 assert(s);
1822 assert(_j);
1823
1824 if (!startswith(s, "/org/freedesktop/systemd1/job/"))
1825 return -EINVAL;
1826
8742514c
LP
1827 r = safe_atou(s + 30, &id);
1828 if (r < 0)
86fbf370
LP
1829 return r;
1830
8742514c
LP
1831 j = manager_get_job(m, id);
1832 if (!j)
86fbf370
LP
1833 return -ENOENT;
1834
1835 *_j = j;
1836
1837 return 0;
1838}
dfcd764e 1839
4927fcae 1840void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
e537352b 1841
4927fcae
LP
1842#ifdef HAVE_AUDIT
1843 char *p;
c1165f82 1844 int audit_fd;
e537352b 1845
c1165f82
LP
1846 audit_fd = get_audit_fd();
1847 if (audit_fd < 0)
e537352b
LP
1848 return;
1849
bbd3a7ba
LP
1850 /* Don't generate audit events if the service was already
1851 * started and we're just deserializing */
a7556052 1852 if (m->n_reloading > 0)
bbd3a7ba
LP
1853 return;
1854
67445f4e 1855 if (m->running_as != SYSTEMD_SYSTEM)
f1dd0c3f
LP
1856 return;
1857
ac155bb8 1858 if (u->type != UNIT_SERVICE)
f1dd0c3f
LP
1859 return;
1860
bd0af849
ZJS
1861 p = unit_name_to_prefix_and_instance(u->id);
1862 if (!p) {
66870f90
ZJS
1863 log_error_unit(u->id,
1864 "Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
e537352b
LP
1865 return;
1866 }
1867
c1165f82 1868 if (audit_log_user_comm_message(audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
391ade86
LP
1869 if (errno == EPERM) {
1870 /* We aren't allowed to send audit messages?
44785992 1871 * Then let's not retry again. */
c1165f82 1872 close_audit_fd();
44785992
LP
1873 } else
1874 log_warning("Failed to send audit message: %m");
391ade86 1875 }
e537352b 1876
4927fcae
LP
1877 free(p);
1878#endif
e537352b 1879
e537352b
LP
1880}
1881
e983b760
LP
1882void manager_send_unit_plymouth(Manager *m, Unit *u) {
1883 int fd = -1;
1884 union sockaddr_union sa;
1885 int n = 0;
1886 char *message = NULL;
e983b760
LP
1887
1888 /* Don't generate plymouth events if the service was already
1889 * started and we're just deserializing */
a7556052 1890 if (m->n_reloading > 0)
e983b760
LP
1891 return;
1892
67445f4e 1893 if (m->running_as != SYSTEMD_SYSTEM)
e983b760
LP
1894 return;
1895
ac155bb8
MS
1896 if (u->type != UNIT_SERVICE &&
1897 u->type != UNIT_MOUNT &&
1898 u->type != UNIT_SWAP)
e983b760
LP
1899 return;
1900
1901 /* We set SOCK_NONBLOCK here so that we rather drop the
1902 * message then wait for plymouth */
e62d8c39
ZJS
1903 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1904 if (fd < 0) {
e983b760
LP
1905 log_error("socket() failed: %m");
1906 return;
1907 }
1908
1909 zero(sa);
1910 sa.sa.sa_family = AF_UNIX;
96707269
LP
1911 strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
1912 if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
e983b760
LP
1913
1914 if (errno != EPIPE &&
1915 errno != EAGAIN &&
1916 errno != ENOENT &&
1917 errno != ECONNREFUSED &&
1918 errno != ECONNRESET &&
1919 errno != ECONNABORTED)
1920 log_error("connect() failed: %m");
1921
1922 goto finish;
1923 }
1924
ac155bb8 1925 if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
0d0f0c50 1926 log_oom();
e983b760
LP
1927 goto finish;
1928 }
1929
1930 errno = 0;
bd40a2d8 1931 if (write(fd, message, n + 1) != n + 1) {
e983b760
LP
1932
1933 if (errno != EPIPE &&
1934 errno != EAGAIN &&
1935 errno != ENOENT &&
1936 errno != ECONNREFUSED &&
1937 errno != ECONNRESET &&
1938 errno != ECONNABORTED)
1939 log_error("Failed to write Plymouth message: %m");
1940
1941 goto finish;
1942 }
1943
1944finish:
1945 if (fd >= 0)
1946 close_nointr_nofail(fd);
1947
1948 free(message);
1949}
1950
05e343b7
LP
1951void manager_dispatch_bus_name_owner_changed(
1952 Manager *m,
1953 const char *name,
1954 const char* old_owner,
1955 const char *new_owner) {
1956
1957 Unit *u;
1958
1959 assert(m);
1960 assert(name);
1961
1962 if (!(u = hashmap_get(m->watch_bus, name)))
1963 return;
1964
1965 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
1966}
1967
1968void manager_dispatch_bus_query_pid_done(
1969 Manager *m,
1970 const char *name,
1971 pid_t pid) {
1972
1973 Unit *u;
1974
1975 assert(m);
1976 assert(name);
1977 assert(pid >= 1);
1978
1979 if (!(u = hashmap_get(m->watch_bus, name)))
1980 return;
1981
1982 UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
1983}
1984
d8d5ab98 1985int manager_open_serialization(Manager *m, FILE **_f) {
b925e726 1986 char *path = NULL;
a16e1123
LP
1987 mode_t saved_umask;
1988 int fd;
1989 FILE *f;
1990
1991 assert(_f);
1992
67445f4e 1993 if (m->running_as == SYSTEMD_SYSTEM)
2b583ce6 1994 asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid());
b925e726
LP
1995 else
1996 asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid());
d8d5ab98 1997
b925e726
LP
1998 if (!path)
1999 return -ENOMEM;
a16e1123
LP
2000
2001 saved_umask = umask(0077);
2002 fd = mkostemp(path, O_RDWR|O_CLOEXEC);
2003 umask(saved_umask);
2004
2005 if (fd < 0) {
2006 free(path);
2007 return -errno;
2008 }
2009
2010 unlink(path);
2011
2012 log_debug("Serializing state to %s", path);
2013 free(path);
2014
01e10de3
LP
2015 f = fdopen(fd, "w+");
2016 if (!f)
a16e1123
LP
2017 return -errno;
2018
2019 *_f = f;
2020
2021 return 0;
2022}
2023
6b78f9b4 2024int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) {
a16e1123
LP
2025 Iterator i;
2026 Unit *u;
2027 const char *t;
4a9fd066 2028 char **e;
a16e1123
LP
2029 int r;
2030
2031 assert(m);
2032 assert(f);
2033 assert(fds);
2034
a7556052 2035 m->n_reloading ++;
38c52d46 2036
01d67b43
LP
2037 fprintf(f, "current-job-id=%i\n", m->current_job_id);
2038 fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
33c5fae9
LP
2039 fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
2040 fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
01d67b43 2041
915b3753
LP
2042 dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp);
2043 dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp);
2044 dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp);
e9ddabc2 2045 dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
f38ed060 2046
26a1efdf 2047 if (!in_initrd()) {
915b3753 2048 dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp);
f38ed060
HH
2049 dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
2050 }
47a483a1 2051
4a9fd066
OS
2052 STRV_FOREACH(e, m->environment) {
2053 _cleanup_free_ char *ce;
2054
2055 ce = cescape(*e);
2056 if (ce)
2057 fprintf(f, "env=%s\n", *e);
2058 }
2059
f2382a94
LP
2060 fputc('\n', f);
2061
a16e1123 2062 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
ac155bb8 2063 if (u->id != t)
a16e1123
LP
2064 continue;
2065
2066 if (!unit_can_serialize(u))
2067 continue;
2068
2069 /* Start marker */
ac155bb8 2070 fputs(u->id, f);
a16e1123
LP
2071 fputc('\n', f);
2072
6b78f9b4 2073 if ((r = unit_serialize(u, f, fds, serialize_jobs)) < 0) {
a7556052 2074 m->n_reloading --;
a16e1123 2075 return r;
38c52d46 2076 }
a16e1123
LP
2077 }
2078
a7556052
LP
2079 assert(m->n_reloading > 0);
2080 m->n_reloading --;
38c52d46 2081
a16e1123
LP
2082 if (ferror(f))
2083 return -EIO;
2084
b23de6af
LP
2085 r = bus_fdset_add_all(m, fds);
2086 if (r < 0)
2087 return r;
2088
a16e1123
LP
2089 return 0;
2090}
2091
2092int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
2093 int r = 0;
2094
2095 assert(m);
2096 assert(f);
2097
2098 log_debug("Deserializing state...");
2099
a7556052 2100 m->n_reloading ++;
82c64bf5 2101
10f8e83c 2102 for (;;) {
20c03b7b 2103 char line[LINE_MAX], *l;
10f8e83c
LP
2104
2105 if (!fgets(line, sizeof(line), f)) {
2106 if (feof(f))
2107 r = 0;
2108 else
2109 r = -errno;
2110
2111 goto finish;
2112 }
2113
2114 char_array_0(line);
2115 l = strstrip(line);
2116
2117 if (l[0] == 0)
2118 break;
2119
01d67b43
LP
2120 if (startswith(l, "current-job-id=")) {
2121 uint32_t id;
2122
2123 if (safe_atou32(l+15, &id) < 0)
2124 log_debug("Failed to parse current job id value %s", l+15);
2125 else
2126 m->current_job_id = MAX(m->current_job_id, id);
33c5fae9
LP
2127 } else if (startswith(l, "n-installed-jobs=")) {
2128 uint32_t n;
2129
2130 if (safe_atou32(l+17, &n) < 0)
2131 log_debug("Failed to parse installed jobs counter %s", l+17);
2132 else
2133 m->n_installed_jobs += n;
2134 } else if (startswith(l, "n-failed-jobs=")) {
2135 uint32_t n;
2136
2137 if (safe_atou32(l+14, &n) < 0)
2138 log_debug("Failed to parse failed jobs counter %s", l+14);
2139 else
2140 m->n_failed_jobs += n;
01d67b43
LP
2141 } else if (startswith(l, "taint-usr=")) {
2142 int b;
2143
2144 if ((b = parse_boolean(l+10)) < 0)
2145 log_debug("Failed to parse taint /usr flag %s", l+10);
2146 else
2147 m->taint_usr = m->taint_usr || b;
915b3753
LP
2148 } else if (startswith(l, "firmware-timestamp="))
2149 dual_timestamp_deserialize(l+19, &m->firmware_timestamp);
2150 else if (startswith(l, "loader-timestamp="))
2151 dual_timestamp_deserialize(l+17, &m->loader_timestamp);
2152 else if (startswith(l, "kernel-timestamp="))
2153 dual_timestamp_deserialize(l+17, &m->kernel_timestamp);
2154 else if (startswith(l, "initrd-timestamp="))
e9ddabc2 2155 dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
915b3753
LP
2156 else if (startswith(l, "userspace-timestamp="))
2157 dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
10717a1a 2158 else if (startswith(l, "finish-timestamp="))
799fd0fd 2159 dual_timestamp_deserialize(l+17, &m->finish_timestamp);
4a9fd066
OS
2160 else if (startswith(l, "env=")) {
2161 _cleanup_free_ char *uce = NULL;
2162 char **e;
2163
2164 uce = cunescape(l+4);
2165 if (!uce) {
2166 r = -ENOMEM;
2167 goto finish;
2168 }
2169
2170 e = strv_env_set(m->environment, uce);
2171 if (!e) {
2172 r = -ENOMEM;
2173 goto finish;
2174 }
2175
2176 strv_free(m->environment);
2177 m->environment = e;
2178 } else
10f8e83c
LP
2179 log_debug("Unknown serialization item '%s'", l);
2180 }
2181
a16e1123
LP
2182 for (;;) {
2183 Unit *u;
2184 char name[UNIT_NAME_MAX+2];
2185
2186 /* Start marker */
2187 if (!fgets(name, sizeof(name), f)) {
2188 if (feof(f))
10f8e83c
LP
2189 r = 0;
2190 else
2191 r = -errno;
a16e1123 2192
82c64bf5 2193 goto finish;
a16e1123
LP
2194 }
2195
2196 char_array_0(name);
2197
bd0af849
ZJS
2198 r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
2199 if (r < 0)
82c64bf5 2200 goto finish;
a16e1123 2201
01e10de3
LP
2202 r = unit_deserialize(u, f, fds);
2203 if (r < 0)
82c64bf5 2204 goto finish;
a16e1123
LP
2205 }
2206
10f8e83c 2207finish:
82c64bf5
LP
2208 if (ferror(f)) {
2209 r = -EIO;
2210 goto finish;
2211 }
a16e1123 2212
a7556052
LP
2213 assert(m->n_reloading > 0);
2214 m->n_reloading --;
82c64bf5
LP
2215
2216 return r;
a16e1123
LP
2217}
2218
01e10de3
LP
2219int manager_distribute_fds(Manager *m, FDSet *fds) {
2220 Unit *u;
2221 Iterator i;
2222 int r;
2223
2224 assert(m);
2225
2226 HASHMAP_FOREACH(u, m->units, i) {
2227
2228 if (fdset_size(fds) <= 0)
2229 break;
2230
2231 if (UNIT_VTABLE(u)->distribute_fds) {
2232 r = UNIT_VTABLE(u)->distribute_fds(u, fds);
2233 if (r < 0)
2234 return r;
2235 }
2236 }
2237
2238 return 0;
2239}
2240
a16e1123
LP
2241int manager_reload(Manager *m) {
2242 int r, q;
2243 FILE *f;
2244 FDSet *fds;
2245
2246 assert(m);
2247
07719a21
LP
2248 r = manager_open_serialization(m, &f);
2249 if (r < 0)
a16e1123
LP
2250 return r;
2251
a7556052 2252 m->n_reloading ++;
38c52d46 2253
07719a21
LP
2254 fds = fdset_new();
2255 if (!fds) {
a7556052 2256 m->n_reloading --;
a16e1123
LP
2257 r = -ENOMEM;
2258 goto finish;
2259 }
2260
6b78f9b4 2261 r = manager_serialize(m, f, fds, true);
07719a21 2262 if (r < 0) {
a7556052 2263 m->n_reloading --;
a16e1123 2264 goto finish;
38c52d46 2265 }
a16e1123
LP
2266
2267 if (fseeko(f, 0, SEEK_SET) < 0) {
a7556052 2268 m->n_reloading --;
a16e1123
LP
2269 r = -errno;
2270 goto finish;
2271 }
2272
2273 /* From here on there is no way back. */
2274 manager_clear_jobs_and_units(m);
5a1e9937 2275 manager_undo_generators(m);
84e3543e 2276 lookup_paths_free(&m->lookup_paths);
2ded0c04 2277
07719a21 2278 /* Find new unit paths */
5a1e9937
LP
2279 manager_run_generators(m);
2280
07719a21
LP
2281 q = lookup_paths_init(
2282 &m->lookup_paths, m->running_as, true,
2283 m->generator_unit_path,
2284 m->generator_unit_path_early,
2285 m->generator_unit_path_late);
2286 if (q < 0)
2287 r = q;
2288
5a1e9937
LP
2289 manager_build_unit_path_cache(m);
2290
a16e1123 2291 /* First, enumerate what we can from all config files */
07719a21
LP
2292 q = manager_enumerate(m);
2293 if (q < 0)
a16e1123
LP
2294 r = q;
2295
2296 /* Second, deserialize our stored data */
07719a21
LP
2297 q = manager_deserialize(m, f, fds);
2298 if (q < 0)
a16e1123
LP
2299 r = q;
2300
2301 fclose(f);
2302 f = NULL;
2303
2304 /* Third, fire things up! */
07719a21
LP
2305 q = manager_coldplug(m);
2306 if (q < 0)
a16e1123
LP
2307 r = q;
2308
a7556052
LP
2309 assert(m->n_reloading > 0);
2310 m->n_reloading--;
9f611ad8 2311
a16e1123
LP
2312finish:
2313 if (f)
2314 fclose(f);
2315
2316 if (fds)
2317 fdset_free(fds);
2318
2319 return r;
2320}
2321
6084e22e 2322static bool manager_is_booting_or_shutting_down(Manager *m) {
9e58ff9c
LP
2323 Unit *u;
2324
2325 assert(m);
2326
2327 /* Is the initial job still around? */
bacbccb7 2328 if (manager_get_job(m, m->default_unit_job_id))
9e58ff9c
LP
2329 return true;
2330
2331 /* Is there a job for the shutdown target? */
27d340c7
LP
2332 u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
2333 if (u)
ac155bb8 2334 return !!u->job;
9e58ff9c
LP
2335
2336 return false;
2337}
2338
c17ec25e
MS
2339bool manager_is_reloading_or_reexecuting(Manager *m) {
2340 assert(m);
2341
2342 return m->n_reloading != 0;
2343}
2344
fdf20a31 2345void manager_reset_failed(Manager *m) {
5632e374
LP
2346 Unit *u;
2347 Iterator i;
2348
2349 assert(m);
2350
2351 HASHMAP_FOREACH(u, m->units, i)
fdf20a31 2352 unit_reset_failed(u);
5632e374
LP
2353}
2354
8f6df3fa
LP
2355bool manager_unit_pending_inactive(Manager *m, const char *name) {
2356 Unit *u;
2357
2358 assert(m);
2359 assert(name);
2360
2361 /* Returns true if the unit is inactive or going down */
bd0af849
ZJS
2362 u = manager_get_unit(m, name);
2363 if (!u)
8f6df3fa
LP
2364 return true;
2365
18ffdfda 2366 return unit_pending_inactive(u);
8f6df3fa
LP
2367}
2368
b0c918b9 2369void manager_check_finished(Manager *m) {
7ceba241 2370 char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
915b3753 2371 usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
b0c918b9
LP
2372
2373 assert(m);
2374
a0b64226
MS
2375 if (m->n_running_jobs == 0)
2376 manager_unwatch_jobs_in_progress(m);
2377
5b176ee0
MS
2378 if (hashmap_size(m->jobs) > 0) {
2379 manager_jobs_in_progress_mod_timer(m);
b0c918b9 2380 return;
5b176ee0 2381 }
b0c918b9 2382
f2b68789
LP
2383 /* Notify Type=idle units that we are done now */
2384 close_pipe(m->idle_pipe);
2385
af6da548
LP
2386 /* Turn off confirm spawn now */
2387 m->confirm_spawn = false;
2388
f2b68789 2389 if (dual_timestamp_is_set(&m->finish_timestamp))
b0c918b9
LP
2390 return;
2391
2392 dual_timestamp_get(&m->finish_timestamp);
2393
67445f4e 2394 if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
e03ae661 2395
915b3753
LP
2396 /* Note that m->kernel_usec.monotonic is always at 0,
2397 * and m->firmware_usec.monotonic and
2398 * m->loader_usec.monotonic should be considered
2399 * negative values. */
2400
7ceba241
LP
2401 firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic;
2402 loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic;
915b3753 2403 userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
7ceba241 2404 total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic;
18fa6b27 2405
e9ddabc2 2406 if (dual_timestamp_is_set(&m->initrd_timestamp)) {
18fa6b27 2407
915b3753
LP
2408 kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
2409 initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
18fa6b27 2410
81270860
LP
2411 if (!log_on_console())
2412 log_struct(LOG_INFO,
1ca6783f 2413 MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
81270860
LP
2414 "KERNEL_USEC=%llu", (unsigned long long) kernel_usec,
2415 "INITRD_USEC=%llu", (unsigned long long) initrd_usec,
2416 "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
2417 "MESSAGE=Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
2fa4092c
LP
2418 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2419 format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
2420 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2421 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
81270860 2422 NULL);
18fa6b27 2423 } else {
915b3753 2424 kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
18fa6b27
LP
2425 initrd_usec = 0;
2426
81270860
LP
2427 if (!log_on_console())
2428 log_struct(LOG_INFO,
1ca6783f 2429 MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
81270860
LP
2430 "KERNEL_USEC=%llu", (unsigned long long) kernel_usec,
2431 "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
2432 "MESSAGE=Startup finished in %s (kernel) + %s (userspace) = %s.",
2fa4092c
LP
2433 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2434 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2435 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
81270860 2436 NULL);
18fa6b27
LP
2437 }
2438 } else {
915b3753
LP
2439 firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
2440 total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
877d54e9 2441
81270860
LP
2442 if (!log_on_console())
2443 log_struct(LOG_INFO,
1ca6783f 2444 MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
81270860
LP
2445 "USERSPACE_USEC=%llu", (unsigned long long) userspace_usec,
2446 "MESSAGE=Startup finished in %s.",
2fa4092c 2447 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
81270860 2448 NULL);
18fa6b27 2449 }
b0c918b9 2450
915b3753 2451 bus_broadcast_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
530345e7
LP
2452
2453 sd_notifyf(false,
2454 "READY=1\nSTATUS=Startup finished in %s.",
2fa4092c 2455 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
b0c918b9
LP
2456}
2457
07719a21
LP
2458static int create_generator_dir(Manager *m, char **generator, const char *name) {
2459 char *p;
2460 int r;
2461
2462 assert(m);
2463 assert(generator);
2464 assert(name);
2465
2466 if (*generator)
2467 return 0;
2468
67445f4e 2469 if (m->running_as == SYSTEMD_SYSTEM && getpid() == 1) {
07719a21
LP
2470
2471 p = strappend("/run/systemd/", name);
0d0f0c50
SL
2472 if (!p)
2473 return log_oom();
07719a21 2474
d2e54fae 2475 r = mkdir_p_label(p, 0755);
07719a21 2476 if (r < 0) {
7ad94c71
ZJS
2477 log_error("Failed to create generator directory %s: %s",
2478 p, strerror(-r));
07719a21
LP
2479 free(p);
2480 return r;
2481 }
2482 } else {
b7def684 2483 p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL);
0d0f0c50
SL
2484 if (!p)
2485 return log_oom();
07719a21
LP
2486
2487 if (!mkdtemp(p)) {
7ad94c71
ZJS
2488 log_error("Failed to create generator directory %s: %m",
2489 p);
34bf0281 2490 free(p);
07719a21
LP
2491 return -errno;
2492 }
2493 }
2494
2495 *generator = p;
2496 return 0;
2497}
2498
2499static void trim_generator_dir(Manager *m, char **generator) {
2500 assert(m);
2501 assert(generator);
2502
2503 if (!*generator)
2504 return;
2505
2506 if (rmdir(*generator) >= 0) {
2507 free(*generator);
2508 *generator = NULL;
2509 }
2510
2511 return;
2512}
2513
5a1e9937
LP
2514void manager_run_generators(Manager *m) {
2515 DIR *d = NULL;
5a1e9937 2516 const char *generator_path;
07719a21 2517 const char *argv[5];
07f8a4aa 2518 mode_t u;
07719a21 2519 int r;
5a1e9937
LP
2520
2521 assert(m);
2522
67445f4e 2523 generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
07719a21
LP
2524 d = opendir(generator_path);
2525 if (!d) {
5a1e9937
LP
2526 if (errno == ENOENT)
2527 return;
2528
7ad94c71
ZJS
2529 log_error("Failed to enumerate generator directory %s: %m",
2530 generator_path);
5a1e9937
LP
2531 return;
2532 }
2533
07719a21
LP
2534 r = create_generator_dir(m, &m->generator_unit_path, "generator");
2535 if (r < 0)
2536 goto finish;
f1d19aa4 2537
07719a21
LP
2538 r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early");
2539 if (r < 0)
2540 goto finish;
5a1e9937 2541
07719a21
LP
2542 r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late");
2543 if (r < 0)
2544 goto finish;
5a1e9937 2545
83cc030f
LP
2546 argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
2547 argv[1] = m->generator_unit_path;
07719a21
LP
2548 argv[2] = m->generator_unit_path_early;
2549 argv[3] = m->generator_unit_path_late;
2550 argv[4] = NULL;
5a1e9937 2551
07f8a4aa 2552 u = umask(0022);
83cc030f 2553 execute_directory(generator_path, d, (char**) argv);
07f8a4aa 2554 umask(u);
5a1e9937 2555
07719a21
LP
2556 trim_generator_dir(m, &m->generator_unit_path);
2557 trim_generator_dir(m, &m->generator_unit_path_early);
2558 trim_generator_dir(m, &m->generator_unit_path_late);
5a1e9937
LP
2559
2560finish:
2561 if (d)
2562 closedir(d);
5a1e9937
LP
2563}
2564
07719a21 2565static void remove_generator_dir(Manager *m, char **generator) {
5a1e9937 2566 assert(m);
07719a21 2567 assert(generator);
5a1e9937 2568
07719a21 2569 if (!*generator)
5a1e9937
LP
2570 return;
2571
07719a21
LP
2572 strv_remove(m->lookup_paths.unit_path, *generator);
2573 rm_rf(*generator, false, true, false);
5a1e9937 2574
07719a21
LP
2575 free(*generator);
2576 *generator = NULL;
2577}
2578
2579void manager_undo_generators(Manager *m) {
2580 assert(m);
2581
2582 remove_generator_dir(m, &m->generator_unit_path);
2583 remove_generator_dir(m, &m->generator_unit_path_early);
2584 remove_generator_dir(m, &m->generator_unit_path_late);
5a1e9937
LP
2585}
2586
06d4c99a
LP
2587int manager_set_default_controllers(Manager *m, char **controllers) {
2588 char **l;
2589
2590 assert(m);
2591
9156e799
LP
2592 l = strv_copy(controllers);
2593 if (!l)
06d4c99a
LP
2594 return -ENOMEM;
2595
2596 strv_free(m->default_controllers);
2597 m->default_controllers = l;
2598
b59e2465 2599 cg_shorten_controllers(m->default_controllers);
9156e799 2600
06d4c99a
LP
2601 return 0;
2602}
2603
c93ff2e9
FC
2604int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
2605 int i;
2606
2607 assert(m);
2608
2609 for (i = 0; i < RLIMIT_NLIMITS; i++) {
07719a21
LP
2610 if (!default_rlimit[i])
2611 continue;
c93ff2e9 2612
07719a21
LP
2613 m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
2614 if (!m->rlimit[i])
2615 return -ENOMEM;
c93ff2e9
FC
2616 }
2617
2618 return 0;
2619}
2620
4cfa2c99 2621void manager_recheck_journal(Manager *m) {
f1dd0c3f
LP
2622 Unit *u;
2623
2624 assert(m);
2625
67445f4e 2626 if (m->running_as != SYSTEMD_SYSTEM)
f1dd0c3f
LP
2627 return;
2628
731a676c
LP
2629 u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
2630 if (u && SOCKET(u)->state != SOCKET_RUNNING) {
4cfa2c99 2631 log_close_journal();
731a676c 2632 return;
f1dd0c3f
LP
2633 }
2634
731a676c
LP
2635 u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
2636 if (u && SERVICE(u)->state != SERVICE_RUNNING) {
4cfa2c99 2637 log_close_journal();
731a676c
LP
2638 return;
2639 }
f1dd0c3f 2640
731a676c
LP
2641 /* Hmm, OK, so the socket is fully up and the service is up
2642 * too, then let's make use of the thing. */
f1dd0c3f
LP
2643 log_open();
2644}
2645
27d340c7
LP
2646void manager_set_show_status(Manager *m, bool b) {
2647 assert(m);
2648
67445f4e 2649 if (m->running_as != SYSTEMD_SYSTEM)
27d340c7
LP
2650 return;
2651
2652 m->show_status = b;
2653
2654 if (b)
2655 touch("/run/systemd/show-status");
2656 else
2657 unlink("/run/systemd/show-status");
2658}
2659
6084e22e 2660static bool manager_get_show_status(Manager *m) {
27d340c7
LP
2661 assert(m);
2662
67445f4e 2663 if (m->running_as != SYSTEMD_SYSTEM)
27d340c7
LP
2664 return false;
2665
2666 if (m->show_status)
2667 return true;
2668
2669 /* If Plymouth is running make sure we show the status, so
2670 * that there's something nice to see when people press Esc */
2671
2672 return plymouth_running();
2673}
68b29a9f 2674
984a2be4 2675void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) {
25cee550
MS
2676 va_list ap;
2677
2678 if (!manager_get_show_status(m))
2679 return;
2680
03b717a3
MS
2681 /* XXX We should totally drop the check for ephemeral here
2682 * and thus effectively make 'Type=idle' pointless. */
2683 if (ephemeral && m->n_on_console > 0)
2684 return;
2685
25cee550
MS
2686 if (!manager_is_booting_or_shutting_down(m))
2687 return;
2688
2689 va_start(ap, format);
984a2be4 2690 status_vprintf(status, true, ephemeral, format, ap);
25cee550
MS
2691 va_end(ap);
2692}
2693
68b29a9f
LP
2694void watch_init(Watch *w) {
2695 assert(w);
2696
2697 w->type = WATCH_INVALID;
2698 w->fd = -1;
2699}