1
0
mirror of https://github.com/systemd/systemd synced 2024-07-08 20:15:55 +00:00

Merge pull request #32847 from YHNdnzj/exitrd

shutdown: several cleanups, rename initrd to exitrd
This commit is contained in:
Yu Watanabe 2024-06-12 18:28:33 +09:00 committed by GitHub
commit 0ef63b11aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -52,8 +52,8 @@
#define SYNC_PROGRESS_ATTEMPTS 3
#define SYNC_TIMEOUT_USEC (10*USEC_PER_SEC)
static char* arg_verb;
static uint8_t arg_exit_code;
static const char *arg_verb = NULL;
static uint8_t arg_exit_code = 0;
static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC;
static int parse_argv(int argc, char *argv[]) {
@ -85,14 +85,14 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_LOG_LEVEL:
r = log_set_max_level_from_string(optarg);
if (r < 0)
log_error_errno(r, "Failed to parse log level %s, ignoring: %m", optarg);
log_warning_errno(r, "Failed to parse log level %s, ignoring: %m", optarg);
break;
case ARG_LOG_TARGET:
r = log_set_target_from_string(optarg);
if (r < 0)
log_error_errno(r, "Failed to parse log target %s, ignoring: %m", optarg);
log_warning_errno(r, "Failed to parse log target %s, ignoring: %m", optarg);
break;
@ -101,7 +101,7 @@ static int parse_argv(int argc, char *argv[]) {
if (optarg) {
r = log_show_color_from_string(optarg);
if (r < 0)
log_error_errno(r, "Failed to parse log color setting %s, ignoring: %m", optarg);
log_warning_errno(r, "Failed to parse log color setting %s, ignoring: %m", optarg);
} else
log_show_color(true);
@ -111,7 +111,7 @@ static int parse_argv(int argc, char *argv[]) {
if (optarg) {
r = log_show_location_from_string(optarg);
if (r < 0)
log_error_errno(r, "Failed to parse log location setting %s, ignoring: %m", optarg);
log_warning_errno(r, "Failed to parse log location setting %s, ignoring: %m", optarg);
} else
log_show_location(true);
@ -122,7 +122,7 @@ static int parse_argv(int argc, char *argv[]) {
if (optarg) {
r = log_show_time_from_string(optarg);
if (r < 0)
log_error_errno(r, "Failed to parse log time setting %s, ignoring: %m", optarg);
log_warning_errno(r, "Failed to parse log time setting %s, ignoring: %m", optarg);
} else
log_show_time(true);
@ -131,14 +131,14 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_EXIT_CODE:
r = safe_atou8(optarg, &arg_exit_code);
if (r < 0)
log_error_errno(r, "Failed to parse exit code %s, ignoring: %m", optarg);
log_warning_errno(r, "Failed to parse exit code %s, ignoring: %m", optarg);
break;
case ARG_TIMEOUT:
r = parse_sec(optarg, &arg_timeout);
if (r < 0)
log_error_errno(r, "Failed to parse shutdown timeout %s, ignoring: %m", optarg);
log_warning_errno(r, "Failed to parse shutdown timeout %s, ignoring: %m", optarg);
break;
@ -146,7 +146,7 @@ static int parse_argv(int argc, char *argv[]) {
if (!arg_verb)
arg_verb = optarg;
else
log_error("Excess arguments, ignoring");
log_warning("Got extraneous arguments, ignoring.");
break;
case '?':
@ -157,8 +157,7 @@ static int parse_argv(int argc, char *argv[]) {
}
if (!arg_verb)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Verb argument missing.");
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Verb argument missing.");
return 0;
}
@ -361,7 +360,6 @@ int main(int argc, char *argv[]) {
NULL
};
_cleanup_free_ char *cgroup = NULL;
char *arguments[3];
int cmd, r;
/* Close random fds we might have get passed, just for paranoia, before we open any new fds, for
@ -378,8 +376,12 @@ int main(int argc, char *argv[]) {
log_set_prohibit_ipc(true);
log_parse_environment();
if (getpid_cached() == 1)
log_set_always_reopen_console(true);
if (getpid_cached() != 1) {
log_error("Not executed by init (PID 1). Refusing to operate.");
return EXIT_FAILURE;
}
log_set_always_reopen_console(true);
r = parse_argv(argc, argv);
if (r < 0)
@ -389,11 +391,6 @@ int main(int argc, char *argv[]) {
umask(0022);
if (getpid_cached() != 1) {
r = log_error_errno(SYNTHETIC_ERRNO(EPERM), "Not executed by init (PID 1).");
goto error;
}
if (streq(arg_verb, "reboot"))
cmd = RB_AUTOBOOT;
else if (streq(arg_verb, "poweroff"))
@ -451,11 +448,11 @@ int main(int argc, char *argv[]) {
broadcast_signal(SIGKILL, true, false, arg_timeout);
bool need_umount = !in_container, need_swapoff = !in_container, need_loop_detach = !in_container,
need_dm_detach = !in_container, need_md_detach = !in_container, can_initrd, last_try = false;
can_initrd = !in_container && !in_initrd() && access("/run/initramfs/shutdown", X_OK) == 0;
need_dm_detach = !in_container, need_md_detach = !in_container,
can_exitrd = !in_container && !in_initrd() && access("/run/initramfs/shutdown", X_OK) >= 0;
/* Unmount all mountpoints, swaps, and loopback devices */
for (;;) {
for (bool last_try = false;;) {
bool changed = false;
(void) watchdog_ping();
@ -532,10 +529,10 @@ int main(int argc, char *argv[]) {
break;
}
if (!changed && !last_try && !can_initrd) {
if (!changed && !last_try && !can_exitrd) {
/* There are things we cannot get rid of. Loop one more time in which we will log
* with higher priority to inform the user. Note that we don't need to do this if
* there is an initrd to switch to, because that one is likely to get rid of the
* there is an exitrd to switch to, because that one is likely to get rid of the
* remaining mounts. If not, it will log about them. */
last_try = true;
continue;
@ -567,14 +564,16 @@ int main(int argc, char *argv[]) {
watchdog_close(/* disarm= */ false);
watchdog_free_device();
arguments[0] = NULL; /* Filled in by execute_directories(), when needed */
arguments[1] = arg_verb;
arguments[2] = NULL;
(void) execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments, NULL, EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS);
const char *arguments[] = {
NULL, /* Filled in by execute_directories(), when needed */
arg_verb,
NULL,
};
(void) execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, (char**) arguments, NULL, EXEC_DIR_PARALLEL | EXEC_DIR_IGNORE_ERRORS);
(void) rlimit_nofile_safe();
if (can_initrd) {
if (can_exitrd) {
r = switch_root_initramfs();
if (r >= 0) {
argv[0] = (char*) "/shutdown";
@ -583,7 +582,7 @@ int main(int argc, char *argv[]) {
(void) make_console_stdio();
log_info("Successfully changed into root pivot.\n"
"Returning to initrd...");
"Entering exitrd...");
execv("/shutdown", argv);
log_error_errno(errno, "Failed to execute shutdown binary: %m");
@ -628,13 +627,9 @@ int main(int argc, char *argv[]) {
r = safe_fork("(sd-kexec)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_WAIT, NULL);
if (r == 0) {
const char * const args[] = {
KEXEC, "-e", NULL
};
/* Child */
execv(args[0], (char * const *) args);
(void) execl(KEXEC, KEXEC, "-e", NULL);
log_debug_errno(errno, "Failed to execute '" KEXEC "' binary, proceeding with reboot(RB_KEXEC): %m");
/* execv failed (kexec binary missing?), so try simply reboot(RB_KEXEC) */
@ -675,7 +670,7 @@ int main(int argc, char *argv[]) {
r = log_error_errno(errno, "Failed to invoke reboot(): %m");
error:
error:
log_struct_errno(LOG_EMERG, r,
LOG_MESSAGE("Critical error while doing system shutdown: %m"),
"MESSAGE_ID=" SD_MESSAGE_SHUTDOWN_ERROR_STR);