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);
528 int manager_enumerate(Manager *m) {
534 /* Let's ask every type to load all units from disk/kernel
535 * that it might know */
536 for (c = 0; c < _UNIT_TYPE_MAX; c++)
537 if (unit_vtable[c]->enumerate)
538 if ((q = unit_vtable[c]->enumerate(m)) < 0)
541 manager_dispatch_load_queue(m);
545 int manager_coldplug(Manager *m) {
553 /* Then, let's set up their initial state. */
554 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
560 if ((q = unit_coldplug(u)) < 0)
567 static void manager_build_unit_path_cache(Manager *m) {
574 set_free_free(m->unit_path_cache);
576 if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) {
577 log_error("Failed to allocate unit path cache.");
581 /* This simply builds a list of files we know exist, so that
582 * we don't always have to go to disk */
584 STRV_FOREACH(i, m->lookup_paths.unit_path) {
587 if (!(d = opendir(*i))) {
588 log_error("Failed to open directory: %m");
592 while ((de = readdir(d))) {
595 if (ignore_file(de->d_name))
598 p = join(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
604 if ((r = set_put(m->unit_path_cache, p)) < 0) {
617 log_error("Failed to build unit path cache: %s", strerror(-r));
619 set_free_free(m->unit_path_cache);
620 m->unit_path_cache = NULL;
626 int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
631 manager_run_generators(m);
633 manager_build_unit_path_cache(m);
635 /* If we will deserialize make sure that during enumeration
636 * this is already known, so we increase the counter here
641 /* First, enumerate what we can from all config files */
642 r = manager_enumerate(m);
644 /* Second, deserialize if there is something to deserialize */
646 if ((q = manager_deserialize(m, serialization, fds)) < 0)
649 /* Third, fire things up! */
650 if ((q = manager_coldplug(m)) < 0)
654 assert(m->n_reloading > 0);
661 int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) {
666 assert(type < _JOB_TYPE_MAX);
668 assert(mode < _JOB_MODE_MAX);
670 if (mode == JOB_ISOLATE && type != JOB_START) {
671 dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start.");
675 if (mode == JOB_ISOLATE && !unit->allow_isolate) {
676 dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
680 log_debug("Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
682 job_type_collapse(&type, unit);
684 tr = transaction_new();
688 r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
689 mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
690 mode == JOB_IGNORE_DEPENDENCIES, e);
694 if (mode == JOB_ISOLATE) {
695 r = transaction_add_isolate_jobs(tr, m);
700 r = transaction_activate(tr, m, mode, e);
704 log_debug("Enqueued job %s/%s as %u", unit->id, job_type_to_string(type), (unsigned) tr->anchor_job->id);
707 *_ret = tr->anchor_job;
709 transaction_free(tr);
713 transaction_abort(tr);
714 transaction_free(tr);
718 int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) {
723 assert(type < _JOB_TYPE_MAX);
725 assert(mode < _JOB_MODE_MAX);
727 if ((r = manager_load_unit(m, name, NULL, NULL, &unit)) < 0)
730 return manager_add_job(m, type, unit, mode, override, e, _ret);
733 Job *manager_get_job(Manager *m, uint32_t id) {
736 return hashmap_get(m->jobs, UINT32_TO_PTR(id));
739 Unit *manager_get_unit(Manager *m, const char *name) {
743 return hashmap_get(m->units, name);
746 unsigned manager_dispatch_load_queue(Manager *m) {
752 /* Make sure we are not run recursively */
753 if (m->dispatching_load_queue)
756 m->dispatching_load_queue = true;
758 /* Dispatches the load queue. Takes a unit from the queue and
759 * tries to load its data until the queue is empty */
761 while ((u = m->load_queue)) {
762 assert(u->in_load_queue);
768 m->dispatching_load_queue = false;
772 int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
778 assert(name || path);
780 /* This will prepare the unit for loading, but not actually
781 * load anything from disk. */
783 if (path && !is_path(path)) {
784 dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path);
789 name = path_get_file_name(path);
791 t = unit_name_to_type(name);
793 if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid_no_type(name, false)) {
794 dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
798 ret = manager_get_unit(m, name);
804 ret = unit_new(m, unit_vtable[t]->object_size);
809 ret->fragment_path = strdup(path);
810 if (!ret->fragment_path) {
816 if ((r = unit_add_name(ret, name)) < 0) {
821 unit_add_to_load_queue(ret);
822 unit_add_to_dbus_queue(ret);
823 unit_add_to_gc_queue(ret);
831 int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) {
836 /* This will load the service information files, but not actually
837 * start any services or anything. */
839 if ((r = manager_load_unit_prepare(m, name, path, e, _ret)) != 0)
842 manager_dispatch_load_queue(m);
845 *_ret = unit_follow_merge(*_ret);
850 void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
857 HASHMAP_FOREACH(j, s->jobs, i)
858 job_dump(j, f, prefix);
861 void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
869 HASHMAP_FOREACH_KEY(u, t, s->units, i)
871 unit_dump(u, f, prefix);
874 void manager_clear_jobs(Manager *m) {
879 while ((j = hashmap_first(m->jobs)))
880 /* No need to recurse. We're cancelling all jobs. */
881 job_finish_and_invalidate(j, JOB_CANCELED, false);
884 unsigned manager_dispatch_run_queue(Manager *m) {
888 if (m->dispatching_run_queue)
891 m->dispatching_run_queue = true;
893 while ((j = m->run_queue)) {
894 assert(j->installed);
895 assert(j->in_run_queue);
897 job_run_and_invalidate(j);
901 m->dispatching_run_queue = false;
905 unsigned manager_dispatch_dbus_queue(Manager *m) {
912 if (m->dispatching_dbus_queue)
915 m->dispatching_dbus_queue = true;
917 while ((u = m->dbus_unit_queue)) {
918 assert(u->in_dbus_queue);
920 bus_unit_send_change_signal(u);
924 while ((j = m->dbus_job_queue)) {
925 assert(j->in_dbus_queue);
927 bus_job_send_change_signal(j);
931 m->dispatching_dbus_queue = false;
935 static int manager_process_notify_fd(Manager *m) {
942 struct msghdr msghdr;
946 struct cmsghdr cmsghdr;
947 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
953 iovec.iov_base = buf;
954 iovec.iov_len = sizeof(buf)-1;
958 msghdr.msg_iov = &iovec;
959 msghdr.msg_iovlen = 1;
960 msghdr.msg_control = &control;
961 msghdr.msg_controllen = sizeof(control);
963 if ((n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT)) <= 0) {
967 if (errno == EAGAIN || errno == EINTR)
973 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
974 control.cmsghdr.cmsg_level != SOL_SOCKET ||
975 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
976 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
977 log_warning("Received notify message without credentials. Ignoring.");
981 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
983 if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid))))
984 if (!(u = cgroup_unit_by_pid(m, ucred->pid))) {
985 log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid);
989 assert((size_t) n < sizeof(buf));
991 if (!(tags = strv_split(buf, "\n\r")))
994 log_debug("Got notification message for unit %s", u->id);
996 if (UNIT_VTABLE(u)->notify_message)
997 UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
1005 static int manager_dispatch_sigchld(Manager *m) {
1015 /* First we call waitd() for a PID and do not reap the
1016 * zombie. That way we can still access /proc/$PID for
1017 * it while it is a zombie. */
1018 if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
1020 if (errno == ECHILD)
1032 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
1035 get_process_comm(si.si_pid, &name);
1036 log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
1040 /* Let's flush any message the dying child might still
1041 * have queued for us. This ensures that the process
1042 * still exists in /proc so that we can figure out
1043 * which cgroup and hence unit it belongs to. */
1044 if ((r = manager_process_notify_fd(m)) < 0)
1047 /* And now figure out the unit this belongs to */
1048 if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid))))
1049 u = cgroup_unit_by_pid(m, si.si_pid);
1051 /* And now, we actually reap the zombie. */
1052 if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
1059 if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
1062 log_debug("Child %lu died (code=%s, status=%i/%s)",
1063 (long unsigned) si.si_pid,
1064 sigchld_code_to_string(si.si_code),
1066 strna(si.si_code == CLD_EXITED
1067 ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
1068 : signal_to_string(si.si_status)));
1073 log_debug("Child %lu belongs to %s", (long unsigned) si.si_pid, u->id);
1075 hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid));
1076 UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
1082 static int manager_start_target(Manager *m, const char *name, JobMode mode) {
1086 dbus_error_init(&error);
1088 log_debug("Activating special unit %s", name);
1090 if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL)) < 0)
1091 log_error("Failed to enqueue %s job: %s", name, bus_error(&error, r));
1093 dbus_error_free(&error);
1098 static int manager_process_signal_fd(Manager *m) {
1100 struct signalfd_siginfo sfsi;
1101 bool sigchld = false;
1106 if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
1111 if (errno == EINTR || errno == EAGAIN)
1117 if (sfsi.ssi_pid > 0) {
1120 get_process_comm(sfsi.ssi_pid, &p);
1122 log_debug("Received SIG%s from PID %lu (%s).",
1123 signal_to_string(sfsi.ssi_signo),
1124 (unsigned long) sfsi.ssi_pid, strna(p));
1127 log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo));
1129 switch (sfsi.ssi_signo) {
1136 if (m->running_as == MANAGER_SYSTEM) {
1137 /* This is for compatibility with the
1138 * original sysvinit */
1139 m->exit_code = MANAGER_REEXECUTE;
1146 if (m->running_as == MANAGER_SYSTEM) {
1147 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
1151 /* Run the exit target if there is one, if not, just exit. */
1152 if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
1153 m->exit_code = MANAGER_EXIT;
1160 if (m->running_as == MANAGER_SYSTEM)
1161 manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
1163 /* This is a nop on non-init */
1167 if (m->running_as == MANAGER_SYSTEM)
1168 manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
1170 /* This is a nop on non-init */
1176 u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
1178 if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
1179 log_info("Trying to reconnect to bus...");
1183 if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
1184 log_info("Loading D-Bus service...");
1185 manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
1196 if (!(f = open_memstream(&dump, &size))) {
1197 log_warning("Failed to allocate memory stream.");
1201 manager_dump_units(m, f, "\t");
1202 manager_dump_jobs(m, f, "\t");
1207 log_warning("Failed to write status stream");
1212 log_dump(LOG_INFO, dump);
1219 m->exit_code = MANAGER_RELOAD;
1224 /* Starting SIGRTMIN+0 */
1225 static const char * const target_table[] = {
1226 [0] = SPECIAL_DEFAULT_TARGET,
1227 [1] = SPECIAL_RESCUE_TARGET,
1228 [2] = SPECIAL_EMERGENCY_TARGET,
1229 [3] = SPECIAL_HALT_TARGET,
1230 [4] = SPECIAL_POWEROFF_TARGET,
1231 [5] = SPECIAL_REBOOT_TARGET,
1232 [6] = SPECIAL_KEXEC_TARGET
1235 /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
1236 static const ManagerExitCode code_table[] = {
1238 [1] = MANAGER_POWEROFF,
1239 [2] = MANAGER_REBOOT,
1243 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
1244 (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
1245 int idx = (int) sfsi.ssi_signo - SIGRTMIN;
1246 manager_start_target(m, target_table[idx],
1247 (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
1251 if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
1252 (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
1253 m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
1257 switch (sfsi.ssi_signo - SIGRTMIN) {
1260 log_debug("Enabling showing of status.");
1261 manager_set_show_status(m, true);
1265 log_debug("Disabling showing of status.");
1266 manager_set_show_status(m, false);
1270 log_set_max_level(LOG_DEBUG);
1271 log_notice("Setting log level to debug.");
1275 log_set_max_level(LOG_INFO);
1276 log_notice("Setting log level to info.");
1280 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1281 log_notice("Setting log target to journal-or-kmsg.");
1285 log_set_target(LOG_TARGET_CONSOLE);
1286 log_notice("Setting log target to console.");
1290 log_set_target(LOG_TARGET_KMSG);
1291 log_notice("Setting log target to kmsg.");
1295 log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
1296 log_notice("Setting log target to syslog-or-kmsg.");
1300 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
1307 return manager_dispatch_sigchld(m);
1312 static int process_event(Manager *m, struct epoll_event *ev) {
1319 assert_se(w = ev->data.ptr);
1321 if (w->type == WATCH_INVALID)
1328 /* An incoming signal? */
1329 if (ev->events != EPOLLIN)
1332 if ((r = manager_process_signal_fd(m)) < 0)
1339 /* An incoming daemon notification event? */
1340 if (ev->events != EPOLLIN)
1343 if ((r = manager_process_notify_fd(m)) < 0)
1350 /* Some fd event, to be dispatched to the units */
1351 UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w);
1354 case WATCH_UNIT_TIMER:
1355 case WATCH_JOB_TIMER: {
1359 /* Some timer event, to be dispatched to the units */
1360 if ((k = read(w->fd, &v, sizeof(v))) != sizeof(v)) {
1362 if (k < 0 && (errno == EINTR || errno == EAGAIN))
1365 return k < 0 ? -errno : -EIO;
1368 if (w->type == WATCH_UNIT_TIMER)
1369 UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w);
1371 job_timer_event(w->data.job, v, w);
1376 /* Some mount table change, intended for the mount subsystem */
1377 mount_fd_event(m, ev->events);
1381 /* Some swap table change, intended for the swap subsystem */
1382 swap_fd_event(m, ev->events);
1386 /* Some notification from udev, intended for the device subsystem */
1387 device_fd_event(m, ev->events);
1390 case WATCH_DBUS_WATCH:
1391 bus_watch_event(m, w, ev->events);
1394 case WATCH_DBUS_TIMEOUT:
1395 bus_timeout_event(m, w, ev->events);
1399 log_error("event type=%i", w->type);
1400 assert_not_reached("Unknown epoll event type.");
1406 int manager_loop(Manager *m) {
1409 RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
1412 m->exit_code = MANAGER_RUNNING;
1414 /* Release the path cache */
1415 set_free_free(m->unit_path_cache);
1416 m->unit_path_cache = NULL;
1418 manager_check_finished(m);
1420 /* There might still be some zombies hanging around from
1421 * before we were exec()'ed. Leat's reap them */
1422 r = manager_dispatch_sigchld(m);
1426 while (m->exit_code == MANAGER_RUNNING) {
1427 struct epoll_event event;
1431 if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM)
1434 if (!ratelimit_test(&rl)) {
1435 /* Yay, something is going seriously wrong, pause a little */
1436 log_warning("Looping too fast. Throttling execution a little.");
1441 if (manager_dispatch_load_queue(m) > 0)
1444 if (manager_dispatch_run_queue(m) > 0)
1447 if (bus_dispatch(m) > 0)
1450 if (manager_dispatch_cleanup_queue(m) > 0)
1453 if (manager_dispatch_gc_queue(m) > 0)
1456 if (manager_dispatch_dbus_queue(m) > 0)
1459 if (swap_dispatch_reload(m) > 0)
1462 /* Sleep for half the watchdog time */
1463 if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYSTEM) {
1464 wait_msec = (int) (m->runtime_watchdog / 2 / USEC_PER_MSEC);
1470 n = epoll_wait(m->epoll_fd, &event, 1, wait_msec);
1482 r = process_event(m, &event);
1487 return m->exit_code;
1490 int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u) {
1498 if (!startswith(s, "/org/freedesktop/systemd1/unit/"))
1501 if (!(n = bus_path_unescape(s+31)))
1504 u = manager_get_unit(m, n);
1515 int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) {
1524 if (!startswith(s, "/org/freedesktop/systemd1/job/"))
1527 if ((r = safe_atou(s + 30, &id)) < 0)
1530 if (!(j = manager_get_job(m, id)))
1538 void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
1543 if (m->audit_fd < 0)
1546 /* Don't generate audit events if the service was already
1547 * started and we're just deserializing */
1548 if (m->n_reloading > 0)
1551 if (m->running_as != MANAGER_SYSTEM)
1554 if (u->type != UNIT_SERVICE)
1557 if (!(p = unit_name_to_prefix_and_instance(u->id))) {
1558 log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
1562 if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) {
1563 if (errno == EPERM) {
1564 /* We aren't allowed to send audit messages?
1565 * Then let's not retry again. */
1566 audit_close(m->audit_fd);
1569 log_warning("Failed to send audit message: %m");
1577 void manager_send_unit_plymouth(Manager *m, Unit *u) {
1579 union sockaddr_union sa;
1581 char *message = NULL;
1583 /* Don't generate plymouth events if the service was already
1584 * started and we're just deserializing */
1585 if (m->n_reloading > 0)
1588 if (m->running_as != MANAGER_SYSTEM)
1591 if (u->type != UNIT_SERVICE &&
1592 u->type != UNIT_MOUNT &&
1593 u->type != UNIT_SWAP)
1596 /* We set SOCK_NONBLOCK here so that we rather drop the
1597 * message then wait for plymouth */
1598 if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
1599 log_error("socket() failed: %m");
1604 sa.sa.sa_family = AF_UNIX;
1605 strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
1606 if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
1608 if (errno != EPIPE &&
1611 errno != ECONNREFUSED &&
1612 errno != ECONNRESET &&
1613 errno != ECONNABORTED)
1614 log_error("connect() failed: %m");
1619 if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
1620 log_error("Out of memory");
1625 if (write(fd, message, n + 1) != n + 1) {
1627 if (errno != EPIPE &&
1630 errno != ECONNREFUSED &&
1631 errno != ECONNRESET &&
1632 errno != ECONNABORTED)
1633 log_error("Failed to write Plymouth message: %m");
1640 close_nointr_nofail(fd);
1645 void manager_dispatch_bus_name_owner_changed(
1648 const char* old_owner,
1649 const char *new_owner) {
1656 if (!(u = hashmap_get(m->watch_bus, name)))
1659 UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
1662 void manager_dispatch_bus_query_pid_done(
1673 if (!(u = hashmap_get(m->watch_bus, name)))
1676 UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
1679 int manager_open_serialization(Manager *m, FILE **_f) {
1687 if (m->running_as == MANAGER_SYSTEM)
1688 asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid());
1690 asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid());
1695 saved_umask = umask(0077);
1696 fd = mkostemp(path, O_RDWR|O_CLOEXEC);
1706 log_debug("Serializing state to %s", path);
1709 if (!(f = fdopen(fd, "w+")))
1717 int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
1729 fprintf(f, "current-job-id=%i\n", m->current_job_id);
1730 fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
1732 dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
1733 dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
1734 dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
1738 HASHMAP_FOREACH_KEY(u, t, m->units, i) {
1742 if (!unit_can_serialize(u))
1749 if ((r = unit_serialize(u, f, fds)) < 0) {
1755 assert(m->n_reloading > 0);
1761 r = bus_fdset_add_all(m, fds);
1768 int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
1774 log_debug("Deserializing state...");
1779 char line[LINE_MAX], *l;
1781 if (!fgets(line, sizeof(line), f)) {
1796 if (startswith(l, "current-job-id=")) {
1799 if (safe_atou32(l+15, &id) < 0)
1800 log_debug("Failed to parse current job id value %s", l+15);
1802 m->current_job_id = MAX(m->current_job_id, id);
1803 } else if (startswith(l, "taint-usr=")) {
1806 if ((b = parse_boolean(l+10)) < 0)
1807 log_debug("Failed to parse taint /usr flag %s", l+10);
1809 m->taint_usr = m->taint_usr || b;
1810 } else if (startswith(l, "initrd-timestamp="))
1811 dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
1812 else if (startswith(l, "startup-timestamp="))
1813 dual_timestamp_deserialize(l+18, &m->startup_timestamp);
1814 else if (startswith(l, "finish-timestamp="))
1815 dual_timestamp_deserialize(l+17, &m->finish_timestamp);
1817 log_debug("Unknown serialization item '%s'", l);
1822 char name[UNIT_NAME_MAX+2];
1825 if (!fgets(name, sizeof(name), f)) {
1836 if ((r = manager_load_unit(m, strstrip(name), NULL, NULL, &u)) < 0)
1839 if ((r = unit_deserialize(u, f, fds)) < 0)
1849 assert(m->n_reloading > 0);
1855 int manager_reload(Manager *m) {
1862 if ((r = manager_open_serialization(m, &f)) < 0)
1867 if (!(fds = fdset_new())) {
1873 if ((r = manager_serialize(m, f, fds)) < 0) {
1878 if (fseeko(f, 0, SEEK_SET) < 0) {
1884 /* From here on there is no way back. */
1885 manager_clear_jobs_and_units(m);
1886 manager_undo_generators(m);
1888 /* Find new unit paths */
1889 lookup_paths_free(&m->lookup_paths);
1890 if ((q = lookup_paths_init(&m->lookup_paths, m->running_as, true)) < 0)
1893 manager_run_generators(m);
1895 manager_build_unit_path_cache(m);
1897 /* First, enumerate what we can from all config files */
1898 if ((q = manager_enumerate(m)) < 0)
1901 /* Second, deserialize our stored data */
1902 if ((q = manager_deserialize(m, f, fds)) < 0)
1908 /* Third, fire things up! */
1909 if ((q = manager_coldplug(m)) < 0)
1912 assert(m->n_reloading > 0);
1925 bool manager_is_booting_or_shutting_down(Manager *m) {
1930 /* Is the initial job still around? */
1931 if (manager_get_job(m, m->default_unit_job_id))
1934 /* Is there a job for the shutdown target? */
1935 u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
1942 void manager_reset_failed(Manager *m) {
1948 HASHMAP_FOREACH(u, m->units, i)
1949 unit_reset_failed(u);
1952 bool manager_unit_pending_inactive(Manager *m, const char *name) {
1958 /* Returns true if the unit is inactive or going down */
1959 if (!(u = manager_get_unit(m, name)))
1962 return unit_pending_inactive(u);
1965 void manager_check_finished(Manager *m) {
1966 char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
1967 usec_t kernel_usec, initrd_usec, userspace_usec, total_usec;
1971 if (hashmap_size(m->jobs) > 0)
1974 /* Notify Type=idle units that we are done now */
1975 close_pipe(m->idle_pipe);
1977 if (dual_timestamp_is_set(&m->finish_timestamp))
1980 dual_timestamp_get(&m->finish_timestamp);
1982 if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) {
1984 userspace_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
1985 total_usec = m->finish_timestamp.monotonic;
1987 if (dual_timestamp_is_set(&m->initrd_timestamp)) {
1989 kernel_usec = m->initrd_timestamp.monotonic;
1990 initrd_usec = m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic;
1992 log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
1993 format_timespan(kernel, sizeof(kernel), kernel_usec),
1994 format_timespan(initrd, sizeof(initrd), initrd_usec),
1995 format_timespan(userspace, sizeof(userspace), userspace_usec),
1996 format_timespan(sum, sizeof(sum), total_usec));
1998 kernel_usec = m->startup_timestamp.monotonic;
2001 log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
2002 format_timespan(kernel, sizeof(kernel), kernel_usec),
2003 format_timespan(userspace, sizeof(userspace), userspace_usec),
2004 format_timespan(sum, sizeof(sum), total_usec));
2007 userspace_usec = initrd_usec = kernel_usec = 0;
2008 total_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
2010 log_debug("Startup finished in %s.",
2011 format_timespan(sum, sizeof(sum), total_usec));
2014 bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec);
2017 "READY=1\nSTATUS=Startup finished in %s.",
2018 format_timespan(sum, sizeof(sum), total_usec));
2021 void manager_run_generators(Manager *m) {
2023 const char *generator_path;
2024 const char *argv[3];
2029 generator_path = m->running_as == MANAGER_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
2030 if (!(d = opendir(generator_path))) {
2032 if (errno == ENOENT)
2035 log_error("Failed to enumerate generator directory: %m");
2039 if (!m->generator_unit_path) {
2041 char user_path[] = "/tmp/systemd-generator-XXXXXX";
2043 if (m->running_as == MANAGER_SYSTEM && getpid() == 1) {
2044 p = "/run/systemd/generator";
2046 if (mkdir_p(p, 0755) < 0) {
2047 log_error("Failed to create generator directory: %m");
2052 if (!(p = mkdtemp(user_path))) {
2053 log_error("Failed to create generator directory: %m");
2058 if (!(m->generator_unit_path = strdup(p))) {
2059 log_error("Failed to allocate generator unit path.");
2064 argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */
2065 argv[1] = m->generator_unit_path;
2069 execute_directory(generator_path, d, (char**) argv);
2072 if (rmdir(m->generator_unit_path) >= 0) {
2073 /* Uh? we were able to remove this dir? I guess that
2074 * means the directory was empty, hence let's shortcut
2077 free(m->generator_unit_path);
2078 m->generator_unit_path = NULL;
2082 if (!strv_find(m->lookup_paths.unit_path, m->generator_unit_path)) {
2085 if (!(l = strv_append(m->lookup_paths.unit_path, m->generator_unit_path))) {
2086 log_error("Failed to add generator directory to unit search path: %m");
2090 strv_free(m->lookup_paths.unit_path);
2091 m->lookup_paths.unit_path = l;
2093 log_debug("Added generator unit path %s to search path.", m->generator_unit_path);
2101 void manager_undo_generators(Manager *m) {
2104 if (!m->generator_unit_path)
2107 strv_remove(m->lookup_paths.unit_path, m->generator_unit_path);
2108 rm_rf(m->generator_unit_path, false, true, false);
2110 free(m->generator_unit_path);
2111 m->generator_unit_path = NULL;
2114 int manager_set_default_controllers(Manager *m, char **controllers) {
2119 l = strv_copy(controllers);
2123 strv_free(m->default_controllers);
2124 m->default_controllers = l;
2126 cg_shorten_controllers(m->default_controllers);
2131 void manager_recheck_journal(Manager *m) {
2136 if (m->running_as != MANAGER_SYSTEM)
2139 u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
2140 if (u && SOCKET(u)->state != SOCKET_RUNNING) {
2141 log_close_journal();
2145 u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
2146 if (u && SERVICE(u)->state != SERVICE_RUNNING) {
2147 log_close_journal();
2151 /* Hmm, OK, so the socket is fully up and the service is up
2152 * too, then let's make use of the thing. */
2156 void manager_set_show_status(Manager *m, bool b) {
2159 if (m->running_as != MANAGER_SYSTEM)
2165 touch("/run/systemd/show-status");
2167 unlink("/run/systemd/show-status");
2170 bool manager_get_show_status(Manager *m) {
2173 if (m->running_as != MANAGER_SYSTEM)
2179 /* If Plymouth is running make sure we show the status, so
2180 * that there's something nice to see when people press Esc */
2182 return plymouth_running();
2185 static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
2186 [MANAGER_SYSTEM] = "system",
2187 [MANAGER_USER] = "user"
2190 DEFINE_STRING_TABLE_LOOKUP(manager_running_as, ManagerRunningAs);