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