SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
SIGRTMIN+0, /* systemd: start default.target */
- SIGRTMIN+1, /* systemd: start rescue.target */
+ SIGRTMIN+1, /* systemd: isolate rescue.target */
SIGRTMIN+2, /* systemd: isolate emergency.target */
SIGRTMIN+3, /* systemd: start halt.target */
SIGRTMIN+4, /* systemd: start poweroff.target */
SIGRTMIN+5, /* systemd: start reboot.target */
+ SIGRTMIN+6, /* systemd: start kexec.target */
+ SIGRTMIN+13, /* systemd: Immediate halt */
+ SIGRTMIN+14, /* systemd: Immediate poweroff */
+ SIGRTMIN+15, /* systemd: Immediate reboot */
+ SIGRTMIN+16, /* systemd: Immediate kexec */
-1);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
m->audit_fd = -1;
#endif
- m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = -1;
+ m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_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 around as "null-like" value */
if (!(m->environment = strv_copy(environ)))
job_add_to_run_queue(j);
job_add_to_dbus_queue(j);
job_start_timer(j);
+
+ log_debug("Installed new job %s/%s as %u", j->unit->meta.id, job_type_to_string(j->type), (unsigned) j->id);
}
/* As last step, kill all remaining job dependencies. */
if (type != JOB_STOP && unit->meta.load_state == UNIT_ERROR) {
dbus_set_error(e, BUS_ERROR_LOAD_FAILED,
"Unit %s failed to load: %s. "
- "You might find more information in the system logs.",
+ "See system logs and 'systemctl status' for details.",
unit->meta.id,
strerror(-unit->meta.load_error));
return -EINVAL;
if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR)
goto fail;
+ SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BIND_TO], i)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR)
+ goto fail;
+
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, e, NULL)) < 0 && r != -EBADR) {
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
goto fail;
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTED_BY], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, e, NULL)) < 0 && r != -EBADR)
goto fail;
} else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR)
goto fail;
+
+ SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BOUND_BY], i)
+ if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR)
+ goto fail;
}
/* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */
}
/* Run the exit target if there is one, if not, just exit. */
- if (manager_start_target(m, SPECIAL_EXIT_SERVICE, JOB_REPLACE) < 0) {
+ if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
m->exit_code = MANAGER_EXIT;
return 0;
}
break;
default: {
- static const char * const table[] = {
+ /* Starting SIGRTMIN+0 */
+ static const char * const target_table[] = {
[0] = SPECIAL_DEFAULT_TARGET,
[1] = SPECIAL_RESCUE_TARGET,
[2] = SPECIAL_EMERGENCY_TARGET,
[3] = SPECIAL_HALT_TARGET,
[4] = SPECIAL_POWEROFF_TARGET,
- [5] = SPECIAL_REBOOT_TARGET
+ [5] = SPECIAL_REBOOT_TARGET,
+ [6] = SPECIAL_KEXEC_TARGET
+ };
+
+ /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
+ static const ManagerExitCode code_table[] = {
+ [0] = MANAGER_HALT,
+ [1] = MANAGER_POWEROFF,
+ [2] = MANAGER_REBOOT,
+ [3] = MANAGER_KEXEC
};
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
- (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(table)) {
- manager_start_target(m, table[sfsi.ssi_signo - SIGRTMIN],
+ (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
+ manager_start_target(m, target_table[sfsi.ssi_signo - SIGRTMIN],
(sfsi.ssi_signo == 1 || sfsi.ssi_signo == 2) ? JOB_ISOLATE : JOB_REPLACE);
break;
}
+ if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
+ (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
+ m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
+ break;
+ }
+
log_warning("Got unhandled signal <%s>.", strna(signal_to_string(sfsi.ssi_signo)));
}
}
mount_fd_event(m, ev->events);
break;
+ case WATCH_SWAP:
+ /* Some swap table change, intended for the swap subsystem */
+ swap_fd_event(m, ev->events);
+ break;
+
case WATCH_UDEV:
/* Some notification from udev, intended for the device subsystem */
device_fd_event(m, ev->events);
if (manager_dispatch_dbus_queue(m) > 0)
continue;
+ if (swap_dispatch_reload(m) > 0)
+ continue;
+
if ((n = epoll_wait(m->epoll_fd, &event, 1, -1)) < 0) {
if (errno == EINTR)
assert(f);
assert(fds);
- fprintf(f, "startup-timestamp=%llu %llu\n\n",
- (unsigned long long) m->startup_timestamp.realtime,
- (unsigned long long) m->startup_timestamp.monotonic);
+ dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
+ dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
+
+ fputc('\n', f);
HASHMAP_FOREACH_KEY(u, t, m->units, i) {
if (u->meta.id != t)
if (l[0] == 0)
break;
- if (startswith(l, "startup-timestamp=")) {
- unsigned long long a, b;
-
- if (sscanf(l+18, "%lli %llu", &a, &b) != 2)
- log_debug("Failed to parse startup timestamp value %s", l+18);
- else {
- m->startup_timestamp.realtime = a;
- m->startup_timestamp.monotonic = b;
- }
- } else
+ if (startswith(l, "startup-timestamp="))
+ dual_timestamp_deserialize(l+18, &m->startup_timestamp);
+ else if (startswith(l, "finish-timestamp="))
+ dual_timestamp_deserialize(l+17, &m->finish_timestamp);
+ else
log_debug("Unknown serialization item '%s'", l);
}