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/ |