manager.c revision c1dc6153c9426d98ddbcd8b5077f397f18ff1da7
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer This file is part of systemd.
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer Copyright 2010 Lennart Poettering
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer systemd is free software; you can redistribute it and/or modify it
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer under the terms of the GNU Lesser General Public License as published by
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer the Free Software Foundation; either version 2.1 of the License, or
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer (at your option) any later version.
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer systemd is distributed in the hope that it will be useful, but
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer WITHOUT ANY WARRANTY; without even the implied warranty of
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer Lesser General Public License for more details.
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer You should have received a copy of the GNU Lesser General Public License
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer along with systemd; If not, see <http://www.gnu.org/licenses/>.
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer/* Initial delay and the interval for printing status messages about running jobs */
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmerstatic int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmerstatic int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poetteringstatic int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poetteringstatic int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poetteringstatic int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poetteringstatic int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmerstatic int manager_watch_jobs_in_progress(Manager *m) {
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer#define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmerstatic void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmervoid manager_flip_auto_status(Manager *m, bool enable) {
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer manager_set_show_status(m, SHOW_STATUS_AUTO);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmerstatic void manager_print_jobs_in_progress(Manager *m) {
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (j->state == JOB_RUNNING && counter++ == print_nr)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer /* m->n_running_jobs must be consistent with the contents of m->jobs,
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer * so the above loop must have succeeded in finding j. */
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer cylon_pos = m->jobs_in_progress_iteration % 14;
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
dbd2a83fbf051fc51bdca3aa7536c78479488c5bLennart Poettering format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek manager_status_printf(m, true, cylon,
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek "%sA %s job is running for %s (%s / %s)",
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmekstatic int manager_watch_idle_pipe(Manager *m) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek r = sd_event_add_io(m->event, &m->idle_pipe_event_source, m->idle_pipe[2], EPOLLIN, manager_dispatch_idle_pipe_fd, m);
0c0cdb06c139b52ff103287f6909b3daa5b2dc54Ronny Chevalier log_error("Failed to watch idle pipe: %s", strerror(-r));
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmekstatic void manager_close_idle_pipe(Manager *m) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek safe_close_pair(m->idle_pipe + 2);
0c0cdb06c139b52ff103287f6909b3daa5b2dc54Ronny Chevalierstatic int manager_setup_time_change(Manager *m) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek /* We only care for the cancellation event, hence we set the
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek * timeout to the latest possible value. */
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
0c0cdb06c139b52ff103287f6909b3daa5b2dc54Ronny Chevalier /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek log_error("Failed to create timerfd: %m");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek m->time_change_fd = safe_close(m->time_change_fd);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek log_error("Failed to create time change event source: %s", strerror(-r));
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmekstatic int enable_special_signals(Manager *m) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek /* Enable that we get SIGINT on control-alt-del. In containers
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek * this will fail with EPERM (older) or EINVAL (newer), so
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek * ignore that. */
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer log_warning("Failed to enable ctrl-alt-del handling: %m");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther /* Support systems without virtual console */
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther log_warning("Failed to open /dev/tty0: %m");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek /* Enable that we get SIGWINCH on kbrequest */
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer log_warning("Failed to enable kbrequest handling: %m");
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmerstatic int manager_setup_signals(Manager *m) {
assert(m);
if (m->test_run)
if (m->signal_fd < 0)
return -errno;
r = sd_event_add_io(m->event, &m->signal_event_source, m->signal_fd, EPOLLIN, manager_dispatch_signal_fd, m);
return enable_special_signals(m);
assert(m);
m->environment,
NULL);
assert(m);
NULL);
if (!m->environment)
return -ENOMEM;
Manager *m;
return -ENOMEM;
#ifdef ENABLE_EFI
m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = -1;
r = manager_default_environment(m);
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
r = manager_setup_signals(m);
goto fail;
r = manager_setup_cgroup(m);
goto fail;
r = manager_setup_time_change(m);
goto fail;
if (!m->udev) {
r = -ENOMEM;
goto fail;
*_m = m;
fail:
manager_free(m);
if (m->test_run)
if (m->notify_fd < 0) {
} sa = {
if (fd < 0) {
return -errno;
return -EINVAL;
if (!m->notify_socket)
return log_oom();
return -errno;
return -errno;
if (!m->notify_event_source) {
r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_dispatch_notify_fd, m);
return -errno;
#ifdef ENABLE_KDBUS
assert(m);
m->kdbus_fd = bus_kernel_create_bus(m->running_as == SYSTEMD_SYSTEM ? "system" : "user", m->running_as == SYSTEMD_SYSTEM, &p);
if (m->kdbus_fd < 0) {
return m->kdbus_fd;
bool try_bus_connect;
assert(m);
if (m->test_run)
m->kdbus_fd >= 0 ||
reexecuting ||
Unit *u;
assert(m);
while ((u = m->cleanup_queue)) {
unit_free(u);
Iterator i;
bool is_bad;
assert(u);
if (u->in_cleanup_queue)
goto bad;
if (unit_check_gc(u))
goto good;
is_bad = true;
goto good;
is_bad = false;
if (is_bad)
goto bad;
bad:
good:
Unit *u;
unsigned gc_marker;
assert(m);
while ((u = m->gc_queue)) {
u->in_gc_queue = false;
m->n_in_gc_queue = 0;
Unit *u;
assert(m);
unit_free(u);
m->n_on_console = 0;
m->n_running_jobs = 0;
UnitType c;
assert(m);
for (c = 0; c < _UNIT_TYPE_MAX; c++)
bus_done(m);
for (i = 0; i < _RLIMIT_MAX; i++)
free(m);
UnitType c;
assert(m);
for (c = 0; c < _UNIT_TYPE_MAX; c++)
Iterator i;
Unit *u;
assert(m);
if (u->id != k)
q = unit_coldplug(u);
assert(m);
if (!m->unit_path_cache) {
d = opendir(*i);
r = -ENOMEM;
goto fail;
goto fail;
closedir(d);
d = NULL;
fail:
Unit *u;
Iterator i;
assert(m);
assert(m);
r = lookup_paths_init(
NULL,
if (serialization)
m->n_reloading ++;
r = manager_enumerate(m);
if (serialization)
q = manager_setup_notify(m);
q = manager_coldplug(m);
if (serialization) {
m->n_reloading --;
m->send_reloading_done = true;
int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
assert(m);
return -EINVAL;
return -EPERM;
if (!tr)
return -ENOMEM;
goto tr_abort;
goto tr_abort;
goto tr_abort;
if (_ret)
int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, sd_bus_error *e, Job **_ret) {
assert(m);
assert(m);
assert(m);
Unit *u;
assert(m);
if (m->dispatching_load_queue)
m->dispatching_load_queue = true;
while ((u = m->load_queue)) {
unit_load(u);
m->dispatching_load_queue = false;
Manager *m,
const char *name,
const char *path,
sd_bus_error *e,
UnitType t;
assert(m);
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)
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);
bool found = false;
} control = {};
Unit *u;
return -EIO;
return -errno;
buf[n] = 0;
found = true;
found = true;
found = true;
if (!found)
assert(m);
assert(u);
assert(m);
return -errno;
Unit *u;
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
int audit_fd;
if (audit_fd < 0)
if (m->n_reloading > 0)
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 = 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];
Iterator i;
assert(m);
if (m->n_running_jobs == 0)
if (m->jobs_in_progress_event_source) {
manager_flip_auto_status(m, false);
m->confirm_spawn = false;
manager_set_first_boot(m, false);
if (!log_on_console())
NULL);
initrd_usec = 0;
if (!log_on_console())
NULL);
if (!log_on_console())
NULL);
if (u->cgroup_path)
cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
sd_notifyf(false,
assert(m);
if (*generator)
return log_oom();
p, strerror(-r));
free(p);
const char *s = NULL;
return -EINVAL;
return log_oom();
p, strerror(-r));
free(p);
return log_oom();
if (!mkdtemp(p)) {
free(p);
return -errno;
*generator = p;
assert(m);
if (!*generator)
const char *generator_path;
assert(m);
if (m->test_run)
goto finish;
goto finish;
goto finish;
assert(m);
if (!*generator)
assert(m);
assert(m);
l = m->environment;
return -ENOMEM;
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, bool ephemeral, const char *status, const char *format, ...) {
if (!manager_get_show_status(m))
assert(m);
return -ENOMEM;
if (!found) {
assert(m);
assert(m);
Unit *u;
assert(m);
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;