+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
#include "alloc-util.h"
#include "cgroup-util.h"
#include "def.h"
+#include "exec-util.h"
#include "fileio.h"
#include "killall.h"
#include "log.h"
return switch_root("/run/initramfs", "/oldroot", false, MS_BIND);
}
-
int main(int argc, char *argv[]) {
bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
bool in_container, use_watchdog = false;
umask(0022);
- if (getpid() != 1) {
+ if (getpid_cached() != 1) {
log_error("Not executed by init (PID 1).");
r = -EPERM;
goto error;
}
(void) cg_get_root_path(&cgroup);
+ in_container = detect_container() > 0;
use_watchdog = !!getenv("WATCHDOG_USEC");
- /* lock us into memory */
+ /* Lock us into memory */
mlockall(MCL_CURRENT|MCL_FUTURE);
+ /* Synchronize everything that is not written to disk yet at this point already. This is a good idea so that
+ * slow IO is processed here already and the final process killing spree is not impacted by processes
+ * desperately trying to sync IO to disk within their timeout. */
+ if (!in_container)
+ sync();
+
log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true);
log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false);
- in_container = detect_container() > 0;
-
need_umount = !in_container;
need_swapoff = !in_container;
need_loop_detach = !in_container;
arguments[0] = NULL;
arguments[1] = arg_verb;
arguments[2] = NULL;
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
if (!in_container && !in_initrd() &&
access("/run/initramfs/shutdown", X_OK) == 0) {
need_loop_detach ? " loop devices," : "",
need_dm_detach ? " DM devices," : "");
- /* The kernel will automaticall flush ATA disks and suchlike
- * on reboot(), but the file systems need to be synce'd
- * explicitly in advance. So let's do this here, but not
- * needlessly slow down containers. */
+ /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be
+ * sync'ed explicitly in advance. So let's do this here, but not needlessly slow down containers. Note that we
+ * sync'ed things already once above, but we did some more work since then which might have caused IO, hence
+ * let's doit once more. */
if (!in_container)
sync();
if (!in_container) {
_cleanup_free_ char *param = NULL;
- if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
+ r = read_one_line_file("/run/systemd/reboot-param", ¶m);
+ if (r < 0 && r != -ENOENT)
+ log_warning_errno(r, "Failed to read reboot parameter file: %m");
+
+ if (!isempty(param)) {
log_info("Rebooting with argument '%s'.", param);
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
+ log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
}
}