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/>.
25 #include <sys/epoll.h>
27 #include <sys/signalfd.h>
31 #include <sys/reboot.h>
32 #include <sys/ioctl.h>
36 #include <sys/types.h>
44 #include <systemd/sd-daemon.h>
47 #include "transaction.h"
54 #include "ratelimit.h"
56 #include "mount-setup.h"
57 #include "unit-name.h"
58 #include "dbus-unit.h"
61 #include "path-lookup.h"
63 #include "bus-errors.h"
64 #include "exit-status.h"
67 #include "cgroup-util.h"
68 #include "path-util.h"
70 /* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
71 #define GC_QUEUE_ENTRIES_MAX 16
73 /* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
74 #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
76 /* Where clients shall send notification messages to */
77 #define NOTIFY_SOCKET_SYSTEM "/run/systemd/notify"
78 #define NOTIFY_SOCKET_USER "@/org/freedesktop/systemd1/notify"
80 static int manager_setup_notify(Manager *m) {
83 struct sockaddr_un un;
85 struct epoll_event ev;
91 m->notify_watch.type = WATCH_NOTIFY;
92 if ((m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
93 log_error("Failed to allocate notification socket: %m");
98 sa.sa.sa_family = AF_UNIX;
101 snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET_USER "/%llu", random_ull());
103 unlink(NOTIFY_SOCKET_SYSTEM);
104 strncpy(sa.un.sun_path, NOTIFY_SOCKET_SYSTEM, sizeof(sa.un.sun_path));
107 if (sa.un.sun_path[0] == '@')
108 sa.un.sun_path[0] = 0;
111 r = bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
115 log_error("bind() failed: %m");
119 if (setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
120 log_error("SO_PASSCRED failed: %m");
126 ev.data.ptr = &m->notify_watch;
128 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0)
131 if (sa.un.sun_path[0] == 0)
132 sa.un.sun_path[0] = '@';
134 if (!(m->notify_socket = strdup(sa.un.sun_path)))
137 log_debug("Using notification socket %s", m->notify_socket);
142 static int enable_special_signals(Manager *m) {
147 /* Enable that we get SIGINT on control-alt-del. In containers
148 * this will fail with EPERM, so ignore that. */
149 if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM)
150 log_warning("Failed to enable ctrl-alt-del handling: %m");
152 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
154 /* Support systems without virtual console */
156 log_warning("Failed to open /dev/tty0: %m");
158 /* Enable that we get SIGWINCH on kbrequest */
159 if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
160 log_warning("Failed to enable kbrequest handling: %s", strerror(errno));
162 close_nointr_nofail(fd);
168 static int manager_setup_signals(Manager *m) {
170 struct epoll_event ev;
175 /* We are not interested in SIGSTOP and friends. */
177 sa.sa_handler = SIG_DFL;
178 sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
179 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
181 assert_se(sigemptyset(&mask) == 0);
183 sigset_add_many(&mask,
184 SIGCHLD, /* Child died */
185 SIGTERM, /* Reexecute daemon */
186 SIGHUP, /* Reload configuration */
187 SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
188 SIGUSR2, /* systemd: dump status */
189 SIGINT, /* Kernel sends us this on control-alt-del */
190 SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
191 SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
192 SIGRTMIN+0, /* systemd: start default.target */
193 SIGRTMIN+1, /* systemd: isolate rescue.target */
194 SIGRTMIN+2, /* systemd: isolate emergency.target */
195 SIGRTMIN+3, /* systemd: start halt.target */
196 SIGRTMIN+4, /* systemd: start poweroff.target */
197 SIGRTMIN+5, /* systemd: start reboot.target */
198 SIGRTMIN+6, /* systemd: start kexec.target */
199 SIGRTMIN+13, /* systemd: Immediate halt */
200 SIGRTMIN+14, /* systemd: Immediate poweroff */
201 SIGRTMIN+15, /* systemd: Immediate reboot */
202 SIGRTMIN+16, /* systemd: Immediate kexec */
203 SIGRTMIN+20, /* systemd: enable status messages */
204 SIGRTMIN+21, /* systemd: disable status messages */
205 SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
206 SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
207 SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
208 SIGRTMIN+27, /* systemd: set log target to console */
209 SIGRTMIN+28, /* systemd: set log target to kmsg */
210 SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */
212 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
214 m->signal_watch.type = WATCH_SIGNAL;
215 if ((m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0)
220 ev.data.ptr = &m->signal_watch;
222 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
225 if (m->running_as == MANAGER_SYSTEM)
226 return enable_special_signals(m);
231 static void manager_strip_environment(Manager *m) {
234 /* Remove variables from the inherited set that are part of
235 * the container interface:
236 * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */
237 strv_remove_prefix(m->environment, "container=");
238 strv_remove_prefix(m->environment, "container_");
240 /* Remove variables from the inherited set that are part of
241 * the initrd interface:
242 * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
243 strv_remove_prefix(m->environment, "RD_");
246 int manager_new(ManagerRunningAs running_as, Manager **_m) {
251 assert(running_as >= 0);
252 assert(running_as < _MANAGER_RUNNING_AS_MAX);
254 if (!(m = new0(Manager, 1)))
257 dual_timestamp_get(&m->startup_timestamp);
259 m->running_as = running_as;
260 m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
261 m->exit_code = _MANAGER_EXIT_CODE_INVALID;
262 m->pin_cgroupfs_fd = -1;
263 m->idle_pipe[0] = m->idle_pipe[1] = -1;
269 m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.fd = -1;
270 m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
272 m->environment = strv_copy(environ);
276 manager_strip_environment(m);
278 if (running_as == MANAGER_SYSTEM) {
279 m->default_controllers = strv_new("cpu", NULL);
280 if (!m->default_controllers)
284 if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
287 if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
290 if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func)))
293 if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func)))
296 if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func)))
299 if ((m->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
302 if ((r = lookup_paths_init(&m->lookup_paths, m->running_as, true)) < 0)
305 if ((r = manager_setup_signals(m)) < 0)
308 if ((r = manager_setup_cgroup(m)) < 0)
311 if ((r = manager_setup_notify(m)) < 0)
314 /* Try to connect to the busses, if possible. */
315 if ((r = bus_init(m, running_as != MANAGER_SYSTEM)) < 0)
319 if ((m->audit_fd = audit_open()) < 0 &&
320 /* If the kernel lacks netlink or audit support,
321 * don't worry about it. */
322 errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
323 log_error("Failed to connect to audit log: %m");
326 m->taint_usr = dir_is_empty("/usr") > 0;
336 static unsigned manager_dispatch_cleanup_queue(Manager *m) {
342 while ((u = m->cleanup_queue)) {
343 assert(u->in_cleanup_queue);
353 GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
354 GC_OFFSET_UNSURE, /* No clue */
355 GC_OFFSET_GOOD, /* We still need this unit */
356 GC_OFFSET_BAD, /* We don't need this unit anymore */
360 static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
367 if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
368 u->gc_marker == gc_marker + GC_OFFSET_BAD ||
369 u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
372 if (u->in_cleanup_queue)
375 if (unit_check_gc(u))
378 u->gc_marker = gc_marker + GC_OFFSET_IN_PATH;
382 SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
383 unit_gc_sweep(other, gc_marker);
385 if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
388 if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
395 /* We were unable to find anything out about this entry, so
396 * let's investigate it later */
397 u->gc_marker = gc_marker + GC_OFFSET_UNSURE;
398 unit_add_to_gc_queue(u);
402 /* We definitely know that this one is not useful anymore, so
403 * let's mark it for deletion */
404 u->gc_marker = gc_marker + GC_OFFSET_BAD;
405 unit_add_to_cleanup_queue(u);
409 u->gc_marker = gc_marker + GC_OFFSET_GOOD;
412 static unsigned manager_dispatch_gc_queue(Manager *m) {
419 if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) &&
420 (m->gc_queue_timestamp <= 0 ||
421 (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC)))
424 log_debug("Running GC...");
426 m->gc_marker += _GC_OFFSET_MAX;
427 if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
430 gc_marker = m->gc_marker;
432 while ((u = m->gc_queue)) {
433 assert(u->in_gc_queue);
435 unit_gc_sweep(u, gc_marker);
437 LIST_REMOVE(Unit, gc_queue, m->gc_queue, u);
438 u->in_gc_queue = false;
442 if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
443 u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
444 log_debug("Collecting %s", u->id);
445 u->gc_marker = gc_marker + GC_OFFSET_BAD;
446 unit_add_to_cleanup_queue(u);
450 m->n_in_gc_queue = 0;
451 m->gc_queue_timestamp = 0;
456 static void manager_clear_jobs_and_units(Manager *m) {
461 while ((u = hashmap_first(m->units)))
464 manager_dispatch_cleanup_queue(m);
466 assert(!m->load_queue);
467 assert(!m->run_queue);
468 assert(!m->dbus_unit_queue);
469 assert(!m->dbus_job_queue);
470 assert(!m->cleanup_queue);
471 assert(!m->gc_queue);
473 assert(hashmap_isempty(m->jobs));
474 assert(hashmap_isempty(m->units));
477 void manager_free(Manager *m) {
482 manager_clear_jobs_and_units(m);
484 for (c = 0; c < _UNIT_TYPE_MAX; c++)
485 if (unit_vtable[c]->shutdown)
486 unit_vtable[c]->shutdown(m);
488 /* If we reexecute ourselves, we keep the root cgroup
490 manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
492 manager_undo_generators(m);
496 hashmap_free(m->units);
497 hashmap_free(m->jobs);
498 hashmap_free(m->watch_pids);
499 hashmap_free(m->watch_bus);
501 if (m->epoll_fd >= 0)
502 close_nointr_nofail(m->epoll_fd);
503 if (m->signal_watch.fd >= 0)
504 close_nointr_nofail(m->signal_watch.fd);
505 if (m->notify_watch.fd >= 0)
506 close_nointr_nofail(m->notify_watch.fd);
509 if (m->audit_fd >= 0)
510 audit_close(m->audit_fd);
513 free(m->notify_socket);
515 lookup_paths_free(&m->lookup_paths);
516 strv_free(m->environment);
518 strv_free(m->default_controllers);
520 hashmap_free(m->cgroup_bondings);
521 set_free_free(m->unit_path_cache);
523 close_pipe(m->idle_pipe);
525 free(m->switch_root);
526 free(m->switch_root_init);
531 int manager_enumerate(Manager *m) {
537 /* Let's ask every type to load all units from disk/kernel
538 * that it might know */
539 for (c = 0; c < _UNIT_TYPE_MAX; c++)
540 if (unit_vtable[c]->enumerate)
541 if ((q = unit_vtable[c]->enumerate(m)) < 0)
544 manager_dispatch_load_queue(m);
548 int manager_coldplug(Manager *m) {
556 /* Then, let's set up their initial state. */
557 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
563 if ((q = unit_coldplug(u)) < 0)
570 static void manager_build_unit_path_cache(Manager *m) {
577 set_free_free(m->unit_path_cache);
579 if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) {
580 log_error("Failed to allocate unit path cache.");
584 /* This simply builds a list of files we know exist, so that
585 * we don't always have to go to disk */
587 STRV_FOREACH(i, m->lookup_paths.unit_path) {
590 if (!(d = opendir(*i))) {
591 log_error("Failed to open directory: %m");
595 while ((de = readdir(d))) {
598 if (ignore_file(de->d_name))
601 p = join(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
607 if ((r = set_put(m->unit_path_cache, p)) < 0) {
620 log_error("Failed to build unit path cache: %s", strerror(-r));
622 set_free_free(m->unit_path_cache);
623 m->unit_path_cache = NULL;
629 int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
634 manager_run_generators(m);
636 manager_build_unit_path_cache(m);
638 /* If we will deserialize make sure that during enumeration
639 * this is already known, so we increase the counter here
644 /* First, enumerate what we can from all config files */
645 r = manager_enumerate(m);
647 /* Second, deserialize if there is something to deserialize */
649 if ((q = manager_deserialize(m, serialization, fds)) < 0)
652 /* Third, fire things up! */
653 if ((q = manager_coldplug(m)) < 0)
657 assert(m->n_reloading > 0);
664 int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) {
669 assert(type < _JOB_TYPE_MAX);
671 assert(mode < _JOB_MODE_MAX);
673 if (mode == JOB_ISOLATE && type != JOB_START) {
674 dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start.");
678 if (mode == JOB_ISOLATE && !unit->allow_isolate) {
679 dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
683 log_debug("Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
685 job_type_collapse(&type, unit);
687 tr = transaction_new();
691 r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
692 mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
693 mode == JOB_IGNORE_DEPENDENCIES, e);
697 if (mode == JOB_ISOLATE) {
698 r = transaction_add_isolate_jobs(tr, m);
703 r = transaction_activate(tr, m, mode, e);
707 log_debug("Enqueued job %s/%s as %u", unit->id, job_type_to_string(type), (unsigned) tr->anchor_job->id);
710 *_ret = tr->anchor_job;
712 transaction_free(tr);
716 transaction_abort(tr);
717 transaction_free(tr);
721 int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) {
726 assert(type < _JOB_TYPE_MAX);
728 assert(mode < _JOB_MODE_MAX);
730 if ((r = manager_load_unit(m, name, NULL, NULL, &unit)) < 0)
733 return manager_add_job(m, type, unit, mode, override, e, _ret);
736 Job *manager_get_job(Manager *m, uint32_t id) {
739 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
742 Unit *manager_get_unit(Manager *m, const char *name) {
746 return hashmap_get(m->units, name);
749 unsigned manager_dispatch_load_queue(Manager *m) {
755 /* Make sure we are not run recursively */
756 if (m->dispatching_load_queue)
759 m->dispatching_load_queue = true;
761 /* Dispatches the load queue. Takes a unit from the queue and
762 * tries to load its data until the queue is empty */
764 while ((u = m->load_queue)) {
765 assert(u->in_load_queue);
771 m->dispatching_load_queue = false;
775 int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
781 assert(name || path);
783 /* This will prepare the unit for loading, but not actually
784 * load anything from disk. */
786 if (path && !is_path(path)) {
787 dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path);
792 name = path_get_file_name(path);
794 t = unit_name_to_type(name);
796 if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid_no_type(name, false)) {
797 dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
801 ret = manager_get_unit(m, name);
807 ret = unit_new(m, unit_vtable[t]->object_size);
812 ret->fragment_path = strdup(path);
813 if (!ret->fragment_path) {
819 if ((r = unit_add_name(ret, name)) < 0) {
824 unit_add_to_load_queue(ret);
825 unit_add_to_dbus_queue(ret);
826 unit_add_to_gc_queue(ret);
834 int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
839 /* This will load the service information files, but not actually
840 * start any services or anything. */
842 if ((r = manager_load_unit_prepare(m, name, path, e, _ret)) != 0)
845 manager_dispatch_load_queue(m);
848 *_ret = unit_follow_merge(*_ret);
853 void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
860 HASHMAP_FOREACH(j, s->jobs, i)
861 job_dump(j, f, prefix);
864 void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
872 HASHMAP_FOREACH_KEY(u, t, s->units, i)
874 unit_dump(u, f, prefix);
877 void manager_clear_jobs(Manager *m) {
882 while ((j = hashmap_first(m->jobs)))
883 /* No need to recurse. We're cancelling all jobs. */
884 job_finish_and_invalidate(j, JOB_CANCELED, false);
887 unsigned manager_dispatch_run_queue(Manager *m) {
891 if (m->dispatching_run_queue)
894 m->dispatching_run_queue = true;
896 while ((j = m->run_queue)) {
897 assert(j->installed);
898 assert(j->in_run_queue);
900 job_run_and_invalidate(j);
904 m->dispatching_run_queue = false;
908 unsigned manager_dispatch_dbus_queue(Manager *m) {
915 if (m->dispatching_dbus_queue)
918 m->dispatching_dbus_queue = true;
920 while ((u = m->dbus_unit_queue)) {
921 assert(u->in_dbus_queue);
923 bus_unit_send_change_signal(u);
927 while ((j = m->dbus_job_queue)) {
928 assert(j->in_dbus_queue);
930 bus_job_send_change_signal(j);
934 m->dispatching_dbus_queue = false;
938 static int manager_process_notify_fd(Manager *m) {
945 struct msghdr msghdr;
949 struct cmsghdr cmsghdr;
950 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
956 iovec.iov_base = buf;
957 iovec.iov_len = sizeof(buf)-1;
961 msghdr.msg_iov = &iovec;
962 msghdr.msg_iovlen = 1;
963 msghdr.msg_control = &control;
964 msghdr.msg_controllen = sizeof(control);
966 if ((n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT)) <= 0) {
970 if (errno == EAGAIN || errno == EINTR)
976 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
977 control.cmsghdr.cmsg_level != SOL_SOCKET ||
978 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
979 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
980 log_warning("Received notify message without credentials. Ignoring.");
984 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
986 if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid))))
987 if (!(u = cgroup_unit_by_pid(m, ucred->pid))) {
988 log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid);
992 assert((size_t) n < sizeof(buf));
994 if (!(tags = strv_split(buf, "\n\r")))
997 log_debug("Got notification message for unit %s", u->id);
999 if (UNIT_VTABLE(u)->notify_message)
1000 UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
1008 static int manager_dispatch_sigchld(Manager *m) {
1018 /* First we call waitd() for a PID and do not reap the
1019 * zombie. That way we can still access /proc/$PID for
1020 * it while it is a zombie. */
1021 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
1023 if (errno == ECHILD)
1035 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
1038 get_process_comm(si.si_pid, &name);
1039 log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
1043 /* Let's flush any message the dying child might still
1044 * have queued for us. This ensures that the process
1045 * still exists in /proc so that we can figure out
1046 * which cgroup and hence unit it belongs to. */
1047 if ((r = manager_process_notify_fd(m)) < 0)
1050 /* And now figure out the unit this belongs to */
1051 if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid))))
1052 u = cgroup_unit_by_pid(m, si.si_pid);
1054 /* And now, we actually reap the zombie. */
1055 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
1062 if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
1065 log_debug("Child %lu died (code=%s, status=%i/%s)",
1066 (long unsigned) si.si_pid,
1067 sigchld_code_to_string(si.si_code),
1069 strna(si.si_code == CLD_EXITED
1070 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
1071 : signal_to_string(si.si_status)));
1076 log_debug("Child %lu belongs to %s", (long unsigned) si.si_pid, u->id);
1078 hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid));
1079 UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
1085 static int manager_start_target(Manager *m, const char *name, JobMode mode) {
1089 dbus_error_init(&error);
1091 log_debug("Activating special unit %s", name);
1093 if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL)) < 0)
1094 log_error("Failed to enqueue %s job: %s", name, bus_error(&error, r));
1096 dbus_error_free(&error);
1101 static int manager_process_signal_fd(Manager *m) {
1103 struct signalfd_siginfo sfsi;
1104 bool sigchld = false;
1109 if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
1114 if (errno == EINTR || errno == EAGAIN)
1120 if (sfsi.ssi_pid > 0) {
1123 get_process_comm(sfsi.ssi_pid, &p);
1125 log_debug("Received SIG%s from PID %lu (%s).",
1126 signal_to_string(sfsi.ssi_signo),
1127 (unsigned long) sfsi.ssi_pid, strna(p));
1130 log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo));
1132 switch (sfsi.ssi_signo) {
1139 if (m->running_as == MANAGER_SYSTEM) {
1140 /* This is for compatibility with the
1141 * original sysvinit */
1142 m->exit_code = MANAGER_REEXECUTE;
1149 if (m->running_as == MANAGER_SYSTEM) {
1150 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
1154 /* Run the exit target if there is one, if not, just exit. */
1155 if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
1156 m->exit_code = MANAGER_EXIT;
1163 if (m->running_as == MANAGER_SYSTEM)
1164 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
1166 /* This is a nop on non-init */
1170 if (m->running_as == MANAGER_SYSTEM)
1171 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
1173 /* This is a nop on non-init */
1179 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
1181 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
1182 log_info("Trying to reconnect to bus...");
1186 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
1187 log_info("Loading D-Bus service...");
1188 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
1199 if (!(f = open_memstream(&dump, &size))) {
1200 log_warning("Failed to allocate memory stream.");
1204 manager_dump_units(m, f, "\t");
1205 manager_dump_jobs(m, f, "\t");
1210 log_warning("Failed to write status stream");
1215 log_dump(LOG_INFO, dump);
1222 m->exit_code = MANAGER_RELOAD;
1227 /* Starting SIGRTMIN+0 */
1228 static const char * const target_table[] = {
1229 [0] = SPECIAL_DEFAULT_TARGET,
1230 [1] = SPECIAL_RESCUE_TARGET,
1231 [2] = SPECIAL_EMERGENCY_TARGET,
1232 [3] = SPECIAL_HALT_TARGET,
1233 [4] = SPECIAL_POWEROFF_TARGET,
1234 [5] = SPECIAL_REBOOT_TARGET,
1235 [6] = SPECIAL_KEXEC_TARGET
1238 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
1239 static const ManagerExitCode code_table[] = {
1241 [1] = MANAGER_POWEROFF,
1242 [2] = MANAGER_REBOOT,
1246 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
1247 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
1248 int idx = (int) sfsi.ssi_signo - SIGRTMIN;
1249 manager_start_target(m, target_table[idx],
1250 (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
1254 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
1255 (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
1256 m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
1260 switch (sfsi.ssi_signo - SIGRTMIN) {
1263 log_debug("Enabling showing of status.");
1264 manager_set_show_status(m, true);
1268 log_debug("Disabling showing of status.");
1269 manager_set_show_status(m, false);
1273 log_set_max_level(LOG_DEBUG);
1274 log_notice("Setting log level to debug.");
1278 log_set_max_level(LOG_INFO);
1279 log_notice("Setting log level to info.");
1283 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1284 log_notice("Setting log target to journal-or-kmsg.");
1288 log_set_target(LOG_TARGET_CONSOLE);
1289 log_notice("Setting log target to console.");
1293 log_set_target(LOG_TARGET_KMSG);
1294 log_notice("Setting log target to kmsg.");
1298 log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
1299 log_notice("Setting log target to syslog-or-kmsg.");
1303 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
1310 return manager_dispatch_sigchld(m);
1315 static int process_event(Manager *m, struct epoll_event *ev) {
1322 assert_se(w = ev->data.ptr);
1324 if (w->type == WATCH_INVALID)
1331 /* An incoming signal? */
1332 if (ev->events != EPOLLIN)
1335 if ((r = manager_process_signal_fd(m)) < 0)
1342 /* An incoming daemon notification event? */
1343 if (ev->events != EPOLLIN)
1346 if ((r = manager_process_notify_fd(m)) < 0)
1353 /* Some fd event, to be dispatched to the units */
1354 UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w);
1357 case WATCH_UNIT_TIMER:
1358 case WATCH_JOB_TIMER: {
1362 /* Some timer event, to be dispatched to the units */
1363 if ((k = read(w->fd, &v, sizeof(v))) != sizeof(v)) {
1365 if (k < 0 && (errno == EINTR || errno == EAGAIN))
1368 return k < 0 ? -errno : -EIO;
1371 if (w->type == WATCH_UNIT_TIMER)
1372 UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w);
1374 job_timer_event(w->data.job, v, w);
1379 /* Some mount table change, intended for the mount subsystem */
1380 mount_fd_event(m, ev->events);
1384 /* Some swap table change, intended for the swap subsystem */
1385 swap_fd_event(m, ev->events);
1389 /* Some notification from udev, intended for the device subsystem */
1390 device_fd_event(m, ev->events);
1393 case WATCH_DBUS_WATCH:
1394 bus_watch_event(m, w, ev->events);
1397 case WATCH_DBUS_TIMEOUT:
1398 bus_timeout_event(m, w, ev->events);
1402 log_error("event type=%i", w->type);
1403 assert_not_reached("Unknown epoll event type.");
1409 int manager_loop(Manager *m) {
1412 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
1415 m->exit_code = MANAGER_RUNNING;
1417 /* Release the path cache */
1418 set_free_free(m->unit_path_cache);
1419 m->unit_path_cache = NULL;
1421 manager_check_finished(m);
1423 /* There might still be some zombies hanging around from
1424 * before we were exec()'ed. Leat's reap them */
1425 r = manager_dispatch_sigchld(m);
1429 while (m->exit_code == MANAGER_RUNNING) {
1430 struct epoll_event event;
1434 if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM)
1437 if (!ratelimit_test(&rl)) {
1438 /* Yay, something is going seriously wrong, pause a little */
1439 log_warning("Looping too fast. Throttling execution a little.");
1444 if (manager_dispatch_load_queue(m) > 0)
1447 if (manager_dispatch_run_queue(m) > 0)
1450 if (bus_dispatch(m) > 0)
1453 if (manager_dispatch_cleanup_queue(m) > 0)
1456 if (manager_dispatch_gc_queue(m) > 0)
1459 if (manager_dispatch_dbus_queue(m) > 0)
1462 if (swap_dispatch_reload(m) > 0)
1465 /* Sleep for half the watchdog time */
1466 if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM) {
1467 wait_msec = (int) (m->runtime_watchdog / 2 / USEC_PER_MSEC);
1473 n = epoll_wait(m->epoll_fd, &event, 1, wait_msec);
1485 r = process_event(m, &event);
1490 return m->exit_code;
1493 int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u) {
1501 if (!startswith(s, "/org/freedesktop/systemd1/unit/"))
1504 if (!(n = bus_path_unescape(s+31)))
1507 u = manager_get_unit(m, n);
1518 int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
1527 if (!startswith(s, "/org/freedesktop/systemd1/job/"))
1530 if ((r = safe_atou(s + 30, &id)) < 0)
1533 if (!(j = manager_get_job(m, id)))
1541 void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
1546 if (m->audit_fd < 0)
1549 /* Don't generate audit events if the service was already
1550 * started and we're just deserializing */
1551 if (m->n_reloading > 0)
1554 if (m->running_as != MANAGER_SYSTEM)
1557 if (u->type != UNIT_SERVICE)
1560 if (!(p = unit_name_to_prefix_and_instance(u->id))) {
1561 log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
1565 if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
1566 if (errno == EPERM) {
1567 /* We aren't allowed to send audit messages?
1568 * Then let's not retry again. */
1569 audit_close(m->audit_fd);
1572 log_warning("Failed to send audit message: %m");
1580 void manager_send_unit_plymouth(Manager *m, Unit *u) {
1582 union sockaddr_union sa;
1584 char *message = NULL;
1586 /* Don't generate plymouth events if the service was already
1587 * started and we're just deserializing */
1588 if (m->n_reloading > 0)
1591 if (m->running_as != MANAGER_SYSTEM)
1594 if (u->type != UNIT_SERVICE &&
1595 u->type != UNIT_MOUNT &&
1596 u->type != UNIT_SWAP)
1599 /* We set SOCK_NONBLOCK here so that we rather drop the
1600 * message then wait for plymouth */
1601 if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
1602 log_error("socket() failed: %m");
1607 sa.sa.sa_family = AF_UNIX;
1608 strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
1609 if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
1611 if (errno != EPIPE &&
1614 errno != ECONNREFUSED &&
1615 errno != ECONNRESET &&
1616 errno != ECONNABORTED)
1617 log_error("connect() failed: %m");
1622 if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
1623 log_error("Out of memory");
1628 if (write(fd, message, n + 1) != n + 1) {
1630 if (errno != EPIPE &&
1633 errno != ECONNREFUSED &&
1634 errno != ECONNRESET &&
1635 errno != ECONNABORTED)
1636 log_error("Failed to write Plymouth message: %m");
1643 close_nointr_nofail(fd);
1648 void manager_dispatch_bus_name_owner_changed(
1651 const char* old_owner,
1652 const char *new_owner) {
1659 if (!(u = hashmap_get(m->watch_bus, name)))
1662 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
1665 void manager_dispatch_bus_query_pid_done(
1676 if (!(u = hashmap_get(m->watch_bus, name)))
1679 UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
1682 int manager_open_serialization(Manager *m, FILE **_f) {
1690 if (m->running_as == MANAGER_SYSTEM)
1691 asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid());
1693 asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid());
1698 saved_umask = umask(0077);
1699 fd = mkostemp(path, O_RDWR|O_CLOEXEC);
1709 log_debug("Serializing state to %s", path);
1712 if (!(f = fdopen(fd, "w+")))
1720 int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
1732 fprintf(f, "current-job-id=%i\n", m->current_job_id);
1733 fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
1735 dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
1736 dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
1737 dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
1741 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
1745 if (!unit_can_serialize(u))
1752 if ((r = unit_serialize(u, f, fds)) < 0) {
1758 assert(m->n_reloading > 0);
1764 r = bus_fdset_add_all(m, fds);
1771 int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
1777 log_debug("Deserializing state...");
1782 char line[LINE_MAX], *l;
1784 if (!fgets(line, sizeof(line), f)) {
1799 if (startswith(l, "current-job-id=")) {
1802 if (safe_atou32(l+15, &id) < 0)
1803 log_debug("Failed to parse current job id value %s", l+15);
1805 m->current_job_id = MAX(m->current_job_id, id);
1806 } else if (startswith(l, "taint-usr=")) {
1809 if ((b = parse_boolean(l+10)) < 0)
1810 log_debug("Failed to parse taint /usr flag %s", l+10);
1812 m->taint_usr = m->taint_usr || b;
1813 } else if (startswith(l, "initrd-timestamp="))
1814 dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
1815 else if (startswith(l, "startup-timestamp="))
1816 dual_timestamp_deserialize(l+18, &m->startup_timestamp);
1817 else if (startswith(l, "finish-timestamp="))
1818 dual_timestamp_deserialize(l+17, &m->finish_timestamp);
1820 log_debug("Unknown serialization item '%s'", l);
1825 char name[UNIT_NAME_MAX+2];
1828 if (!fgets(name, sizeof(name), f)) {
1839 if ((r = manager_load_unit(m, strstrip(name), NULL, NULL, &u)) < 0)
1842 if ((r = unit_deserialize(u, f, fds)) < 0)
1852 assert(m->n_reloading > 0);
1858 int manager_reload(Manager *m) {
1865 if ((r = manager_open_serialization(m, &f)) < 0)
1870 if (!(fds = fdset_new())) {
1876 if ((r = manager_serialize(m, f, fds)) < 0) {
1881 if (fseeko(f, 0, SEEK_SET) < 0) {
1887 /* From here on there is no way back. */
1888 manager_clear_jobs_and_units(m);
1889 manager_undo_generators(m);
1891 /* Find new unit paths */
1892 lookup_paths_free(&m->lookup_paths);
1893 if ((q = lookup_paths_init(&m->lookup_paths, m->running_as, true)) < 0)
1896 manager_run_generators(m);
1898 manager_build_unit_path_cache(m);
1900 /* First, enumerate what we can from all config files */
1901 if ((q = manager_enumerate(m)) < 0)
1904 /* Second, deserialize our stored data */
1905 if ((q = manager_deserialize(m, f, fds)) < 0)
1911 /* Third, fire things up! */
1912 if ((q = manager_coldplug(m)) < 0)
1915 assert(m->n_reloading > 0);
1928 bool manager_is_booting_or_shutting_down(Manager *m) {
1933 /* Is the initial job still around? */
1934 if (manager_get_job(m, m->default_unit_job_id))
1937 /* Is there a job for the shutdown target? */
1938 u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
1945 void manager_reset_failed(Manager *m) {
1951 HASHMAP_FOREACH(u, m->units, i)
1952 unit_reset_failed(u);
1955 bool manager_unit_pending_inactive(Manager *m, const char *name) {
1961 /* Returns true if the unit is inactive or going down */
1962 if (!(u = manager_get_unit(m, name)))
1965 return unit_pending_inactive(u);
1968 void manager_check_finished(Manager *m) {
1969 char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
1970 usec_t kernel_usec, initrd_usec, userspace_usec, total_usec;
1974 if (hashmap_size(m->jobs) > 0)
1977 /* Notify Type=idle units that we are done now */
1978 close_pipe(m->idle_pipe);
1980 if (dual_timestamp_is_set(&m->finish_timestamp))
1983 dual_timestamp_get(&m->finish_timestamp);
1985 if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) {
1987 userspace_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
1988 total_usec = m->finish_timestamp.monotonic;
1990 if (dual_timestamp_is_set(&m->initrd_timestamp)) {
1992 kernel_usec = m->initrd_timestamp.monotonic;
1993 initrd_usec = m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic;
1995 log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
1996 format_timespan(kernel, sizeof(kernel), kernel_usec),
1997 format_timespan(initrd, sizeof(initrd), initrd_usec),
1998 format_timespan(userspace, sizeof(userspace), userspace_usec),
1999 format_timespan(sum, sizeof(sum), total_usec));
2001 kernel_usec = m->startup_timestamp.monotonic;
2004 log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
2005 format_timespan(kernel, sizeof(kernel), kernel_usec),
2006 format_timespan(userspace, sizeof(userspace), userspace_usec),
2007 format_timespan(sum, sizeof(sum), total_usec));
2010 userspace_usec = initrd_usec = kernel_usec = 0;
2011 total_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
2013 log_debug("Startup finished in %s.",
2014 format_timespan(sum, sizeof(sum), total_usec));
2017 bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec);
2020 "READY=1\nSTATUS=Startup finished in %s.",
2021 format_timespan(sum, sizeof(sum), total_usec));
2024 void manager_run_generators(Manager *m) {
2026 const char *generator_path;
2027 const char *argv[3];
2032 generator_path = m->running_as == MANAGER_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
2033 if (!(d = opendir(generator_path))) {
2035 if (errno == ENOENT)
2038 log_error("Failed to enumerate generator directory: %m");
2042 if (!m->generator_unit_path) {
2044 char user_path[] = "/tmp/systemd-generator-XXXXXX";
2046 if (m->running_as == MANAGER_SYSTEM && getpid() == 1) {
2047 p = "/run/systemd/generator";
2049 if (mkdir_p(p, 0755) < 0) {
2050 log_error("Failed to create generator directory: %m");
2055 if (!(p = mkdtemp(user_path))) {
2056 log_error("Failed to create generator directory: %m");
2061 if (!(m->generator_unit_path = strdup(p))) {
2062 log_error("Failed to allocate generator unit path.");
2067 argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
2068 argv[1] = m->generator_unit_path;
2072 execute_directory(generator_path, d, (char**) argv);
2075 if (rmdir(m->generator_unit_path) >= 0) {
2076 /* Uh? we were able to remove this dir? I guess that
2077 * means the directory was empty, hence let's shortcut
2080 free(m->generator_unit_path);
2081 m->generator_unit_path = NULL;
2085 if (!strv_find(m->lookup_paths.unit_path, m->generator_unit_path)) {
2088 if (!(l = strv_append(m->lookup_paths.unit_path, m->generator_unit_path))) {
2089 log_error("Failed to add generator directory to unit search path: %m");
2093 strv_free(m->lookup_paths.unit_path);
2094 m->lookup_paths.unit_path = l;
2096 log_debug("Added generator unit path %s to search path.", m->generator_unit_path);
2104 void manager_undo_generators(Manager *m) {
2107 if (!m->generator_unit_path)
2110 strv_remove(m->lookup_paths.unit_path, m->generator_unit_path);
2111 rm_rf(m->generator_unit_path, false, true, false);
2113 free(m->generator_unit_path);
2114 m->generator_unit_path = NULL;
2117 int manager_set_default_controllers(Manager *m, char **controllers) {
2122 l = strv_copy(controllers);
2126 strv_free(m->default_controllers);
2127 m->default_controllers = l;
2129 cg_shorten_controllers(m->default_controllers);
2134 void manager_recheck_journal(Manager *m) {
2139 if (m->running_as != MANAGER_SYSTEM)
2142 u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
2143 if (u && SOCKET(u)->state != SOCKET_RUNNING) {
2144 log_close_journal();
2148 u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
2149 if (u && SERVICE(u)->state != SERVICE_RUNNING) {
2150 log_close_journal();
2154 /* Hmm, OK, so the socket is fully up and the service is up
2155 * too, then let's make use of the thing. */
2159 void manager_set_show_status(Manager *m, bool b) {
2162 if (m->running_as != MANAGER_SYSTEM)
2168 touch("/run/systemd/show-status");
2170 unlink("/run/systemd/show-status");
2173 bool manager_get_show_status(Manager *m) {
2176 if (m->running_as != MANAGER_SYSTEM)
2182 /* If Plymouth is running make sure we show the status, so
2183 * that there's something nice to see when people press Esc */
2185 return plymouth_running();
2188 static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
2189 [MANAGER_SYSTEM] = "system",
2190 [MANAGER_USER] = "user"
2193 DEFINE_STRING_TABLE_LOOKUP(manager_running_as, ManagerRunningAs);