1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
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.
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.
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/>.
28 #include <sys/inotify.h>
29 #include <sys/epoll.h>
31 #include <sys/reboot.h>
32 #include <sys/ioctl.h>
36 #include <sys/types.h>
39 #include <sys/timerfd.h>
45 #include "sd-daemon.h"
47 #include "sd-messages.h"
50 #include "transaction.h"
57 #include "ratelimit.h"
58 #include "locale-setup.h"
59 #include "mount-setup.h"
60 #include "unit-name.h"
62 #include "path-lookup.h"
64 #include "exit-status.h"
67 #include "cgroup-util.h"
68 #include "path-util.h"
70 #include "boot-timestamps.h"
72 #include "bus-errors.h"
73 #include "bus-error.h"
76 #include "dbus-unit.h"
78 #include "dbus-manager.h"
79 #include "bus-kernel.h"
80 #include "time-util.h"
82 /* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
83 #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
85 /* Initial delay and the interval for printing status messages about running jobs */
86 #define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
87 #define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
88 #define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
90 static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
91 static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
92 static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
93 static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
94 static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
95 static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
97 static int manager_watch_jobs_in_progress(Manager *m) {
102 if (m->jobs_in_progress_event_source)
105 next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
106 return sd_event_add_time(
108 &m->jobs_in_progress_event_source,
111 manager_dispatch_jobs_in_progress, m);
114 #define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
116 static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
119 assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
120 assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
124 p = mempset(p, ' ', pos-2);
125 p = stpcpy(p, ANSI_RED_ON);
129 if (pos > 0 && pos <= width) {
130 p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON);
134 p = stpcpy(p, ANSI_HIGHLIGHT_OFF);
137 p = stpcpy(p, ANSI_RED_ON);
140 p = mempset(p, ' ', width-1-pos);
141 strcpy(p, ANSI_HIGHLIGHT_OFF);
145 void manager_flip_auto_status(Manager *m, bool enable) {
149 if (m->show_status == SHOW_STATUS_AUTO)
150 manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
152 if (m->show_status == SHOW_STATUS_TEMPORARY)
153 manager_set_show_status(m, SHOW_STATUS_AUTO);
157 static void manager_print_jobs_in_progress(Manager *m) {
158 _cleanup_free_ char *job_of_n = NULL;
161 unsigned counter = 0, print_nr;
162 char cylon[6 + CYLON_BUFFER_EXTRA + 1];
164 char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
169 manager_flip_auto_status(m, true);
171 print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
173 HASHMAP_FOREACH(j, m->jobs, i)
174 if (j->state == JOB_RUNNING && counter++ == print_nr)
177 /* m->n_running_jobs must be consistent with the contents of m->jobs,
178 * so the above loop must have succeeded in finding j. */
179 assert(counter == print_nr + 1);
182 cylon_pos = m->jobs_in_progress_iteration % 14;
184 cylon_pos = 14 - cylon_pos;
185 draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
187 m->jobs_in_progress_iteration++;
189 if (m->n_running_jobs > 1)
190 if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
193 format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
194 if (job_get_timeout(j, &x) > 0)
195 format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
197 manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
198 "%sA %s job is running for %s (%s / %s)",
200 job_type_to_string(j->type),
201 unit_description(j->unit),
206 static int have_ask_password(void) {
207 _cleanup_closedir_ DIR *dir;
209 dir = opendir("/run/systemd/ask-password");
222 if (!de && errno != 0)
227 if (startswith(de->d_name, "ask."))
232 static int manager_dispatch_ask_password_fd(sd_event_source *source,
233 int fd, uint32_t revents, void *userdata) {
234 Manager *m = userdata;
240 m->have_ask_password = have_ask_password();
241 if (m->have_ask_password < 0)
242 /* Log error but continue. Negative have_ask_password
243 * is treated as unknown status. */
244 log_error("Failed to list /run/systemd/ask-password: %s", strerror(m->have_ask_password));
249 static void manager_close_ask_password(Manager *m) {
252 m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
253 m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
254 m->have_ask_password = -EINVAL;
257 static int manager_check_ask_password(Manager *m) {
262 if (!m->ask_password_event_source) {
263 assert(m->ask_password_inotify_fd < 0);
265 mkdir_p_label("/run/systemd/ask-password", 0755);
267 m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
268 if (m->ask_password_inotify_fd < 0) {
269 log_error("inotify_init1() failed: %m");
273 if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
274 log_error("Failed to add watch on /run/systemd/ask-password: %m");
275 manager_close_ask_password(m);
279 r = sd_event_add_io(m->event, &m->ask_password_event_source,
280 m->ask_password_inotify_fd, EPOLLIN,
281 manager_dispatch_ask_password_fd, m);
283 log_error("Failed to add event source for /run/systemd/ask-password: %m");
284 manager_close_ask_password(m);
288 /* Queries might have been added meanwhile... */
289 manager_dispatch_ask_password_fd(m->ask_password_event_source,
290 m->ask_password_inotify_fd, EPOLLIN, m);
293 return m->have_ask_password;
296 static int manager_watch_idle_pipe(Manager *m) {
301 if (m->idle_pipe_event_source)
304 if (m->idle_pipe[2] < 0)
307 r = sd_event_add_io(m->event, &m->idle_pipe_event_source, m->idle_pipe[2], EPOLLIN, manager_dispatch_idle_pipe_fd, m);
309 log_error("Failed to watch idle pipe: %s", strerror(-r));
316 static void manager_close_idle_pipe(Manager *m) {
319 safe_close_pair(m->idle_pipe);
320 safe_close_pair(m->idle_pipe + 2);
323 static int manager_setup_time_change(Manager *m) {
326 /* We only care for the cancellation event, hence we set the
327 * timeout to the latest possible value. */
328 struct itimerspec its = {
329 .it_value.tv_sec = TIME_T_MAX,
333 assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
338 /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
339 * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
341 m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
342 if (m->time_change_fd < 0) {
343 log_error("Failed to create timerfd: %m");
347 if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
348 log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
349 m->time_change_fd = safe_close(m->time_change_fd);
353 r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
355 log_error("Failed to create time change event source: %s", strerror(-r));
359 log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
364 static int enable_special_signals(Manager *m) {
365 _cleanup_close_ int fd = -1;
369 /* Enable that we get SIGINT on control-alt-del. In containers
370 * this will fail with EPERM (older) or EINVAL (newer), so
372 if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
373 log_warning("Failed to enable ctrl-alt-del handling: %m");
375 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
377 /* Support systems without virtual console */
379 log_warning("Failed to open /dev/tty0: %m");
381 /* Enable that we get SIGWINCH on kbrequest */
382 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
383 log_warning("Failed to enable kbrequest handling: %m");
389 static int manager_setup_signals(Manager *m) {
390 struct sigaction sa = {
391 .sa_handler = SIG_DFL,
392 .sa_flags = SA_NOCLDSTOP|SA_RESTART,
402 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
404 /* We make liberal use of realtime signals here. On
405 * Linux/glibc we have 30 of them (with the exception of Linux
406 * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
409 assert_se(sigemptyset(&mask) == 0);
410 sigset_add_many(&mask,
411 SIGCHLD, /* Child died */
412 SIGTERM, /* Reexecute daemon */
413 SIGHUP, /* Reload configuration */
414 SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
415 SIGUSR2, /* systemd: dump status */
416 SIGINT, /* Kernel sends us this on control-alt-del */
417 SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
418 SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
420 SIGRTMIN+0, /* systemd: start default.target */
421 SIGRTMIN+1, /* systemd: isolate rescue.target */
422 SIGRTMIN+2, /* systemd: isolate emergency.target */
423 SIGRTMIN+3, /* systemd: start halt.target */
424 SIGRTMIN+4, /* systemd: start poweroff.target */
425 SIGRTMIN+5, /* systemd: start reboot.target */
426 SIGRTMIN+6, /* systemd: start kexec.target */
428 /* ... space for more special targets ... */
430 SIGRTMIN+13, /* systemd: Immediate halt */
431 SIGRTMIN+14, /* systemd: Immediate poweroff */
432 SIGRTMIN+15, /* systemd: Immediate reboot */
433 SIGRTMIN+16, /* systemd: Immediate kexec */
435 /* ... space for more immediate system state changes ... */
437 SIGRTMIN+20, /* systemd: enable status messages */
438 SIGRTMIN+21, /* systemd: disable status messages */
439 SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
440 SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
441 SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
443 /* .. one free signal here ... */
445 #if !defined(__hppa64__) && !defined(__hppa__)
446 /* Apparently Linux on hppa has fewer RT
447 * signals (SIGRTMAX is SIGRTMIN+25 there),
448 * hence let's not try to make use of them
449 * here. Since these commands are accessible
450 * by different means and only really a safety
451 * net, the missing functionality on hppa
452 * shouldn't matter. */
454 SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
455 SIGRTMIN+27, /* systemd: set log target to console */
456 SIGRTMIN+28, /* systemd: set log target to kmsg */
457 SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete)*/
459 /* ... one free signal here SIGRTMIN+30 ... */
462 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
464 m->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
465 if (m->signal_fd < 0)
468 r = sd_event_add_io(m->event, &m->signal_event_source, m->signal_fd, EPOLLIN, manager_dispatch_signal_fd, m);
472 /* Process signals a bit earlier than the rest of things, but
473 * later than notify_fd processing, so that the notify
474 * processing can still figure out to which process/service a
475 * message belongs, before we reap the process. */
476 r = sd_event_source_set_priority(m->signal_event_source, -5);
480 if (m->running_as == SYSTEMD_SYSTEM)
481 return enable_special_signals(m);
486 static void manager_clean_environment(Manager *m) {
489 /* Let's remove some environment variables that we
490 * need ourselves to communicate with our clients */
503 static int manager_default_environment(Manager *m) {
506 if (m->running_as == SYSTEMD_SYSTEM) {
507 /* The system manager always starts with a clean
508 * environment for its children. It does not import
509 * the kernel or the parents exported variables.
511 * The initial passed environ is untouched to keep
512 * /proc/self/environ valid; it is used for tagging
513 * the init process inside containers. */
514 m->environment = strv_new("PATH=" DEFAULT_PATH,
517 /* Import locale variables LC_*= from configuration */
518 locale_setup(&m->environment);
520 /* The user manager passes its own environment
521 * along to its children. */
522 m->environment = strv_copy(environ);
528 manager_clean_environment(m);
529 strv_sort(m->environment);
534 int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
539 assert(running_as >= 0);
540 assert(running_as < _SYSTEMD_RUNNING_AS_MAX);
542 m = new0(Manager, 1);
547 if (running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0)
548 boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
551 m->running_as = running_as;
552 m->exit_code = _MANAGER_EXIT_CODE_INVALID;
553 m->default_timer_accuracy_usec = USEC_PER_MINUTE;
555 m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
557 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;
558 m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
560 m->ask_password_inotify_fd = -1;
561 m->have_ask_password = -EINVAL; /* we don't know */
563 m->test_run = test_run;
565 r = manager_default_environment(m);
569 r = hashmap_ensure_allocated(&m->units, &string_hash_ops);
573 r = hashmap_ensure_allocated(&m->jobs, NULL);
577 r = hashmap_ensure_allocated(&m->cgroup_unit, &string_hash_ops);
581 r = hashmap_ensure_allocated(&m->watch_bus, &string_hash_ops);
585 r = set_ensure_allocated(&m->startup_units, NULL);
589 r = set_ensure_allocated(&m->failed_units, NULL);
593 r = sd_event_default(&m->event);
597 r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
601 r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
605 r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
609 r = manager_setup_signals(m);
613 r = manager_setup_cgroup(m);
617 r = manager_setup_time_change(m);
621 m->udev = udev_new();
627 /* Note that we set up neither kdbus, nor the notify fd
628 * here. We do that after deserialization, since they might
629 * have gotten serialized across the reexec. */
631 m->taint_usr = dir_is_empty("/usr") > 0;
641 static int manager_setup_notify(Manager *m) {
647 if (m->notify_fd < 0) {
648 _cleanup_close_ int fd = -1;
649 union sockaddr_union sa = {
650 .sa.sa_family = AF_UNIX,
652 static const int one = 1;
654 /* First free all secondary fields */
655 free(m->notify_socket);
656 m->notify_socket = NULL;
657 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
659 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
661 log_error("Failed to allocate notification socket: %m");
665 if (m->running_as == SYSTEMD_SYSTEM)
666 m->notify_socket = strdup("/run/systemd/notify");
670 e = getenv("XDG_RUNTIME_DIR");
672 log_error("XDG_RUNTIME_DIR is not set: %m");
676 m->notify_socket = strappend(e, "/systemd/notify");
678 if (!m->notify_socket)
681 (void) mkdir_parents_label(m->notify_socket, 0755);
682 (void) unlink(m->notify_socket);
684 strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
685 r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
687 log_error("bind(%s) failed: %m", sa.un.sun_path);
691 r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
693 log_error("SO_PASSCRED failed: %m");
700 log_debug("Using notification socket %s", m->notify_socket);
703 if (!m->notify_event_source) {
704 r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_dispatch_notify_fd, m);
706 log_error("Failed to allocate notify event source: %s", strerror(-r));
710 /* Process signals a bit earlier than SIGCHLD, so that we can
711 * still identify to which service an exit message belongs */
712 r = sd_event_source_set_priority(m->notify_event_source, -7);
714 log_error("Failed to set priority of notify event source: %s", strerror(-r));
722 static int manager_setup_kdbus(Manager *m) {
724 _cleanup_free_ char *p = NULL;
728 if (m->test_run || m->kdbus_fd >= 0)
731 m->kdbus_fd = bus_kernel_create_bus(m->running_as == SYSTEMD_SYSTEM ? "system" : "user", m->running_as == SYSTEMD_SYSTEM, &p);
732 if (m->kdbus_fd < 0) {
733 log_debug("Failed to set up kdbus: %s", strerror(-m->kdbus_fd));
737 log_debug("Successfully set up kdbus on %s", p);
739 /* Create the namespace directory here, so that the contents
740 * of that directory is not visible to non-root users. This is
741 * necessary to ensure that users cannot get access to busses
742 * of virtualized users when no UID namespacing is used. */
743 if (m->running_as == SYSTEMD_SYSTEM)
744 mkdir_p_label("/dev/kdbus/domain", 0700);
750 static int manager_connect_bus(Manager *m, bool reexecuting) {
751 bool try_bus_connect;
761 (m->running_as == SYSTEMD_USER && getenv("DBUS_SESSION_BUS_ADDRESS"));
763 /* Try to connect to the busses, if possible. */
764 return bus_init(m, try_bus_connect);
767 static unsigned manager_dispatch_cleanup_queue(Manager *m) {
773 while ((u = m->cleanup_queue)) {
774 assert(u->in_cleanup_queue);
784 GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
785 GC_OFFSET_UNSURE, /* No clue */
786 GC_OFFSET_GOOD, /* We still need this unit */
787 GC_OFFSET_BAD, /* We don't need this unit anymore */
791 static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
798 if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
799 u->gc_marker == gc_marker + GC_OFFSET_BAD ||
800 u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
803 if (u->in_cleanup_queue)
806 if (unit_check_gc(u))
809 u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
813 SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
814 unit_gc_sweep(other, gc_marker);
816 if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
819 if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
826 /* We were unable to find anything out about this entry, so
827 * let's investigate it later */
828 u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
829 unit_add_to_gc_queue(u);
833 /* We definitely know that this one is not useful anymore, so
834 * let's mark it for deletion */
835 u->gc_marker = gc_marker + GC_OFFSET_BAD;
836 unit_add_to_cleanup_queue(u);
840 u->gc_marker = gc_marker + GC_OFFSET_GOOD;
843 static unsigned manager_dispatch_gc_queue(Manager *m) {
850 /* log_debug("Running GC..."); */
852 m->gc_marker += _GC_OFFSET_MAX;
853 if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
856 gc_marker = m->gc_marker;
858 while ((u = m->gc_queue)) {
859 assert(u->in_gc_queue);
861 unit_gc_sweep(u, gc_marker);
863 LIST_REMOVE(gc_queue, m->gc_queue, u);
864 u->in_gc_queue = false;
868 if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
869 u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
870 log_debug_unit(u->id, "Collecting %s", u->id);
871 u->gc_marker = gc_marker + GC_OFFSET_BAD;
872 unit_add_to_cleanup_queue(u);
876 m->n_in_gc_queue = 0;
881 static void manager_clear_jobs_and_units(Manager *m) {
886 while ((u = hashmap_first(m->units)))
889 manager_dispatch_cleanup_queue(m);
891 assert(!m->load_queue);
892 assert(!m->run_queue);
893 assert(!m->dbus_unit_queue);
894 assert(!m->dbus_job_queue);
895 assert(!m->cleanup_queue);
896 assert(!m->gc_queue);
898 assert(hashmap_isempty(m->jobs));
899 assert(hashmap_isempty(m->units));
902 m->n_running_jobs = 0;
905 void manager_free(Manager *m) {
911 manager_clear_jobs_and_units(m);
913 for (c = 0; c < _UNIT_TYPE_MAX; c++)
914 if (unit_vtable[c]->shutdown)
915 unit_vtable[c]->shutdown(m);
917 /* If we reexecute ourselves, we keep the root cgroup
919 manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
921 manager_undo_generators(m);
925 hashmap_free(m->units);
926 hashmap_free(m->jobs);
927 hashmap_free(m->watch_pids1);
928 hashmap_free(m->watch_pids2);
929 hashmap_free(m->watch_bus);
931 set_free(m->startup_units);
932 set_free(m->failed_units);
934 sd_event_source_unref(m->signal_event_source);
935 sd_event_source_unref(m->notify_event_source);
936 sd_event_source_unref(m->time_change_event_source);
937 sd_event_source_unref(m->jobs_in_progress_event_source);
938 sd_event_source_unref(m->idle_pipe_event_source);
939 sd_event_source_unref(m->run_queue_event_source);
941 safe_close(m->signal_fd);
942 safe_close(m->notify_fd);
943 safe_close(m->time_change_fd);
944 safe_close(m->kdbus_fd);
946 manager_close_ask_password(m);
948 manager_close_idle_pipe(m);
951 sd_event_unref(m->event);
953 free(m->notify_socket);
955 lookup_paths_free(&m->lookup_paths);
956 strv_free(m->environment);
958 hashmap_free(m->cgroup_unit);
959 set_free_free(m->unit_path_cache);
961 free(m->switch_root);
962 free(m->switch_root_init);
964 for (i = 0; i < _RLIMIT_MAX; i++)
967 assert(hashmap_isempty(m->units_requiring_mounts_for));
968 hashmap_free(m->units_requiring_mounts_for);
973 int manager_enumerate(Manager *m) {
979 /* Let's ask every type to load all units from disk/kernel
980 * that it might know */
981 for (c = 0; c < _UNIT_TYPE_MAX; c++)
982 if (unit_vtable[c]->enumerate) {
983 q = unit_vtable[c]->enumerate(m);
988 manager_dispatch_load_queue(m);
992 static int manager_coldplug(Manager *m) {
1000 /* Then, let's set up their initial state. */
1001 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
1004 /* ignore aliases */
1008 q = unit_coldplug(u);
1016 static void manager_build_unit_path_cache(Manager *m) {
1018 _cleanup_closedir_ DIR *d = NULL;
1023 set_free_free(m->unit_path_cache);
1025 m->unit_path_cache = set_new(&string_hash_ops);
1026 if (!m->unit_path_cache) {
1027 log_error("Failed to allocate unit path cache.");
1031 /* This simply builds a list of files we know exist, so that
1032 * we don't always have to go to disk */
1034 STRV_FOREACH(i, m->lookup_paths.unit_path) {
1039 if (errno != ENOENT)
1040 log_error("Failed to open directory %s: %m", *i);
1044 while ((de = readdir(d))) {
1047 if (ignore_file(de->d_name))
1050 p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
1056 r = set_consume(m->unit_path_cache, p);
1068 log_error("Failed to build unit path cache: %s", strerror(-r));
1070 set_free_free(m->unit_path_cache);
1071 m->unit_path_cache = NULL;
1075 static int manager_distribute_fds(Manager *m, FDSet *fds) {
1082 HASHMAP_FOREACH(u, m->units, i) {
1084 if (fdset_size(fds) <= 0)
1087 if (UNIT_VTABLE(u)->distribute_fds) {
1088 r = UNIT_VTABLE(u)->distribute_fds(u, fds);
1097 int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
1102 dual_timestamp_get(&m->generators_start_timestamp);
1103 manager_run_generators(m);
1104 dual_timestamp_get(&m->generators_finish_timestamp);
1106 r = lookup_paths_init(
1107 &m->lookup_paths, m->running_as, true,
1109 m->generator_unit_path,
1110 m->generator_unit_path_early,
1111 m->generator_unit_path_late);
1115 manager_build_unit_path_cache(m);
1117 /* If we will deserialize make sure that during enumeration
1118 * this is already known, so we increase the counter here
1123 /* First, enumerate what we can from all config files */
1124 dual_timestamp_get(&m->units_load_start_timestamp);
1125 r = manager_enumerate(m);
1126 dual_timestamp_get(&m->units_load_finish_timestamp);
1128 /* Second, deserialize if there is something to deserialize */
1130 r = manager_deserialize(m, serialization, fds);
1132 /* Any fds left? Find some unit which wants them. This is
1133 * useful to allow container managers to pass some file
1134 * descriptors to us pre-initialized. This enables
1135 * socket-based activation of entire containers. */
1136 if (fdset_size(fds) > 0) {
1137 q = manager_distribute_fds(m, fds);
1138 if (q < 0 && r == 0)
1142 /* We might have deserialized the notify fd, but if we didn't
1143 * then let's create the bus now */
1144 q = manager_setup_notify(m);
1145 if (q < 0 && r == 0)
1148 /* We might have deserialized the kdbus control fd, but if we
1149 * didn't, then let's create the bus now. */
1150 manager_setup_kdbus(m);
1151 manager_connect_bus(m, !!serialization);
1152 bus_track_coldplug(m, &m->subscribed, &m->deserialized_subscribed);
1154 /* Third, fire things up! */
1155 q = manager_coldplug(m);
1156 if (q < 0 && r == 0)
1159 if (serialization) {
1160 assert(m->n_reloading > 0);
1163 /* Let's wait for the UnitNew/JobNew messages being
1164 * sent, before we notify that the reload is
1166 m->send_reloading_done = true;
1172 int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
1177 assert(type < _JOB_TYPE_MAX);
1179 assert(mode < _JOB_MODE_MAX);
1181 if (mode == JOB_ISOLATE && type != JOB_START)
1182 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start.");
1184 if (mode == JOB_ISOLATE && !unit->allow_isolate)
1185 return sd_bus_error_setf(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
1187 log_debug_unit(unit->id,
1188 "Trying to enqueue job %s/%s/%s", unit->id,
1189 job_type_to_string(type), job_mode_to_string(mode));
1191 job_type_collapse(&type, unit);
1193 tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
1197 r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
1198 mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
1199 mode == JOB_IGNORE_DEPENDENCIES, e);
1203 if (mode == JOB_ISOLATE) {
1204 r = transaction_add_isolate_jobs(tr, m);
1209 r = transaction_activate(tr, m, mode, e);
1213 log_debug_unit(unit->id,
1214 "Enqueued job %s/%s as %u", unit->id,
1215 job_type_to_string(type), (unsigned) tr->anchor_job->id);
1218 *_ret = tr->anchor_job;
1220 transaction_free(tr);
1224 transaction_abort(tr);
1225 transaction_free(tr);
1229 int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
1234 assert(type < _JOB_TYPE_MAX);
1236 assert(mode < _JOB_MODE_MAX);
1238 r = manager_load_unit(m, name, NULL, NULL, &unit);
1242 return manager_add_job(m, type, unit, mode, override, e, _ret);
1245 Job *manager_get_job(Manager *m, uint32_t id) {
1248 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
1251 Unit *manager_get_unit(Manager *m, const char *name) {
1255 return hashmap_get(m->units, name);
1258 unsigned manager_dispatch_load_queue(Manager *m) {
1264 /* Make sure we are not run recursively */
1265 if (m->dispatching_load_queue)
1268 m->dispatching_load_queue = true;
1270 /* Dispatches the load queue. Takes a unit from the queue and
1271 * tries to load its data until the queue is empty */
1273 while ((u = m->load_queue)) {
1274 assert(u->in_load_queue);
1280 m->dispatching_load_queue = false;
1284 int manager_load_unit_prepare(
1296 assert(name || path);
1298 /* This will prepare the unit for loading, but not actually
1299 * load anything from disk. */
1301 if (path && !is_path(path))
1302 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
1305 name = basename(path);
1307 t = unit_name_to_type(name);
1309 if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid(name, TEMPLATE_INVALID))
1310 return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is not valid.", name);
1312 ret = manager_get_unit(m, name);
1318 ret = unit_new(m, unit_vtable[t]->object_size);
1323 ret->fragment_path = strdup(path);
1324 if (!ret->fragment_path) {
1330 r = unit_add_name(ret, name);
1336 unit_add_to_load_queue(ret);
1337 unit_add_to_dbus_queue(ret);
1338 unit_add_to_gc_queue(ret);
1346 int manager_load_unit(
1357 /* This will load the service information files, but not actually
1358 * start any services or anything. */
1360 r = manager_load_unit_prepare(m, name, path, e, _ret);
1364 manager_dispatch_load_queue(m);
1367 *_ret = unit_follow_merge(*_ret);
1372 void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
1379 HASHMAP_FOREACH(j, s->jobs, i)
1380 job_dump(j, f, prefix);
1383 void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
1391 HASHMAP_FOREACH_KEY(u, t, s->units, i)
1393 unit_dump(u, f, prefix);
1396 void manager_clear_jobs(Manager *m) {
1401 while ((j = hashmap_first(m->jobs)))
1402 /* No need to recurse. We're cancelling all jobs. */
1403 job_finish_and_invalidate(j, JOB_CANCELED, false);
1406 static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
1407 Manager *m = userdata;
1413 while ((j = m->run_queue)) {
1414 assert(j->installed);
1415 assert(j->in_run_queue);
1417 job_run_and_invalidate(j);
1420 if (m->n_running_jobs > 0)
1421 manager_watch_jobs_in_progress(m);
1423 if (m->n_on_console > 0)
1424 manager_watch_idle_pipe(m);
1429 static unsigned manager_dispatch_dbus_queue(Manager *m) {
1436 if (m->dispatching_dbus_queue)
1439 m->dispatching_dbus_queue = true;
1441 while ((u = m->dbus_unit_queue)) {
1442 assert(u->in_dbus_queue);
1444 bus_unit_send_change_signal(u);
1448 while ((j = m->dbus_job_queue)) {
1449 assert(j->in_dbus_queue);
1451 bus_job_send_change_signal(j);
1455 m->dispatching_dbus_queue = false;
1457 if (m->send_reloading_done) {
1458 m->send_reloading_done = false;
1460 bus_manager_send_reloading(m, false);
1463 if (m->queued_message)
1464 bus_send_queued_message(m);
1469 static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, char *buf, size_t n) {
1470 _cleanup_strv_free_ char **tags = NULL;
1477 tags = strv_split(buf, "\n\r");
1483 log_debug_unit(u->id, "Got notification message for unit %s", u->id);
1485 if (UNIT_VTABLE(u)->notify_message)
1486 UNIT_VTABLE(u)->notify_message(u, pid, tags);
1489 static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1490 Manager *m = userdata;
1494 assert(m->notify_fd == fd);
1496 if (revents != EPOLLIN) {
1497 log_warning("Got unexpected poll event for notify fd.");
1503 struct iovec iovec = {
1505 .iov_len = sizeof(buf)-1,
1510 struct cmsghdr cmsghdr;
1511 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
1514 struct msghdr msghdr = {
1517 .msg_control = &control,
1518 .msg_controllen = sizeof(control),
1520 struct ucred *ucred;
1523 n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT);
1528 if (errno == EAGAIN || errno == EINTR)
1534 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
1535 control.cmsghdr.cmsg_level != SOL_SOCKET ||
1536 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
1537 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
1538 log_warning("Received notify message without credentials. Ignoring.");
1542 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
1544 assert((size_t) n < sizeof(buf));
1547 /* Notify every unit that might be interested, but try
1548 * to avoid notifying the same one multiple times. */
1549 u1 = manager_get_unit_by_pid(m, ucred->pid);
1551 manager_invoke_notify_message(m, u1, ucred->pid, buf, n);
1555 u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(ucred->pid));
1556 if (u2 && u2 != u1) {
1557 manager_invoke_notify_message(m, u2, ucred->pid, buf, n);
1561 u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(ucred->pid));
1562 if (u3 && u3 != u2 && u3 != u1) {
1563 manager_invoke_notify_message(m, u3, ucred->pid, buf, n);
1568 log_warning("Cannot find unit for notify message of PID "PID_FMT".", ucred->pid);
1574 static void invoke_sigchld_event(Manager *m, Unit *u, siginfo_t *si) {
1579 log_debug_unit(u->id, "Child "PID_FMT" belongs to %s", si->si_pid, u->id);
1581 unit_unwatch_pid(u, si->si_pid);
1582 UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
1585 static int manager_dispatch_sigchld(Manager *m) {
1591 /* First we call waitd() for a PID and do not reap the
1592 * zombie. That way we can still access /proc/$PID for
1593 * it while it is a zombie. */
1594 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
1596 if (errno == ECHILD)
1608 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
1609 _cleanup_free_ char *name = NULL;
1612 get_process_comm(si.si_pid, &name);
1614 log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)",
1615 si.si_pid, strna(name),
1616 sigchld_code_to_string(si.si_code),
1618 strna(si.si_code == CLD_EXITED
1619 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
1620 : signal_to_string(si.si_status)));
1622 /* And now figure out the unit this belongs
1623 * to, it might be multiple... */
1624 u1 = manager_get_unit_by_pid(m, si.si_pid);
1626 invoke_sigchld_event(m, u1, &si);
1627 u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(si.si_pid));
1629 invoke_sigchld_event(m, u2, &si);
1630 u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(si.si_pid));
1631 if (u3 && u3 != u2 && u3 != u1)
1632 invoke_sigchld_event(m, u3, &si);
1635 /* And now, we actually reap the zombie. */
1636 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
1647 static int manager_start_target(Manager *m, const char *name, JobMode mode) {
1648 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1651 log_debug_unit(name, "Activating special unit %s", name);
1653 r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL);
1655 log_error_unit(name, "Failed to enqueue %s job: %s", name, bus_error_message(&error, r));
1660 static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1661 Manager *m = userdata;
1663 struct signalfd_siginfo sfsi;
1664 bool sigchld = false;
1667 assert(m->signal_fd == fd);
1669 if (revents != EPOLLIN) {
1670 log_warning("Got unexpected events from signal file descriptor.");
1675 n = read(m->signal_fd, &sfsi, sizeof(sfsi));
1676 if (n != sizeof(sfsi)) {
1681 if (errno == EINTR || errno == EAGAIN)
1687 log_received_signal(sfsi.ssi_signo == SIGCHLD ||
1688 (sfsi.ssi_signo == SIGTERM && m->running_as == SYSTEMD_USER)
1689 ? LOG_DEBUG : LOG_INFO,
1692 switch (sfsi.ssi_signo) {
1699 if (m->running_as == SYSTEMD_SYSTEM) {
1700 /* This is for compatibility with the
1701 * original sysvinit */
1702 m->exit_code = MANAGER_REEXECUTE;
1709 if (m->running_as == SYSTEMD_SYSTEM) {
1710 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
1714 /* Run the exit target if there is one, if not, just exit. */
1715 if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
1716 m->exit_code = MANAGER_EXIT;
1723 if (m->running_as == SYSTEMD_SYSTEM)
1724 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
1726 /* This is a nop on non-init */
1730 if (m->running_as == SYSTEMD_SYSTEM)
1731 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
1733 /* This is a nop on non-init */
1739 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
1741 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
1742 log_info("Trying to reconnect to bus...");
1746 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
1747 log_info("Loading D-Bus service...");
1748 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
1755 _cleanup_free_ char *dump = NULL;
1756 _cleanup_fclose_ FILE *f = NULL;
1759 f = open_memstream(&dump, &size);
1761 log_warning("Failed to allocate memory stream.");
1765 manager_dump_units(m, f, "\t");
1766 manager_dump_jobs(m, f, "\t");
1769 log_warning("Failed to write status stream");
1774 log_warning("Failed to flush status stream");
1778 log_dump(LOG_INFO, dump);
1783 m->exit_code = MANAGER_RELOAD;
1788 /* Starting SIGRTMIN+0 */
1789 static const char * const target_table[] = {
1790 [0] = SPECIAL_DEFAULT_TARGET,
1791 [1] = SPECIAL_RESCUE_TARGET,
1792 [2] = SPECIAL_EMERGENCY_TARGET,
1793 [3] = SPECIAL_HALT_TARGET,
1794 [4] = SPECIAL_POWEROFF_TARGET,
1795 [5] = SPECIAL_REBOOT_TARGET,
1796 [6] = SPECIAL_KEXEC_TARGET
1799 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
1800 static const ManagerExitCode code_table[] = {
1802 [1] = MANAGER_POWEROFF,
1803 [2] = MANAGER_REBOOT,
1807 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
1808 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
1809 int idx = (int) sfsi.ssi_signo - SIGRTMIN;
1810 manager_start_target(m, target_table[idx],
1811 (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
1815 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
1816 (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
1817 m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
1821 switch (sfsi.ssi_signo - SIGRTMIN) {
1824 log_debug("Enabling showing of status.");
1825 manager_set_show_status(m, SHOW_STATUS_YES);
1829 log_debug("Disabling showing of status.");
1830 manager_set_show_status(m, SHOW_STATUS_NO);
1834 log_set_max_level(LOG_DEBUG);
1835 log_notice("Setting log level to debug.");
1839 log_set_max_level(LOG_INFO);
1840 log_notice("Setting log level to info.");
1844 if (m->running_as == SYSTEMD_USER) {
1845 m->exit_code = MANAGER_EXIT;
1849 /* This is a nop on init */
1853 case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
1854 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1855 log_notice("Setting log target to journal-or-kmsg.");
1859 log_set_target(LOG_TARGET_CONSOLE);
1860 log_notice("Setting log target to console.");
1864 log_set_target(LOG_TARGET_KMSG);
1865 log_notice("Setting log target to kmsg.");
1869 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
1876 manager_dispatch_sigchld(m);
1881 static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1882 Manager *m = userdata;
1887 assert(m->time_change_fd == fd);
1889 log_struct(LOG_INFO,
1890 MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
1891 "MESSAGE=Time has been changed",
1894 /* Restart the watch */
1895 m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
1896 m->time_change_fd = safe_close(m->time_change_fd);
1898 manager_setup_time_change(m);
1900 HASHMAP_FOREACH(u, m->units, i)
1901 if (UNIT_VTABLE(u)->time_change)
1902 UNIT_VTABLE(u)->time_change(u);
1907 static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1908 Manager *m = userdata;
1911 assert(m->idle_pipe[2] == fd);
1913 m->no_console_output = m->n_on_console > 0;
1915 m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
1916 manager_close_idle_pipe(m);
1921 static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
1922 Manager *m = userdata;
1929 manager_print_jobs_in_progress(m);
1931 next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
1932 r = sd_event_source_set_time(source, next);
1936 return sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
1939 int manager_loop(Manager *m) {
1942 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
1945 m->exit_code = MANAGER_OK;
1947 /* Release the path cache */
1948 set_free_free(m->unit_path_cache);
1949 m->unit_path_cache = NULL;
1951 manager_check_finished(m);
1953 /* There might still be some zombies hanging around from
1954 * before we were exec()'ed. Let's reap them. */
1955 r = manager_dispatch_sigchld(m);
1959 while (m->exit_code == MANAGER_OK) {
1962 if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
1965 if (!ratelimit_test(&rl)) {
1966 /* Yay, something is going seriously wrong, pause a little */
1967 log_warning("Looping too fast. Throttling execution a little.");
1972 if (manager_dispatch_load_queue(m) > 0)
1975 if (manager_dispatch_gc_queue(m) > 0)
1978 if (manager_dispatch_cleanup_queue(m) > 0)
1981 if (manager_dispatch_cgroup_queue(m) > 0)
1984 if (manager_dispatch_dbus_queue(m) > 0)
1987 /* Sleep for half the watchdog time */
1988 if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM) {
1989 wait_usec = m->runtime_watchdog / 2;
1993 wait_usec = USEC_INFINITY;
1995 r = sd_event_run(m->event, wait_usec);
1997 log_error("Failed to run event loop: %s", strerror(-r));
2002 return m->exit_code;
2005 int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u) {
2006 _cleanup_free_ char *n = NULL;
2014 r = unit_name_from_dbus_path(s, &n);
2018 r = manager_load_unit(m, n, NULL, e, &u);
2027 int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
2037 p = startswith(s, "/org/freedesktop/systemd1/job/");
2041 r = safe_atou(p, &id);
2045 j = manager_get_job(m, id);
2054 void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
2057 _cleanup_free_ char *p = NULL;
2061 audit_fd = get_audit_fd();
2065 /* Don't generate audit events if the service was already
2066 * started and we're just deserializing */
2067 if (m->n_reloading > 0)
2070 if (m->running_as != SYSTEMD_SYSTEM)
2073 if (u->type != UNIT_SERVICE)
2076 p = unit_name_to_prefix_and_instance(u->id);
2082 msg = strappenda("unit=", p);
2084 if (audit_log_user_comm_message(audit_fd, type, msg, "systemd", NULL, NULL, NULL, success) < 0) {
2086 /* We aren't allowed to send audit messages?
2087 * Then let's not retry again. */
2090 log_warning("Failed to send audit message: %m");
2096 void manager_send_unit_plymouth(Manager *m, Unit *u) {
2097 union sockaddr_union sa = PLYMOUTH_SOCKET;
2100 _cleanup_free_ char *message = NULL;
2101 _cleanup_close_ int fd = -1;
2103 /* Don't generate plymouth events if the service was already
2104 * started and we're just deserializing */
2105 if (m->n_reloading > 0)
2108 if (m->running_as != SYSTEMD_SYSTEM)
2111 if (detect_container(NULL) > 0)
2114 if (u->type != UNIT_SERVICE &&
2115 u->type != UNIT_MOUNT &&
2116 u->type != UNIT_SWAP)
2119 /* We set SOCK_NONBLOCK here so that we rather drop the
2120 * message then wait for plymouth */
2121 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
2123 log_error("socket() failed: %m");
2127 if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
2129 if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
2130 log_error("connect() failed: %m");
2134 if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
2140 if (write(fd, message, n + 1) != n + 1)
2141 if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
2142 log_error("Failed to write Plymouth message: %m");
2145 void manager_dispatch_bus_name_owner_changed(
2148 const char* old_owner,
2149 const char *new_owner) {
2156 u = hashmap_get(m->watch_bus, name);
2160 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
2163 int manager_open_serialization(Manager *m, FILE **_f) {
2170 path = m->running_as == SYSTEMD_SYSTEM ? "/run/systemd" : "/tmp";
2171 fd = open_tmpfile(path, O_RDWR|O_CLOEXEC);
2175 log_debug("Serializing state to %s", path);
2177 f = fdopen(fd, "w+");
2188 int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
2201 fprintf(f, "current-job-id=%i\n", m->current_job_id);
2202 fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
2203 fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
2204 fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
2206 dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp);
2207 dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp);
2208 dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp);
2209 dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
2212 dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp);
2213 dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
2214 dual_timestamp_serialize(f, "security-start-timestamp", &m->security_start_timestamp);
2215 dual_timestamp_serialize(f, "security-finish-timestamp", &m->security_finish_timestamp);
2216 dual_timestamp_serialize(f, "generators-start-timestamp", &m->generators_start_timestamp);
2217 dual_timestamp_serialize(f, "generators-finish-timestamp", &m->generators_finish_timestamp);
2218 dual_timestamp_serialize(f, "units-load-start-timestamp", &m->units_load_start_timestamp);
2219 dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp);
2222 if (!switching_root) {
2223 STRV_FOREACH(e, m->environment) {
2224 _cleanup_free_ char *ce;
2230 fprintf(f, "env=%s\n", *e);
2234 if (m->notify_fd >= 0) {
2237 copy = fdset_put_dup(fds, m->notify_fd);
2241 fprintf(f, "notify-fd=%i\n", copy);
2242 fprintf(f, "notify-socket=%s\n", m->notify_socket);
2245 if (m->kdbus_fd >= 0) {
2248 copy = fdset_put_dup(fds, m->kdbus_fd);
2252 fprintf(f, "kdbus-fd=%i\n", copy);
2255 bus_track_serialize(m->subscribed, f);
2259 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
2267 r = unit_serialize(u, f, fds, !switching_root);
2274 assert(m->n_reloading > 0);
2280 r = bus_fdset_add_all(m, fds);
2287 int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
2293 log_debug("Deserializing state...");
2298 char line[LINE_MAX], *l;
2300 if (!fgets(line, sizeof(line), f)) {
2315 if (startswith(l, "current-job-id=")) {
2318 if (safe_atou32(l+15, &id) < 0)
2319 log_warning("Failed to parse current job id value %s", l+15);
2321 m->current_job_id = MAX(m->current_job_id, id);
2323 } else if (startswith(l, "n-installed-jobs=")) {
2326 if (safe_atou32(l+17, &n) < 0)
2327 log_warning("Failed to parse installed jobs counter %s", l+17);
2329 m->n_installed_jobs += n;
2331 } else if (startswith(l, "n-failed-jobs=")) {
2334 if (safe_atou32(l+14, &n) < 0)
2335 log_warning("Failed to parse failed jobs counter %s", l+14);
2337 m->n_failed_jobs += n;
2339 } else if (startswith(l, "taint-usr=")) {
2342 b = parse_boolean(l+10);
2344 log_warning("Failed to parse taint /usr flag %s", l+10);
2346 m->taint_usr = m->taint_usr || b;
2348 } else if (startswith(l, "firmware-timestamp="))
2349 dual_timestamp_deserialize(l+19, &m->firmware_timestamp);
2350 else if (startswith(l, "loader-timestamp="))
2351 dual_timestamp_deserialize(l+17, &m->loader_timestamp);
2352 else if (startswith(l, "kernel-timestamp="))
2353 dual_timestamp_deserialize(l+17, &m->kernel_timestamp);
2354 else if (startswith(l, "initrd-timestamp="))
2355 dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
2356 else if (startswith(l, "userspace-timestamp="))
2357 dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
2358 else if (startswith(l, "finish-timestamp="))
2359 dual_timestamp_deserialize(l+17, &m->finish_timestamp);
2360 else if (startswith(l, "security-start-timestamp="))
2361 dual_timestamp_deserialize(l+25, &m->security_start_timestamp);
2362 else if (startswith(l, "security-finish-timestamp="))
2363 dual_timestamp_deserialize(l+26, &m->security_finish_timestamp);
2364 else if (startswith(l, "generators-start-timestamp="))
2365 dual_timestamp_deserialize(l+27, &m->generators_start_timestamp);
2366 else if (startswith(l, "generators-finish-timestamp="))
2367 dual_timestamp_deserialize(l+28, &m->generators_finish_timestamp);
2368 else if (startswith(l, "units-load-start-timestamp="))
2369 dual_timestamp_deserialize(l+27, &m->units_load_start_timestamp);
2370 else if (startswith(l, "units-load-finish-timestamp="))
2371 dual_timestamp_deserialize(l+28, &m->units_load_finish_timestamp);
2372 else if (startswith(l, "env=")) {
2373 _cleanup_free_ char *uce = NULL;
2376 uce = cunescape(l+4);
2382 e = strv_env_set(m->environment, uce);
2388 strv_free(m->environment);
2391 } else if (startswith(l, "notify-fd=")) {
2394 if (safe_atoi(l + 10, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
2395 log_warning("Failed to parse notify fd: %s", l + 10);
2397 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
2398 safe_close(m->notify_fd);
2399 m->notify_fd = fdset_remove(fds, fd);
2402 } else if (startswith(l, "notify-socket=")) {
2411 free(m->notify_socket);
2412 m->notify_socket = n;
2414 } else if (startswith(l, "kdbus-fd=")) {
2417 if (safe_atoi(l + 9, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
2418 log_warning("Failed to parse kdbus fd: %s", l + 9);
2420 safe_close(m->kdbus_fd);
2421 m->kdbus_fd = fdset_remove(fds, fd);
2424 } else if (bus_track_deserialize_item(&m->deserialized_subscribed, l) == 0)
2425 log_warning("Unknown serialization item '%s'", l);
2430 char name[UNIT_NAME_MAX+2];
2433 if (!fgets(name, sizeof(name), f)) {
2444 r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
2448 r = unit_deserialize(u, f, fds);
2457 assert(m->n_reloading > 0);
2463 int manager_reload(Manager *m) {
2465 _cleanup_fclose_ FILE *f = NULL;
2466 _cleanup_fdset_free_ FDSet *fds = NULL;
2470 r = manager_open_serialization(m, &f);
2475 bus_manager_send_reloading(m, true);
2483 r = manager_serialize(m, f, fds, false);
2489 if (fseeko(f, 0, SEEK_SET) < 0) {
2494 /* From here on there is no way back. */
2495 manager_clear_jobs_and_units(m);
2496 manager_undo_generators(m);
2497 lookup_paths_free(&m->lookup_paths);
2499 /* Find new unit paths */
2500 manager_run_generators(m);
2502 q = lookup_paths_init(
2503 &m->lookup_paths, m->running_as, true,
2505 m->generator_unit_path,
2506 m->generator_unit_path_early,
2507 m->generator_unit_path_late);
2511 manager_build_unit_path_cache(m);
2513 /* First, enumerate what we can from all config files */
2514 q = manager_enumerate(m);
2518 /* Second, deserialize our stored data */
2519 q = manager_deserialize(m, f, fds);
2526 /* Re-register notify_fd as event source */
2527 q = manager_setup_notify(m);
2531 /* Third, fire things up! */
2532 q = manager_coldplug(m);
2536 assert(m->n_reloading > 0);
2539 m->send_reloading_done = true;
2544 bool manager_is_reloading_or_reexecuting(Manager *m) {
2547 return m->n_reloading != 0;
2550 void manager_reset_failed(Manager *m) {
2556 HASHMAP_FOREACH(u, m->units, i)
2557 unit_reset_failed(u);
2560 bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
2566 /* Returns true if the unit is inactive or going down */
2567 u = manager_get_unit(m, name);
2571 return unit_inactive_or_pending(u);
2574 static void manager_notify_finished(Manager *m) {
2575 char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
2576 usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
2581 if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
2583 /* Note that m->kernel_usec.monotonic is always at 0,
2584 * and m->firmware_usec.monotonic and
2585 * m->loader_usec.monotonic should be considered
2586 * negative values. */
2588 firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic;
2589 loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic;
2590 userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
2591 total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic;
2593 if (dual_timestamp_is_set(&m->initrd_timestamp)) {
2595 kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
2596 initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
2598 log_struct(LOG_INFO,
2599 MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
2600 "KERNEL_USEC="USEC_FMT, kernel_usec,
2601 "INITRD_USEC="USEC_FMT, initrd_usec,
2602 "USERSPACE_USEC="USEC_FMT, userspace_usec,
2603 "MESSAGE=Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
2604 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2605 format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
2606 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2607 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
2610 kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
2613 log_struct(LOG_INFO,
2614 MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
2615 "KERNEL_USEC="USEC_FMT, kernel_usec,
2616 "USERSPACE_USEC="USEC_FMT, userspace_usec,
2617 "MESSAGE=Startup finished in %s (kernel) + %s (userspace) = %s.",
2618 format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
2619 format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
2620 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
2624 firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
2625 total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
2627 log_struct(LOG_INFO,
2628 MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
2629 "USERSPACE_USEC="USEC_FMT, userspace_usec,
2630 "MESSAGE=Startup finished in %s.",
2631 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
2635 bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
2639 "STATUS=Startup finished in %s.",
2640 format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
2643 void manager_check_finished(Manager *m) {
2649 if (m->n_running_jobs == 0)
2650 m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
2652 if (hashmap_size(m->jobs) > 0) {
2654 if (m->jobs_in_progress_event_source)
2655 sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
2660 manager_flip_auto_status(m, false);
2662 /* Notify Type=idle units that we are done now */
2663 m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
2664 manager_close_idle_pipe(m);
2666 /* Turn off confirm spawn now */
2667 m->confirm_spawn = false;
2669 /* No need to update ask password status when we're going non-interactive */
2670 manager_close_ask_password(m);
2672 /* This is no longer the first boot */
2673 manager_set_first_boot(m, false);
2675 if (dual_timestamp_is_set(&m->finish_timestamp))
2678 dual_timestamp_get(&m->finish_timestamp);
2680 manager_notify_finished(m);
2682 SET_FOREACH(u, m->startup_units, i)
2684 cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
2687 static int create_generator_dir(Manager *m, char **generator, const char *name) {
2698 if (m->running_as == SYSTEMD_SYSTEM && getpid() == 1) {
2699 /* systemd --system, not running --test */
2701 p = strappend("/run/systemd/", name);
2705 r = mkdir_p_label(p, 0755);
2707 log_error("Failed to create generator directory %s: %s",
2712 } else if (m->running_as == SYSTEMD_USER) {
2713 const char *s = NULL;
2715 s = getenv("XDG_RUNTIME_DIR");
2718 p = strjoin(s, "/systemd/", name, NULL);
2722 r = mkdir_p_label(p, 0755);
2724 log_error("Failed to create generator directory %s: %s",
2730 /* systemd --system --test */
2732 p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL);
2737 log_error("Failed to create generator directory %s: %m",
2748 static void trim_generator_dir(Manager *m, char **generator) {
2755 if (rmdir(*generator) >= 0) {
2763 void manager_run_generators(Manager *m) {
2764 _cleanup_closedir_ DIR *d = NULL;
2765 const char *generator_path;
2766 const char *argv[5];
2774 generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
2775 d = opendir(generator_path);
2777 if (errno == ENOENT)
2780 log_error("Failed to enumerate generator directory %s: %m",
2785 r = create_generator_dir(m, &m->generator_unit_path, "generator");
2789 r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early");
2793 r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late");
2797 argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
2798 argv[1] = m->generator_unit_path;
2799 argv[2] = m->generator_unit_path_early;
2800 argv[3] = m->generator_unit_path_late;
2803 RUN_WITH_UMASK(0022)
2804 execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv);
2807 trim_generator_dir(m, &m->generator_unit_path);
2808 trim_generator_dir(m, &m->generator_unit_path_early);
2809 trim_generator_dir(m, &m->generator_unit_path_late);
2812 static void remove_generator_dir(Manager *m, char **generator) {
2819 strv_remove(m->lookup_paths.unit_path, *generator);
2820 rm_rf(*generator, false, true, false);
2826 void manager_undo_generators(Manager *m) {
2829 remove_generator_dir(m, &m->generator_unit_path);
2830 remove_generator_dir(m, &m->generator_unit_path_early);
2831 remove_generator_dir(m, &m->generator_unit_path_late);
2834 int manager_environment_add(Manager *m, char **minus, char **plus) {
2835 char **a = NULL, **b = NULL, **l;
2840 if (!strv_isempty(minus)) {
2841 a = strv_env_delete(l, 1, minus);
2848 if (!strv_isempty(plus)) {
2849 b = strv_env_merge(2, l, plus);
2858 if (m->environment != l)
2859 strv_free(m->environment);
2866 manager_clean_environment(m);
2867 strv_sort(m->environment);
2872 int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
2877 for (i = 0; i < _RLIMIT_MAX; i++) {
2878 if (!default_rlimit[i])
2881 m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
2889 void manager_recheck_journal(Manager *m) {
2894 if (m->running_as != SYSTEMD_SYSTEM)
2897 u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
2898 if (u && SOCKET(u)->state != SOCKET_RUNNING) {
2899 log_close_journal();
2903 u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
2904 if (u && SERVICE(u)->state != SERVICE_RUNNING) {
2905 log_close_journal();
2909 /* Hmm, OK, so the socket is fully up and the service is up
2910 * too, then let's make use of the thing. */
2914 void manager_set_show_status(Manager *m, ShowStatus mode) {
2916 assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY));
2918 if (m->running_as != SYSTEMD_SYSTEM)
2921 m->show_status = mode;
2924 touch("/run/systemd/show-status");
2926 unlink("/run/systemd/show-status");
2929 static bool manager_get_show_status(Manager *m, StatusType type) {
2932 if (m->running_as != SYSTEMD_SYSTEM)
2935 if (m->no_console_output)
2938 if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
2941 /* If we cannot find out the status properly, just proceed. */
2942 if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
2945 if (m->show_status > 0)
2948 /* If Plymouth is running make sure we show the status, so
2949 * that there's something nice to see when people press Esc */
2950 return plymouth_running();
2953 void manager_set_first_boot(Manager *m, bool b) {
2956 if (m->running_as != SYSTEMD_SYSTEM)
2962 touch("/run/systemd/first-boot");
2964 unlink("/run/systemd/first-boot");
2967 void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
2970 if (!manager_get_show_status(m, type))
2973 /* XXX We should totally drop the check for ephemeral here
2974 * and thus effectively make 'Type=idle' pointless. */
2975 if (type == STATUS_TYPE_EPHEMERAL && m->n_on_console > 0)
2978 va_start(ap, format);
2979 status_vprintf(status, true, type == STATUS_TYPE_EPHEMERAL, format, ap);
2983 int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, Unit **_found) {
2984 _cleanup_free_ char *p = NULL;
2992 p = unit_name_from_path(path, suffix);
2996 found = manager_get_unit(m, p);
3006 Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
3007 char p[strlen(path)+1];
3013 path_kill_slashes(p);
3015 return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
3018 const char *manager_get_runtime_prefix(Manager *m) {
3021 return m->running_as == SYSTEMD_SYSTEM ?
3023 getenv("XDG_RUNTIME_DIR");
3026 ManagerState manager_state(Manager *m) {
3031 /* Did we ever finish booting? If not then we are still starting up */
3032 if (!dual_timestamp_is_set(&m->finish_timestamp)) {
3034 u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
3035 if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
3036 return MANAGER_INITIALIZING;
3038 return MANAGER_STARTING;
3041 /* Is the special shutdown target queued? If so, we are in shutdown state */
3042 u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
3043 if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))
3044 return MANAGER_STOPPING;
3046 /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
3047 u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
3048 if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
3049 (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
3050 return MANAGER_MAINTENANCE;
3052 u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
3053 if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
3054 (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
3055 return MANAGER_MAINTENANCE;
3057 /* Are there any failed units? If so, we are in degraded mode */
3058 if (set_size(m->failed_units) > 0)
3059 return MANAGER_DEGRADED;
3061 return MANAGER_RUNNING;
3064 static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
3065 [MANAGER_INITIALIZING] = "initializing",
3066 [MANAGER_STARTING] = "starting",
3067 [MANAGER_RUNNING] = "running",
3068 [MANAGER_DEGRADED] = "degraded",
3069 [MANAGER_MAINTENANCE] = "maintenance",
3070 [MANAGER_STOPPING] = "stopping",
3073 DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);