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