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