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