manager.c revision 9771b62d8b833e06606178f19f4da2ba802931b5
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering This file is part of systemd.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Copyright 2010 Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is free software; you can redistribute it and/or modify it
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering under the terms of the GNU Lesser General Public License as published by
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering (at your option) any later version.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is distributed in the hope that it will be useful, but
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Lesser General Public License for more details.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering You should have received a copy of the GNU Lesser General Public License
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering/* Initial delay and the interval for printing status messages about running jobs */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_run_generators(Manager *m);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic void manager_undo_generators(Manager *m);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic void manager_watch_jobs_in_progress(Manager *m) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering (void) sd_event_source_set_description(m->jobs_in_progress_event_source, "manager-jobs-in-progress");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(buflen >= CYLON_BUFFER_EXTRA + width + 1);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(pos <= width+1); /* 0 or width+1 mean that the center light is behind the corner */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringvoid manager_flip_auto_status(Manager *m, bool enable) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (m->show_status == SHOW_STATUS_TEMPORARY)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering manager_set_show_status(m, SHOW_STATUS_AUTO);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic void manager_print_jobs_in_progress(Manager *m) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (j->state == JOB_RUNNING && counter++ == print_nr)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* m->n_running_jobs must be consistent with the contents of m->jobs,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering * so the above loop must have succeeded in finding j. */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering cylon_pos = m->jobs_in_progress_iteration % 14;
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek if (job_get_timeout(j, &x) > 0)
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "%sA %s job is running for %s (%s / %s)",
7b909d7407965c03caaba30daae7aee113627a83Josh Triplettstatic int have_ask_password(void) {
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett return false;
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirovstatic int manager_dispatch_ask_password_fd(sd_event_source *source,
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov int fd, uint32_t revents, void *userdata) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt /* Log error but continue. Negative have_ask_password
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett * is treated as unknown status. */
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett log_error_errno(m->have_ask_password, "Failed to list /run/systemd/ask-password: %m");
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirovstatic void manager_close_ask_password(Manager *m) {
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplettstatic int manager_check_ask_password(Manager *m) {
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula mkdir_p_label("/run/systemd/ask-password", 0755);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett return log_error_errno(errno, "inotify_init1() failed: %m");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed to add watch on /run/systemd/ask-password: %m");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering r = sd_event_add_io(m->event, &m->ask_password_event_source,
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_error_errno(errno, "Failed to add event source for /run/systemd/ask-password: %m");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering (void) sd_event_source_set_description(m->ask_password_event_source, "manager-ask-password");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering /* Queries might have been added meanwhile... */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering manager_dispatch_ask_password_fd(m->ask_password_event_source,
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int manager_watch_idle_pipe(Manager *m) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_event_add_io(m->event, &m->idle_pipe_event_source, m->idle_pipe[2], EPOLLIN, manager_dispatch_idle_pipe_fd, m);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return log_error_errno(r, "Failed to watch idle pipe: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering (void) sd_event_source_set_description(m->idle_pipe_event_source, "manager-idle-pipe");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic void manager_close_idle_pipe(Manager *m) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int manager_setup_time_change(Manager *m) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek /* We only care for the cancellation event, hence we set the
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering * timeout to the latest possible value. */
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering m->time_change_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return log_error_errno(errno, "Failed to create timerfd: %m");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering log_debug_errno(errno, "Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering m->time_change_fd = safe_close(m->time_change_fd);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return log_error_errno(r, "Failed to create time change event source: %m");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering (void) sd_event_source_set_description(m->time_change_event_source, "manager-time-change");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poetteringstatic int enable_special_signals(Manager *m) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering /* Enable that we get SIGINT on control-alt-del. In containers
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering * this will fail with EPERM (older) or EINVAL (newer), so
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering * ignore that. */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_warning_errno(errno, "Failed to enable ctrl-alt-del handling: %m");
73e231abde39f22097df50542c745e01de879836Jan Engelhardt fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* Support systems without virtual console */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_warning_errno(errno, "Failed to open /dev/tty0: %m");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering /* Enable that we get SIGWINCH on kbrequest */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_warning_errno(errno, "Failed to enable kbrequest handling: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int manager_setup_signals(Manager *m) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
bca81be7755d15e7369d764bfa94a7ca6c595c76Topi Miettinen /* We make liberal use of realtime signals here. On
bca81be7755d15e7369d764bfa94a7ca6c595c76Topi Miettinen * Linux/glibc we have 30 of them (with the exception of Linux
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering * (aka SIGRTMAX). */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering SIGINT, /* Kernel sends us this on control-alt-del */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering SIGRTMIN+0, /* systemd: start default.target */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+1, /* systemd: isolate rescue.target */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+2, /* systemd: isolate emergency.target */
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek SIGRTMIN+3, /* systemd: start halt.target */
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek SIGRTMIN+4, /* systemd: start poweroff.target */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+5, /* systemd: start reboot.target */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+6, /* systemd: start kexec.target */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering /* ... space for more special targets ... */
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek SIGRTMIN+13, /* systemd: Immediate halt */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+14, /* systemd: Immediate poweroff */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+15, /* systemd: Immediate reboot */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+16, /* systemd: Immediate kexec */
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek /* ... space for more immediate system state changes ... */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+20, /* systemd: enable status messages */
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek SIGRTMIN+21, /* systemd: disable status messages */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
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 = m->utab_inotify_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) {
if (fd < 0)
return -EINVAL;
if (!m->notify_socket)
return log_oom();
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);
#ifdef ENABLE_KDBUS
assert(m);
if (!is_kdbus_available())
return -ESOCKTNOSUPPORT;
if (m->kdbus_fd < 0)
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;
if (u->id)
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;
return NULL;
for (c = 0; c < _UNIT_TYPE_MAX; c++)
bus_done(m);
for (i = 0; i < _RLIMIT_MAX; i++)
free(m);
return NULL;
UnitType c;
assert(m);
for (c = 0; c < _UNIT_TYPE_MAX; c++) {
if (!unit_type_supported(c)) {
Iterator i;
Unit *u;
assert(m);
if (u->id != k)
r = 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 = manager_run_generators(m);
r = lookup_paths_init(
NULL,
if (serialization)
m->n_reloading ++;
r = manager_enumerate(m);
if (serialization)
q = manager_setup_notify(m);
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 sd_bus_error_setf(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated.");
log_unit_debug(unit, "Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode));
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)
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;
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:
status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately.");
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, r;
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;
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);
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->n_reloading > 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 (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)
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);
if (!found) {
assert(m);
assert(m);
unsigned size;
assert(m);
if (failed) {
log_oom();
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;