manager.c revision 90b99192ad5b7674585996e2b801679989f8a8a7
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt This file is part of systemd.
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt Copyright 2010 Lennart Poettering
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is free software; you can redistribute it and/or modify it
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt under the terms of the GNU Lesser General Public License as published by
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt the Free Software Foundation; either version 2.1 of the License, or
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt (at your option) any later version.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is distributed in the hope that it will be useful, but
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt WITHOUT ANY WARRANTY; without even the implied warranty of
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Lesser General Public License for more details.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt You should have received a copy of the GNU Lesser General Public License
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt along with systemd; If not, see <http://www.gnu.org/licenses/>.
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt/* Initial delay and the interval for printing status messages about running jobs */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic void manager_undo_generators(Manager *m);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int manager_watch_jobs_in_progress(Manager *m) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
0ae0e5cd96813bacad43a39920a043d8d20a67dbLennart Poettering#define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
d7c9c21f18704580f66a1ce73fb6b506fdf40732Patrik Flyktvoid manager_flip_auto_status(Manager *m, bool enable) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williamsstatic void manager_print_jobs_in_progress(Manager *m) {
0ae0e5cd96813bacad43a39920a043d8d20a67dbLennart Poettering char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
0ae0e5cd96813bacad43a39920a043d8d20a67dbLennart Poettering print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams if (j->state == JOB_RUNNING && counter++ == print_nr)
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams /* m->n_running_jobs must be consistent with the contents of m->jobs,
d7c9c21f18704580f66a1ce73fb6b506fdf40732Patrik Flykt * so the above loop must have succeeded in finding j. */
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen cylon_pos = m->jobs_in_progress_iteration % 14;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen if (job_get_timeout(j, &x) > 0)
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen "%sA %s job is running for %s (%s / %s)",
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersenstatic int have_ask_password(void) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return false;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return false;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return true;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktstatic int manager_dispatch_ask_password_fd(sd_event_source *source,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt /* Log error but continue. Negative have_ask_password
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt * is treated as unknown status. */
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt log_error_errno(m->have_ask_password, "Failed to list /run/systemd/ask-password: %m");
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktstatic void manager_close_ask_password(Manager *m) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktstatic int manager_check_ask_password(Manager *m) {
3098562c9236fe0bd3e7d950b6c53907304d277fTom Gundersen mkdir_p_label("/run/systemd/ask-password", 0755);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt return log_error_errno(errno, "inotify_init1() failed: %m");
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt log_error_errno(errno, "Failed to add watch on /run/systemd/ask-password: %m");
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt r = sd_event_add_io(m->event, &m->ask_password_event_source,
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt if (r < 0) {
f89087272b5561c9a3fc9d6a4e2a09f75f688fa7Thomas Haller log_error_errno(errno, "Failed to add event source for /run/systemd/ask-password: %m");
f89087272b5561c9a3fc9d6a4e2a09f75f688fa7Thomas Haller /* Queries might have been added meanwhile... */
f89087272b5561c9a3fc9d6a4e2a09f75f688fa7Thomas Haller manager_dispatch_ask_password_fd(m->ask_password_event_source,
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flyktstatic int manager_watch_idle_pipe(Manager *m) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = sd_event_add_io(m->event, &m->idle_pipe_event_source, m->idle_pipe[2], EPOLLIN, manager_dispatch_idle_pipe_fd, m);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return log_error_errno(r, "Failed to watch idle pipe: %m");
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic void manager_close_idle_pipe(Manager *m) {
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flyktstatic int manager_setup_time_change(Manager *m) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* We only care for the cancellation event, hence we set the
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt * timeout to the latest possible value. */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return log_error_errno(errno, "Failed to create timerfd: %m");
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_debug_errno(errno, "Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt m->time_change_fd = safe_close(m->time_change_fd);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return log_error_errno(r, "Failed to create time change event source: %m");
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt /* Enable that we get SIGINT on control-alt-del. In containers
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt * this will fail with EPERM (older) or EINVAL (newer), so
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt * ignore that. */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_warning_errno(errno, "Failed to enable ctrl-alt-del handling: %m");
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt /* Support systems without virtual console */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt log_warning_errno(errno, "Failed to open /dev/tty0: %m");
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt /* Enable that we get SIGWINCH on kbrequest */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt log_warning_errno(errno, "Failed to enable kbrequest handling: %m");
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* We make liberal use of realtime signals here. On
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt * Linux/glibc we have 30 of them (with the exception of Linux
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt * (aka SIGRTMAX). */
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams SIGINT, /* Kernel sends us this on control-alt-del */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt SIGRTMIN+0, /* systemd: start default.target */
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt SIGRTMIN+1, /* systemd: isolate rescue.target */
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt SIGRTMIN+2, /* systemd: isolate emergency.target */
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt SIGRTMIN+4, /* systemd: start poweroff.target */
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt /* ... space for more special targets ... */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* ... space for more immediate system state changes ... */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt SIGRTMIN+20, /* systemd: enable status messages */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt SIGRTMIN+21, /* systemd: disable status messages */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* .. one free signal here ... */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* Apparently Linux on hppa has fewer RT
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * signals (SIGRTMAX is SIGRTMIN+25 there),
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * hence let's not try to make use of them
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * here. Since these commands are accessible
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * by different means and only really a safety
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * net, the missing functionality on hppa
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * shouldn't matter. */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt SIGRTMIN+27, /* systemd: set log target to console */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt SIGRTMIN+28, /* systemd: set log target to kmsg */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete) */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* ... one free signal here SIGRTMIN+30 ... */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt m->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = sd_event_add_io(m->event, &m->signal_event_source, m->signal_fd, EPOLLIN, manager_dispatch_signal_fd, m);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* Process signals a bit earlier than the rest of things, but
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt * later than notify_fd processing, so that the notify
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt * processing can still figure out to which process/service a
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * message belongs, before we reap the process. */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = sd_event_source_set_priority(m->signal_event_source, -5);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic void manager_clean_environment(Manager *m) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt /* Let's remove some environment variables that we
10c9ce615d98e125bc520efa94aebaef250a4061David Herrmann * need ourselves to communicate with our clients */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt "NOTIFY_SOCKET",
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt "MANAGERPID",
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt "LISTEN_PID",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt "LISTEN_FDS",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt "WATCHDOG_PID",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt "WATCHDOG_USEC",
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic int manager_default_environment(Manager *m) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* The system manager always starts with a clean
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * environment for its children. It does not import
4b4923e65423e60d755841b5b264730e8f3deab3Tom Gundersen * the kernel or the parents exported variables.
513a6fa8679510ea1b55967bdb482dd5f8a39f21Ronny Chevalier * The initial passed environ is untouched to keep
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * /proc/self/environ valid; it is used for tagging
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt * the init process inside containers. */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt m->environment = strv_new("PATH=" DEFAULT_PATH,
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* Import locale variables LC_*= from configuration */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* The user manager passes its own environment
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * along to its children. */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flyktint manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt m->default_timer_accuracy_usec = USEC_PER_MINUTE;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt 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 = m->utab_inotify_fd = -1;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt m->have_ask_password = -EINVAL; /* we don't know */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = hashmap_ensure_allocated(&m->units, &string_hash_ops);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = hashmap_ensure_allocated(&m->cgroup_unit, &string_hash_ops);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = hashmap_ensure_allocated(&m->watch_bus, &string_hash_ops);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = set_ensure_allocated(&m->startup_units, NULL);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt r = set_ensure_allocated(&m->failed_units, NULL);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = sd_event_add_defer(m->event, &m->run_queue_event_source, manager_dispatch_run_queue, m);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = sd_event_source_set_priority(m->run_queue_event_source, SD_EVENT_PRIORITY_IDLE);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_OFF);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* Note that we set up neither kdbus, nor the notify fd
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * here. We do that after deserialization, since they might
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * have gotten serialized across the reexec. */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* First free all secondary fields */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt m->notify_event_source = sd_event_source_unref(m->notify_event_source);
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return log_error_errno(errno, "Failed to allocate notification socket: %m");
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt m->notify_socket = strdup("/run/systemd/notify");
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen const char *e;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_error_errno(errno, "XDG_RUNTIME_DIR is not set: %m");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt m->notify_socket = strappend(e, "/systemd/notify");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt (void) mkdir_parents_label(m->notify_socket, 0755);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return log_error_errno(errno, "SO_PASSCRED failed: %m");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug("Using notification socket %s", m->notify_socket);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_dispatch_notify_fd, m);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return log_error_errno(r, "Failed to allocate notify event source: %m");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Process signals a bit earlier than SIGCHLD, so that we can
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * still identify to which service an exit message belongs */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = sd_event_source_set_priority(m->notify_event_source, -7);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return log_error_errno(r, "Failed to set priority of notify event source: %m");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt m->running_as == SYSTEMD_SYSTEM ? "system" : "user",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return log_debug_errno(m->kdbus_fd, "Failed to set up kdbus: %m");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug("Successfully set up kdbus on %s", p);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int manager_connect_bus(Manager *m, bool reexecuting) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt (m->running_as == SYSTEMD_USER && getenv("DBUS_SESSION_BUS_ADDRESS"));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt /* Try to connect to the busses, if possible. */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic unsigned manager_dispatch_cleanup_queue(Manager *m) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unsigned n = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt while ((u = m->cleanup_queue)) {
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt GC_OFFSET_BAD, /* We don't need this unit anymore */
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flyktstatic void unit_gc_sweep(Unit *u, unsigned gc_marker) {
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (other->gc_marker == gc_marker + GC_OFFSET_GOOD)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (other->gc_marker != gc_marker + GC_OFFSET_BAD)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* We were unable to find anything out about this entry, so
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * let's investigate it later */
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt /* We definitely know that this one is not useful anymore, so
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt * let's mark it for deletion */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic unsigned manager_dispatch_gc_queue(Manager *m) {
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt unsigned n = 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* log_debug("Running GC..."); */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt while ((u = m->gc_queue)) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (u->gc_marker == gc_marker + GC_OFFSET_BAD ||
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt u->gc_marker == gc_marker + GC_OFFSET_UNSURE) {
0ae0e5cd96813bacad43a39920a043d8d20a67dbLennart Poettering log_unit_debug(u->id, "Collecting %s", u->id);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic void manager_clear_jobs_and_units(Manager *m) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt for (c = 0; c < _UNIT_TYPE_MAX; c++)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* If we reexecute ourselves, we keep the root cgroup
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_event_source_unref(m->time_change_event_source);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_event_source_unref(m->jobs_in_progress_event_source);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_event_source_unref(m->idle_pipe_event_source);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_event_source_unref(m->run_queue_event_source);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt for (i = 0; i < _RLIMIT_MAX; i++)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(hashmap_isempty(m->units_requiring_mounts_for));
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt /* Let's ask every type to load all units from disk/kernel
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * that it might know */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt for (c = 0; c < _UNIT_TYPE_MAX; c++) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (unit_vtable[c]->supported && !unit_vtable[c]->supported(m)) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_info("Unit type .%s is not supported on this system.", unit_type_to_string(c));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Then, let's set up their initial state. */
0ae0e5cd96813bacad43a39920a043d8d20a67dbLennart Poettering /* ignore aliases */
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (u->id != k)
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flyktstatic void manager_build_unit_path_cache(Manager *m) {
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt m->unit_path_cache = set_new(&string_hash_ops);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_error("Failed to allocate unit path cache.");
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen /* This simply builds a list of files we know exist, so that
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt * we don't always have to go to disk */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_error_errno(errno, "Failed to open directory %s: %m", *i);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_error_errno(r, "Failed to build unit path cache: %m");
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic int manager_distribute_fds(Manager *m, FDSet *fds) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktint manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen dual_timestamp_get(&m->generators_start_timestamp);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt dual_timestamp_get(&m->generators_finish_timestamp);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* If we will deserialize make sure that during enumeration
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * this is already known, so we increase the counter here
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * already */
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen /* First, enumerate what we can from all config files */
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt dual_timestamp_get(&m->units_load_start_timestamp);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt dual_timestamp_get(&m->units_load_finish_timestamp);
f667c150a9116022f348cb6d8f2a553dce2386c3Tom Gundersen /* Second, deserialize if there is something to deserialize */
10c9ce615d98e125bc520efa94aebaef250a4061David Herrmann r = manager_deserialize(m, serialization, fds);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* Any fds left? Find some unit which wants them. This is
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * useful to allow container managers to pass some file
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * descriptors to us pre-initialized. This enables
f667c150a9116022f348cb6d8f2a553dce2386c3Tom Gundersen * socket-based activation of entire containers. */
f667c150a9116022f348cb6d8f2a553dce2386c3Tom Gundersen if (q < 0 && r == 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* We might have deserialized the notify fd, but if we didn't
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt * then let's create the bus now */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (q < 0 && r == 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* We might have deserialized the kdbus control fd, but if we
d7c9c21f18704580f66a1ce73fb6b506fdf40732Patrik Flykt * didn't, then let's create the bus now. */
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek bus_track_coldplug(m, &m->subscribed, &m->deserialized_subscribed);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt /* Third, fire things up! */
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (q < 0 && r == 0)
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller /* Let's wait for the UnitNew/JobNew messages being
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt * sent, before we notify that the reload is
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt * finished */
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktint manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Isolate is only valid for start.");
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (mode == JOB_ISOLATE && !unit->allow_isolate)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return sd_bus_error_setf(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt job_type_to_string(type), job_mode_to_string(mode));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = transaction_add_job_and_dependencies(tr, type, unit, NULL, true, override, false,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt job_type_to_string(type), (unsigned) tr->anchor_job->id);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktint manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8Lennart Poettering r = manager_load_unit(m, name, NULL, NULL, &unit);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return manager_add_job(m, type, unit, mode, override, e, _ret);
3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8Lennart Poettering return hashmap_get(m->jobs, UINT32_TO_PTR(id));
3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8Lennart PoetteringUnit *manager_get_unit(Manager *m, const char *name) {
3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8Lennart Poetteringunsigned manager_dispatch_load_queue(Manager *m) {
3733eec3e292e4ddb4cba5eb8d3bd8cbee7102d8Lennart Poettering unsigned n = 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* Make sure we are not run recursively */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* Dispatches the load queue. Takes a unit from the queue and
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * tries to load its data until the queue is empty */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt while ((u = m->load_queue)) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt const char *name,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt const char *path,
if (!name)
if (ret) {
if (!ret)
return -ENOMEM;
if (path) {
return -ENOMEM;
if (_ret)
int manager_load_unit(
Manager *m,
const char *name,
const char *path,
sd_bus_error *e,
assert(m);
if (_ret)
Iterator i;
Job *j;
assert(s);
assert(f);
Iterator i;
Unit *u;
assert(s);
assert(f);
if (u->id == t)
Job *j;
assert(m);
Job *j;
assert(m);
while ((j = m->run_queue)) {
if (m->n_running_jobs > 0)
if (m->n_on_console > 0)
Job *j;
Unit *u;
assert(m);
if (m->dispatching_dbus_queue)
m->dispatching_dbus_queue = true;
while ((u = m->dbus_unit_queue)) {
while ((j = m->dbus_job_queue)) {
m->dispatching_dbus_queue = false;
if (m->send_reloading_done) {
m->send_reloading_done = false;
bus_manager_send_reloading(m, false);
if (m->queued_message)
static void manager_invoke_notify_message(Manager *m, Unit *u, pid_t pid, char *buf, size_t n, FDSet *fds) {
assert(m);
assert(u);
assert(n > 0);
if (!tags) {
log_oom();
static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
ssize_t n;
assert(m);
} control = {};
bool found = false;
unsigned n_fds = 0;
return -errno;
return -ECONNRESET;
if (n_fds > 0) {
return log_oom();
buf[n] = 0;
if (u1) {
found = true;
found = true;
found = true;
if (!found)
assert(m);
assert(u);
assert(m);
return -errno;
if (u1)
return -errno;
static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
ssize_t n;
bool sigchld = false;
assert(m);
if (n != sizeof(sfsi)) {
return -EIO;
return -errno;
&sfsi);
case SIGCHLD:
sigchld = true;
case SIGTERM:
case SIGINT:
case SIGWINCH:
case SIGPWR:
case SIGUSR1: {
Unit *u;
bus_init(m, true);
case SIGUSR2: {
if (ferror(f)) {
if (fflush(f)) {
case SIGHUP:
static const char * const target_table[] = {
[0] = SPECIAL_DEFAULT_TARGET,
[0] = MANAGER_HALT,
if (sigchld)
static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
Iterator i;
Unit *u;
assert(m);
NULL);
static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
assert(m);
static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
assert(m);
assert(m);
r = manager_dispatch_sigchld(m);
if (manager_dispatch_load_queue(m) > 0)
if (manager_dispatch_gc_queue(m) > 0)
if (manager_dispatch_cleanup_queue(m) > 0)
if (manager_dispatch_cgroup_queue(m) > 0)
if (manager_dispatch_dbus_queue(m) > 0)
if (wait_usec <= 0)
return m->exit_code;
Unit *u;
assert(m);
assert(s);
r = unit_name_from_dbus_path(s, &n);
*_u = u;
unsigned id;
Job *j;
assert(m);
assert(s);
return -EINVAL;
return -ENOENT;
*_j = j;
#ifdef HAVE_AUDIT
const char *msg;
int audit_fd;
if (audit_fd < 0)
if (m->n_reloading > 0)
log_oom();
if (m->n_reloading > 0)
if (fd < 0) {
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
log_oom();
errno = 0;
Manager *m,
const char *name,
const char* old_owner,
const char *new_owner) {
Unit *u;
assert(m);
const char *path;
FILE *f;
if (fd < 0)
return -errno;
return -errno;
*_f = f;
Iterator i;
Unit *u;
assert(m);
assert(f);
m->n_reloading ++;
if (!in_initrd()) {
if (!switching_root) {
if (!ce)
return -ENOMEM;
if (m->notify_fd >= 0) {
int copy;
if (copy < 0)
return copy;
if (m->kdbus_fd >= 0) {
int copy;
if (copy < 0)
return copy;
if (u->id != t)
m->n_reloading --;
m->n_reloading --;
if (ferror(f))
return -EIO;
assert(m);
assert(f);
m->n_reloading ++;
if (feof(f))
r = -errno;
goto finish;
uint32_t n;
m->n_installed_jobs += n;
uint32_t n;
m->n_failed_jobs += n;
if (!uce) {
r = -ENOMEM;
goto finish;
r = -ENOMEM;
goto finish;
m->environment = e;
int fd;
r = -ENOMEM;
goto finish;
m->notify_socket = n;
int fd;
Unit *u;
if (feof(f))
r = -errno;
goto finish;
goto finish;
goto finish;
if (ferror(f))
r = -EIO;
m->n_reloading --;
assert(m);
r = manager_open_serialization(m, &f);
m->n_reloading ++;
bus_manager_send_reloading(m, true);
if (!fds) {
m->n_reloading --;
return -ENOMEM;
m->n_reloading --;
m->n_reloading --;
return -errno;
q = manager_run_generators(m);
q = lookup_paths_init(
NULL,
q = manager_enumerate(m);
fclose(f);
f = NULL;
q = manager_setup_notify(m);
q = manager_coldplug(m);
m->n_reloading--;
m->send_reloading_done = true;
assert(m);
return m->n_reloading != 0;
Unit *u;
Iterator i;
assert(m);
Unit *u;
assert(m);
return unit_inactive_or_pending(u);
char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
if (m->test_run)
NULL);
initrd_usec = 0;
NULL);
NULL);
bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
sd_notifyf(false,
Iterator i;
assert(m);
if (m->jobs_in_progress_event_source)
sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
manager_flip_auto_status(m, false);
m->confirm_spawn = false;
manager_set_first_boot(m, false);
if (u->cgroup_path)
cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
assert(m);
if (*generator)
return log_oom();
free(p);
const char *s = NULL;
return -EINVAL;
return log_oom();
free(p);
return log_oom();
if (!mkdtemp(p)) {
free(p);
return -errno;
*generator = p;
assert(m);
if (!*generator)
char **path;
assert(m);
if (m->test_run)
if (!paths)
return log_oom();
goto found;
goto finish;
goto finish;
goto finish;
assert(m);
if (!*generator)
assert(m);
assert(m);
l = m->environment;
return -ENOMEM;
strv_free(a);
return -ENOMEM;
if (m->environment != l)
strv_free(a);
strv_free(b);
m->environment = l;
assert(m);
for (i = 0; i < _RLIMIT_MAX; i++) {
if (!default_rlimit[i])
if (!m->rlimit[i])
return -ENOMEM;
Unit *u;
assert(m);
log_open();
assert(m);
if (mode > 0)
assert(m);
if (m->no_console_output)
if (m->show_status > 0)
return plymouth_running();
assert(m);
m->first_boot = b;
if (m->first_boot)
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
assert(m);
return -ENOMEM;
if (!found) {
assert(m);
assert(m);
Unit *u;
assert(m);
return MANAGER_INITIALIZING;
return MANAGER_STARTING;
if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))
return MANAGER_STOPPING;
return MANAGER_MAINTENANCE;
return MANAGER_MAINTENANCE;
return MANAGER_DEGRADED;
return MANAGER_RUNNING;