manager.c   manager.c 
skipping to change at line 44 skipping to change at line 44
#include <termios.h> #include <termios.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h> #include <dirent.h>
#ifdef HAVE_AUDIT #ifdef HAVE_AUDIT
#include <libaudit.h> #include <libaudit.h>
#endif #endif
#include <systemd/sd-daemon.h> #include "systemd/sd-daemon.h"
#include "systemd/sd-id128.h"
#include "systemd/sd-messages.h"
#include "manager.h" #include "manager.h"
#include "transaction.h" #include "transaction.h"
#include "hashmap.h" #include "hashmap.h"
#include "macro.h" #include "macro.h"
#include "strv.h" #include "strv.h"
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
#include "mkdir.h" #include "mkdir.h"
#include "ratelimit.h" #include "ratelimit.h"
skipping to change at line 139 skipping to change at line 141
return 0; return 0;
} }
static int enable_special_signals(Manager *m) { static int enable_special_signals(Manager *m) {
int fd; int fd;
assert(m); assert(m);
/* Enable that we get SIGINT on control-alt-del. In containers /* Enable that we get SIGINT on control-alt-del. In containers
* this will fail with EPERM, so ignore that. */ * this will fail with EPERM (older) or EINVAL (newer), so
if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM) * ignore that. */
if (reboot(RB_DISABLE_CAD) < 0 && errno != EPERM && errno != EINVAL
)
log_warning("Failed to enable ctrl-alt-del handling: %m"); log_warning("Failed to enable ctrl-alt-del handling: %m");
fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
/* Support systems without virtual console */ /* Support systems without virtual console */
if (fd != -ENOENT) if (fd != -ENOENT)
log_warning("Failed to open /dev/tty0: %m"); log_warning("Failed to open /dev/tty0: %m");
} else { } else {
/* Enable that we get SIGWINCH on kbrequest */ /* Enable that we get SIGWINCH on kbrequest */
if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0) if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0)
skipping to change at line 216 skipping to change at line 219
if ((m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOE XEC)) < 0) if ((m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOE XEC)) < 0)
return -errno; return -errno;
zero(ev); zero(ev);
ev.events = EPOLLIN; ev.events = EPOLLIN;
ev.data.ptr = &m->signal_watch; ev.data.ptr = &m->signal_watch;
if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0) if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
return -errno; return -errno;
if (m->running_as == MANAGER_SYSTEM) if (m->running_as == SYSTEMD_SYSTEM)
return enable_special_signals(m); return enable_special_signals(m);
return 0; return 0;
} }
static void manager_strip_environment(Manager *m) { static void manager_strip_environment(Manager *m) {
assert(m); assert(m);
/* Remove variables from the inherited set that are part of /* Remove variables from the inherited set that are part of
* the container interface: * the container interface:
* http://www.freedesktop.org/wiki/Software/systemd/ContainerInterf ace */ * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterf ace */
strv_remove_prefix(m->environment, "container="); strv_remove_prefix(m->environment, "container=");
strv_remove_prefix(m->environment, "container_"); strv_remove_prefix(m->environment, "container_");
/* Remove variables from the inherited set that are part of /* Remove variables from the inherited set that are part of
* the initrd interface: * the initrd interface:
* http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */ * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
strv_remove_prefix(m->environment, "RD_"); strv_remove_prefix(m->environment, "RD_");
} }
int manager_new(ManagerRunningAs running_as, Manager **_m) { int manager_new(SystemdRunningAs running_as, Manager **_m) {
Manager *m; Manager *m;
int r = -ENOMEM; int r = -ENOMEM;
assert(_m); assert(_m);
assert(running_as >= 0); assert(running_as >= 0);
assert(running_as < _MANAGER_RUNNING_AS_MAX); assert(running_as < _SYSTEMD_RUNNING_AS_MAX);
if (!(m = new0(Manager, 1))) m = new0(Manager, 1);
if (!m)
return -ENOMEM; return -ENOMEM;
dual_timestamp_get(&m->startup_timestamp); dual_timestamp_get(&m->userspace_timestamp);
m->running_as = running_as; m->running_as = running_as;
m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = - 1; m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = - 1;
m->exit_code = _MANAGER_EXIT_CODE_INVALID; m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->pin_cgroupfs_fd = -1; m->pin_cgroupfs_fd = -1;
m->idle_pipe[0] = m->idle_pipe[1] = -1; m->idle_pipe[0] = m->idle_pipe[1] = -1;
#ifdef HAVE_AUDIT #ifdef HAVE_AUDIT
m->audit_fd = -1; m->audit_fd = -1;
#endif #endif
m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epol l_fd = m->dev_autofs_fd = m->swap_watch.fd = -1; m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epol l_fd = m->dev_autofs_fd = m->swap_watch.fd = -1;
m->current_job_id = 1; /* start as id #1, so that we can leave #0 a round as "null-like" value */ m->current_job_id = 1; /* start as id #1, so that we can leave #0 a round as "null-like" value */
m->environment = strv_copy(environ); m->environment = strv_copy(environ);
if (!m->environment) if (!m->environment)
goto fail; goto fail;
manager_strip_environment(m); manager_strip_environment(m);
if (running_as == MANAGER_SYSTEM) { if (running_as == SYSTEMD_SYSTEM) {
m->default_controllers = strv_new("cpu", NULL); m->default_controllers = strv_new("cpu", NULL);
if (!m->default_controllers) if (!m->default_controllers)
goto fail; goto fail;
} }
if (!(m->units = hashmap_new(string_hash_func, string_compare_func) )) if (!(m->units = hashmap_new(string_hash_func, string_compare_func) ))
goto fail; goto fail;
if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func ))) if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func )))
goto fail; goto fail;
skipping to change at line 303 skipping to change at line 307
if ((r = manager_setup_signals(m)) < 0) if ((r = manager_setup_signals(m)) < 0)
goto fail; goto fail;
if ((r = manager_setup_cgroup(m)) < 0) if ((r = manager_setup_cgroup(m)) < 0)
goto fail; goto fail;
if ((r = manager_setup_notify(m)) < 0) if ((r = manager_setup_notify(m)) < 0)
goto fail; goto fail;
/* Try to connect to the busses, if possible. */ /* Try to connect to the busses, if possible. */
if ((r = bus_init(m, running_as != MANAGER_SYSTEM)) < 0) if ((r = bus_init(m, running_as != SYSTEMD_SYSTEM)) < 0)
goto fail; goto fail;
#ifdef HAVE_AUDIT #ifdef HAVE_AUDIT
if ((m->audit_fd = audit_open()) < 0 && if ((m->audit_fd = audit_open()) < 0 &&
/* If the kernel lacks netlink or audit support, /* If the kernel lacks netlink or audit support,
* don't worry about it. */ * don't worry about it. */
errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
log_error("Failed to connect to audit log: %m"); log_error("Failed to connect to audit log: %m");
#endif #endif
skipping to change at line 733 skipping to change at line 737
int manager_add_job_by_name(Manager *m, JobType type, const char *name, Job Mode mode, bool override, DBusError *e, Job **_ret) { int manager_add_job_by_name(Manager *m, JobType type, const char *name, Job Mode mode, bool override, DBusError *e, Job **_ret) {
Unit *unit; Unit *unit;
int r; int r;
assert(m); assert(m);
assert(type < _JOB_TYPE_MAX); assert(type < _JOB_TYPE_MAX);
assert(name); assert(name);
assert(mode < _JOB_MODE_MAX); assert(mode < _JOB_MODE_MAX);
if ((r = manager_load_unit(m, name, NULL, NULL, &unit)) < 0) r = manager_load_unit(m, name, NULL, NULL, &unit);
if (r < 0)
return r; return r;
return manager_add_job(m, type, unit, mode, override, e, _ret); return manager_add_job(m, type, unit, mode, override, e, _ret);
} }
Job *manager_get_job(Manager *m, uint32_t id) { Job *manager_get_job(Manager *m, uint32_t id) {
assert(m); assert(m);
return hashmap_get(m->jobs, UINT32_TO_PTR(id)); return hashmap_get(m->jobs, UINT32_TO_PTR(id));
} }
skipping to change at line 845 skipping to change at line 850
} }
int manager_load_unit(Manager *m, const char *name, const char *path, DBusE rror *e, Unit **_ret) { int manager_load_unit(Manager *m, const char *name, const char *path, DBusE rror *e, Unit **_ret) {
int r; int r;
assert(m); assert(m);
/* This will load the service information files, but not actually /* This will load the service information files, but not actually
* start any services or anything. */ * start any services or anything. */
if ((r = manager_load_unit_prepare(m, name, path, e, _ret)) != 0) r = manager_load_unit_prepare(m, name, path, e, _ret);
if (r != 0)
return r; return r;
manager_dispatch_load_queue(m); manager_dispatch_load_queue(m);
if (_ret) if (_ret)
*_ret = unit_follow_merge(*_ret); *_ret = unit_follow_merge(*_ret);
return 0; return 0;
} }
skipping to change at line 1142 skipping to change at line 1148
} else } else
log_debug("Received SIG%s.", signal_to_string(sfsi. ssi_signo)); log_debug("Received SIG%s.", signal_to_string(sfsi. ssi_signo));
switch (sfsi.ssi_signo) { switch (sfsi.ssi_signo) {
case SIGCHLD: case SIGCHLD:
sigchld = true; sigchld = true;
break; break;
case SIGTERM: case SIGTERM:
if (m->running_as == MANAGER_SYSTEM) { if (m->running_as == SYSTEMD_SYSTEM) {
/* This is for compatibility with the /* This is for compatibility with the
* original sysvinit */ * original sysvinit */
m->exit_code = MANAGER_REEXECUTE; m->exit_code = MANAGER_REEXECUTE;
break; break;
} }
/* Fall through */ /* Fall through */
case SIGINT: case SIGINT:
if (m->running_as == MANAGER_SYSTEM) { if (m->running_as == SYSTEMD_SYSTEM) {
manager_start_target(m, SPECIAL_CTRL_ALT_DE L_TARGET, JOB_REPLACE); manager_start_target(m, SPECIAL_CTRL_ALT_DE L_TARGET, JOB_REPLACE);
break; break;
} }
/* Run the exit target if there is one, if not, jus t exit. */ /* Run the exit target if there is one, if not, jus t exit. */
if (manager_start_target(m, SPECIAL_EXIT_TARGET, JO B_REPLACE) < 0) { if (manager_start_target(m, SPECIAL_EXIT_TARGET, JO B_REPLACE) < 0) {
m->exit_code = MANAGER_EXIT; m->exit_code = MANAGER_EXIT;
return 0; return 0;
} }
break; break;
case SIGWINCH: case SIGWINCH:
if (m->running_as == MANAGER_SYSTEM) if (m->running_as == SYSTEMD_SYSTEM)
manager_start_target(m, SPECIAL_KBREQUEST_T ARGET, JOB_REPLACE); manager_start_target(m, SPECIAL_KBREQUEST_T ARGET, JOB_REPLACE);
/* This is a nop on non-init */ /* This is a nop on non-init */
break; break;
case SIGPWR: case SIGPWR:
if (m->running_as == MANAGER_SYSTEM) if (m->running_as == SYSTEMD_SYSTEM)
manager_start_target(m, SPECIAL_SIGPWR_TARG ET, JOB_REPLACE); manager_start_target(m, SPECIAL_SIGPWR_TARG ET, JOB_REPLACE);
/* This is a nop on non-init */ /* This is a nop on non-init */
break; break;
case SIGUSR1: { case SIGUSR1: {
Unit *u; Unit *u;
u = manager_get_unit(m, SPECIAL_DBUS_SERVICE); u = manager_get_unit(m, SPECIAL_DBUS_SERVICE);
skipping to change at line 1437 skipping to change at line 1443
* before we were exec()'ed. Leat's reap them */ * before we were exec()'ed. Leat's reap them */
r = manager_dispatch_sigchld(m); r = manager_dispatch_sigchld(m);
if (r < 0) if (r < 0)
return r; return r;
while (m->exit_code == MANAGER_RUNNING) { while (m->exit_code == MANAGER_RUNNING) {
struct epoll_event event; struct epoll_event event;
int n; int n;
int wait_msec = -1; int wait_msec = -1;
if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYS TEM) if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYS TEM)
watchdog_ping(); watchdog_ping();
if (!ratelimit_test(&rl)) { if (!ratelimit_test(&rl)) {
/* Yay, something is going seriously wrong, pause a little */ /* Yay, something is going seriously wrong, pause a little */
log_warning("Looping too fast. Throttling execution a little."); log_warning("Looping too fast. Throttling execution a little.");
sleep(1); sleep(1);
continue; continue;
} }
if (manager_dispatch_load_queue(m) > 0) if (manager_dispatch_load_queue(m) > 0)
skipping to change at line 1469 skipping to change at line 1475
if (manager_dispatch_gc_queue(m) > 0) if (manager_dispatch_gc_queue(m) > 0)
continue; continue;
if (manager_dispatch_dbus_queue(m) > 0) if (manager_dispatch_dbus_queue(m) > 0)
continue; continue;
if (swap_dispatch_reload(m) > 0) if (swap_dispatch_reload(m) > 0)
continue; continue;
/* Sleep for half the watchdog time */ /* Sleep for half the watchdog time */
if (m->runtime_watchdog > 0 && m->running_as == MANAGER_SYS TEM) { if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYS TEM) {
wait_msec = (int) (m->runtime_watchdog / 2 / USEC_P ER_MSEC); wait_msec = (int) (m->runtime_watchdog / 2 / USEC_P ER_MSEC);
if (wait_msec <= 0) if (wait_msec <= 0)
wait_msec = 1; wait_msec = 1;
} else } else
wait_msec = -1; wait_msec = -1;
n = epoll_wait(m->epoll_fd, &event, 1, wait_msec); n = epoll_wait(m->epoll_fd, &event, 1, wait_msec);
if (n < 0) { if (n < 0) {
if (errno == EINTR) if (errno == EINTR)
skipping to change at line 1559 skipping to change at line 1565
char *p; char *p;
if (m->audit_fd < 0) if (m->audit_fd < 0)
return; return;
/* Don't generate audit events if the service was already /* Don't generate audit events if the service was already
* started and we're just deserializing */ * started and we're just deserializing */
if (m->n_reloading > 0) if (m->n_reloading > 0)
return; return;
if (m->running_as != MANAGER_SYSTEM) if (m->running_as != SYSTEMD_SYSTEM)
return; return;
if (u->type != UNIT_SERVICE) if (u->type != UNIT_SERVICE)
return; return;
if (!(p = unit_name_to_prefix_and_instance(u->id))) { if (!(p = unit_name_to_prefix_and_instance(u->id))) {
log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM)); log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM));
return; return;
} }
skipping to change at line 1596 skipping to change at line 1602
int fd = -1; int fd = -1;
union sockaddr_union sa; union sockaddr_union sa;
int n = 0; int n = 0;
char *message = NULL; char *message = NULL;
/* Don't generate plymouth events if the service was already /* Don't generate plymouth events if the service was already
* started and we're just deserializing */ * started and we're just deserializing */
if (m->n_reloading > 0) if (m->n_reloading > 0)
return; return;
if (m->running_as != MANAGER_SYSTEM) if (m->running_as != SYSTEMD_SYSTEM)
return; return;
if (u->type != UNIT_SERVICE && if (u->type != UNIT_SERVICE &&
u->type != UNIT_MOUNT && u->type != UNIT_MOUNT &&
u->type != UNIT_SWAP) u->type != UNIT_SWAP)
return; return;
/* We set SOCK_NONBLOCK here so that we rather drop the /* We set SOCK_NONBLOCK here so that we rather drop the
* message then wait for plymouth */ * message then wait for plymouth */
if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0 )) < 0) { if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0 )) < 0) {
skipping to change at line 1695 skipping to change at line 1701
} }
int manager_open_serialization(Manager *m, FILE **_f) { int manager_open_serialization(Manager *m, FILE **_f) {
char *path = NULL; char *path = NULL;
mode_t saved_umask; mode_t saved_umask;
int fd; int fd;
FILE *f; FILE *f;
assert(_f); assert(_f);
if (m->running_as == MANAGER_SYSTEM) if (m->running_as == SYSTEMD_SYSTEM)
asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned l ong) getpid()); asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned l ong) getpid());
else else
asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned l ong) getpid()); asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned l ong) getpid());
if (!path) if (!path)
return -ENOMEM; return -ENOMEM;
saved_umask = umask(0077); saved_umask = umask(0077);
fd = mkostemp(path, O_RDWR|O_CLOEXEC); fd = mkostemp(path, O_RDWR|O_CLOEXEC);
umask(saved_umask); umask(saved_umask);
skipping to change at line 1742 skipping to change at line 1748
assert(f); assert(f);
assert(fds); assert(fds);
m->n_reloading ++; m->n_reloading ++;
fprintf(f, "current-job-id=%i\n", m->current_job_id); fprintf(f, "current-job-id=%i\n", m->current_job_id);
fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr)); fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs); fprintf(f, "n-installed-jobs=%u\n", m->n_installed_jobs);
fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs); fprintf(f, "n-failed-jobs=%u\n", m->n_failed_jobs);
dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_time
stamp);
dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestam
p);
dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestam
p);
dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestam p); dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestam p);
if (!in_initrd()) { if (!in_initrd()) {
dual_timestamp_serialize(f, "startup-timestamp", &m->startu p_timestamp); dual_timestamp_serialize(f, "userspace-timestamp", &m->user space_timestamp);
dual_timestamp_serialize(f, "finish-timestamp", &m->finish_ timestamp); dual_timestamp_serialize(f, "finish-timestamp", &m->finish_ timestamp);
} }
fputc('\n', f); fputc('\n', f);
HASHMAP_FOREACH_KEY(u, t, m->units, i) { HASHMAP_FOREACH_KEY(u, t, m->units, i) {
if (u->id != t) if (u->id != t)
continue; continue;
if (!unit_can_serialize(u)) if (!unit_can_serialize(u))
skipping to change at line 1837 skipping to change at line 1846
log_debug("Failed to parse failed jobs coun ter %s", l+14); log_debug("Failed to parse failed jobs coun ter %s", l+14);
else else
m->n_failed_jobs += n; m->n_failed_jobs += n;
} else if (startswith(l, "taint-usr=")) { } else if (startswith(l, "taint-usr=")) {
int b; int b;
if ((b = parse_boolean(l+10)) < 0) if ((b = parse_boolean(l+10)) < 0)
log_debug("Failed to parse taint /usr flag %s", l+10); log_debug("Failed to parse taint /usr flag %s", l+10);
else else
m->taint_usr = m->taint_usr || b; m->taint_usr = m->taint_usr || b;
} else if (startswith(l, "initrd-timestamp=")) } else if (startswith(l, "firmware-timestamp="))
dual_timestamp_deserialize(l+19, &m->firmware_times
tamp);
else if (startswith(l, "loader-timestamp="))
dual_timestamp_deserialize(l+17, &m->loader_timesta
mp);
else if (startswith(l, "kernel-timestamp="))
dual_timestamp_deserialize(l+17, &m->kernel_timesta
mp);
else if (startswith(l, "initrd-timestamp="))
dual_timestamp_deserialize(l+17, &m->initrd_timesta mp); dual_timestamp_deserialize(l+17, &m->initrd_timesta mp);
else if (startswith(l, "startup-timestamp=")) else if (startswith(l, "userspace-timestamp="))
dual_timestamp_deserialize(l+18, &m->startup_timest dual_timestamp_deserialize(l+20, &m->userspace_time
amp); stamp);
else if (startswith(l, "finish-timestamp=")) else if (startswith(l, "finish-timestamp="))
dual_timestamp_deserialize(l+17, &m->finish_timesta mp); dual_timestamp_deserialize(l+17, &m->finish_timesta mp);
else else
log_debug("Unknown serialization item '%s'", l); log_debug("Unknown serialization item '%s'", l);
} }
for (;;) { for (;;) {
Unit *u; Unit *u;
char name[UNIT_NAME_MAX+2]; char name[UNIT_NAME_MAX+2];
skipping to change at line 2005 skipping to change at line 2020
/* Returns true if the unit is inactive or going down */ /* Returns true if the unit is inactive or going down */
if (!(u = manager_get_unit(m, name))) if (!(u = manager_get_unit(m, name)))
return true; return true;
return unit_pending_inactive(u); return unit_pending_inactive(u);
} }
void manager_check_finished(Manager *m) { void manager_check_finished(Manager *m) {
char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], k ernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX]; char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], k ernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
usec_t kernel_usec, initrd_usec, userspace_usec, total_usec; usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, usersp ace_usec, total_usec;
assert(m); assert(m);
if (hashmap_size(m->jobs) > 0) if (hashmap_size(m->jobs) > 0)
return; return;
/* Notify Type=idle units that we are done now */ /* Notify Type=idle units that we are done now */
close_pipe(m->idle_pipe); close_pipe(m->idle_pipe);
/* Turn off confirm spawn now */ /* Turn off confirm spawn now */
m->confirm_spawn = false; m->confirm_spawn = false;
if (dual_timestamp_is_set(&m->finish_timestamp)) if (dual_timestamp_is_set(&m->finish_timestamp))
return; return;
dual_timestamp_get(&m->finish_timestamp); dual_timestamp_get(&m->finish_timestamp);
if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) { if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
userspace_usec = m->finish_timestamp.monotonic - m->startup /* Note that m->kernel_usec.monotonic is always at 0,
_timestamp.monotonic; * and m->firmware_usec.monotonic and
total_usec = m->finish_timestamp.monotonic; * m->loader_usec.monotonic should be considered
* negative values. */
firmware_usec = m->firmware_timestamp.monotonic - m->loader
_timestamp.monotonic;
loader_usec = m->loader_timestamp.monotonic - m->kernel_tim
estamp.monotonic;
userspace_usec = m->finish_timestamp.monotonic - m->userspa
ce_timestamp.monotonic;
total_usec = m->firmware_timestamp.monotonic + m->finish_ti
mestamp.monotonic;
if (dual_timestamp_is_set(&m->initrd_timestamp)) { if (dual_timestamp_is_set(&m->initrd_timestamp)) {
kernel_usec = m->initrd_timestamp.monotonic; kernel_usec = m->initrd_timestamp.monotonic - m->ke
initrd_usec = m->startup_timestamp.monotonic - m->i rnel_timestamp.monotonic;
nitrd_timestamp.monotonic; initrd_usec = m->userspace_timestamp.monotonic - m-
>initrd_timestamp.monotonic;
log_info("Startup finished in %s (kernel) + %s (ini if (!log_on_console())
trd) + %s (userspace) = %s.", log_struct(LOG_INFO,
format_timespan(kernel, sizeof(kernel), ke "MESSAGE_ID=" SD_ID128_FORMAT_ST
rnel_usec), R, SD_ID128_FORMAT_VAL(SD_MESSAGE_STARTUP_FINISHED),
format_timespan(initrd, sizeof(initrd), in "KERNEL_USEC=%llu", (unsigned lo
itrd_usec), ng long) kernel_usec,
format_timespan(userspace, sizeof(userspac "INITRD_USEC=%llu", (unsigned lo
e), userspace_usec), ng long) initrd_usec,
format_timespan(sum, sizeof(sum), total_us "USERSPACE_USEC=%llu", (unsigned
ec)); long long) userspace_usec,
"MESSAGE=Startup finished in %s
(kernel) + %s (initrd) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(k
ernel), kernel_usec),
format_timespan(initrd, sizeof(i
nitrd), initrd_usec),
format_timespan(userspace, sizeo
f(userspace), userspace_usec),
format_timespan(sum, sizeof(sum)
, total_usec),
NULL);
} else { } else {
kernel_usec = m->startup_timestamp.monotonic; kernel_usec = m->userspace_timestamp.monotonic - m- >kernel_timestamp.monotonic;
initrd_usec = 0; initrd_usec = 0;
log_info("Startup finished in %s (kernel) + %s (use if (!log_on_console())
rspace) = %s.", log_struct(LOG_INFO,
format_timespan(kernel, sizeof(kernel), ke "MESSAGE_ID=" SD_ID128_FORMAT_ST
rnel_usec), R, SD_ID128_FORMAT_VAL(SD_MESSAGE_STARTUP_FINISHED),
format_timespan(userspace, sizeof(userspac "KERNEL_USEC=%llu", (unsigned lo
e), userspace_usec), ng long) kernel_usec,
format_timespan(sum, sizeof(sum), total_us "USERSPACE_USEC=%llu", (unsigned
ec)); long long) userspace_usec,
"MESSAGE=Startup finished in %s
(kernel) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(k
ernel), kernel_usec),
format_timespan(userspace, sizeo
f(userspace), userspace_usec),
format_timespan(sum, sizeof(sum)
, total_usec),
NULL);
} }
} else { } else {
userspace_usec = initrd_usec = kernel_usec = 0; firmware_usec = loader_usec = initrd_usec = kernel_usec = 0
total_usec = m->finish_timestamp.monotonic - m->startup_tim ;
estamp.monotonic; total_usec = userspace_usec = m->finish_timestamp.monotonic
- m->userspace_timestamp.monotonic;
log_debug("Startup finished in %s.", if (!log_on_console())
format_timespan(sum, sizeof(sum), total_usec)); log_struct(LOG_INFO,
"MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID
128_FORMAT_VAL(SD_MESSAGE_STARTUP_FINISHED),
"USERSPACE_USEC=%llu", (unsigned long lo
ng) userspace_usec,
"MESSAGE=Startup finished in %s.",
format_timespan(sum, sizeof(sum), total_
usec),
NULL);
} }
bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec); bus_broadcast_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
sd_notifyf(false, sd_notifyf(false,
"READY=1\nSTATUS=Startup finished in %s.", "READY=1\nSTATUS=Startup finished in %s.",
format_timespan(sum, sizeof(sum), total_usec)); format_timespan(sum, sizeof(sum), total_usec));
} }
static int create_generator_dir(Manager *m, char **generator, const char *n ame) { static int create_generator_dir(Manager *m, char **generator, const char *n ame) {
char *p; char *p;
int r; int r;
assert(m); assert(m);
assert(generator); assert(generator);
assert(name); assert(name);
if (*generator) if (*generator)
return 0; return 0;
if (m->running_as == MANAGER_SYSTEM && getpid() == 1) { if (m->running_as == SYSTEMD_SYSTEM && getpid() == 1) {
p = strappend("/run/systemd/", name); p = strappend("/run/systemd/", name);
if (!p) if (!p)
return log_oom(); return log_oom();
r = mkdir_p_label(p, 0755); r = mkdir_p_label(p, 0755);
if (r < 0) { if (r < 0) {
log_error("Failed to create generator directory: %s ", strerror(-r)); log_error("Failed to create generator directory: %s ", strerror(-r));
free(p); free(p);
return r; return r;
skipping to change at line 2125 skipping to change at line 2165
void manager_run_generators(Manager *m) { void manager_run_generators(Manager *m) {
DIR *d = NULL; DIR *d = NULL;
const char *generator_path; const char *generator_path;
const char *argv[5]; const char *argv[5];
mode_t u; mode_t u;
int r; int r;
assert(m); assert(m);
generator_path = m->running_as == MANAGER_SYSTEM ? SYSTEM_GENERATOR _PATH : USER_GENERATOR_PATH; generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR _PATH : USER_GENERATOR_PATH;
d = opendir(generator_path); d = opendir(generator_path);
if (!d) { if (!d) {
if (errno == ENOENT) if (errno == ENOENT)
return; return;
log_error("Failed to enumerate generator directory: %m"); log_error("Failed to enumerate generator directory: %m");
return; return;
} }
r = create_generator_dir(m, &m->generator_unit_path, "generator"); r = create_generator_dir(m, &m->generator_unit_path, "generator");
skipping to change at line 2227 skipping to change at line 2267
} }
return 0; return 0;
} }
void manager_recheck_journal(Manager *m) { void manager_recheck_journal(Manager *m) {
Unit *u; Unit *u;
assert(m); assert(m);
if (m->running_as != MANAGER_SYSTEM) if (m->running_as != SYSTEMD_SYSTEM)
return; return;
u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET); u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET);
if (u && SOCKET(u)->state != SOCKET_RUNNING) { if (u && SOCKET(u)->state != SOCKET_RUNNING) {
log_close_journal(); log_close_journal();
return; return;
} }
u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE); u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE);
if (u && SERVICE(u)->state != SERVICE_RUNNING) { if (u && SERVICE(u)->state != SERVICE_RUNNING) {
skipping to change at line 2250 skipping to change at line 2290
} }
/* Hmm, OK, so the socket is fully up and the service is up /* Hmm, OK, so the socket is fully up and the service is up
* too, then let's make use of the thing. */ * too, then let's make use of the thing. */
log_open(); log_open();
} }
void manager_set_show_status(Manager *m, bool b) { void manager_set_show_status(Manager *m, bool b) {
assert(m); assert(m);
if (m->running_as != MANAGER_SYSTEM) if (m->running_as != SYSTEMD_SYSTEM)
return; return;
m->show_status = b; m->show_status = b;
if (b) if (b)
touch("/run/systemd/show-status"); touch("/run/systemd/show-status");
else else
unlink("/run/systemd/show-status"); unlink("/run/systemd/show-status");
} }
bool manager_get_show_status(Manager *m) { bool manager_get_show_status(Manager *m) {
assert(m); assert(m);
if (m->running_as != MANAGER_SYSTEM) if (m->running_as != SYSTEMD_SYSTEM)
return false; return false;
if (m->show_status) if (m->show_status)
return true; return true;
/* If Plymouth is running make sure we show the status, so /* If Plymouth is running make sure we show the status, so
* that there's something nice to see when people press Esc */ * that there's something nice to see when people press Esc */
return plymouth_running(); return plymouth_running();
} }
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX]
= {
[MANAGER_SYSTEM] = "system",
[MANAGER_USER] = "user"
};
DEFINE_STRING_TABLE_LOOKUP(manager_running_as, ManagerRunningAs);
 End of changes. 40 change blocks. 
64 lines changed or deleted 126 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/