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