From 3584d3ca4f278ccd7d0cddf8b8352814f1e236d9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 20 Nov 2018 16:55:51 +0100 Subject: [PATCH 1/4] exit-status: introduce EXIT_EXCEPTION mapping to 255 --- src/shared/exit-status.c | 10 +++++++--- src/shared/exit-status.h | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c index 21af8c4c71..26b3060d9b 100644 --- a/src/shared/exit-status.c +++ b/src/shared/exit-status.c @@ -19,9 +19,10 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { * 79…199 │ (Currently unmapped) * 200…241 │ systemd's private error codes (might be extended to 254 in future development) * 242…254 │ (Currently unmapped, but see above) - * 255 │ (We should probably stay away from that one, it's frequently used by applications to indicate an - * │ exit reason that cannot really be expressed in a single exit status value — such as a propagated - * │ signal or such) + * + * 255 │ EXIT_EXCEPTION (We use this to propagate exit-by-signal events. It's frequently used by others apps (like bash) + * │ to indicate exit reason that cannot really be expressed in a single exit status value — such as a propagated + * │ signal or such, and we follow that logic here.) */ switch (status) { /* We always cover the ISO C ones */ @@ -155,6 +156,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { case EXIT_CONFIGURATION_DIRECTORY: return "CONFIGURATION_DIRECTORY"; + + case EXIT_EXCEPTION: + return "EXCEPTION"; } } diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h index c41e8b82c3..510eb319cf 100644 --- a/src/shared/exit-status.h +++ b/src/shared/exit-status.h @@ -69,6 +69,8 @@ enum { EXIT_CACHE_DIRECTORY, EXIT_LOGS_DIRECTORY, /* 240 */ EXIT_CONFIGURATION_DIRECTORY, + + EXIT_EXCEPTION = 255, /* Whenever we want to propagate an abnormal/signal exit, in line with bash */ }; typedef enum ExitStatusLevel { From f2fb2ec942f54c7edd545b3641949c443d83c70d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 20 Nov 2018 16:58:42 +0100 Subject: [PATCH 2/4] nspawn: use EXIT_EXCEPTION where appropriate --- src/nspawn/nspawn-stub-pid1.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c index c83d55cb86..5d17df39d9 100644 --- a/src/nspawn/nspawn-stub-pid1.c +++ b/src/nspawn/nspawn-stub-pid1.c @@ -5,6 +5,8 @@ #include #include +#include "def.h" +#include "exit-status.h" #include "fd-util.h" #include "log.h" #include "missing.h" @@ -12,7 +14,6 @@ #include "process-util.h" #include "signal-util.h" #include "time-util.h" -#include "def.h" static int reset_environ(const char *new_environment, size_t length) { unsigned long start, end; @@ -122,7 +123,7 @@ int stub_pid1(sd_id128_t uuid) { if (si.si_pid == pid && si.si_code == CLD_EXITED) r = si.si_status; /* pass on exit code */ else - r = 255; /* signal, coredump, timeout, … */ + r = EXIT_EXCEPTION; /* signal, coredump, timeout, … */ goto finish; } From bb85a58208a8b83178e826e5dab1f2c31aaa6b7e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 20 Nov 2018 17:03:35 +0100 Subject: [PATCH 3/4] main: use EXIT_EXCEPTION instead of EXIT_FAILURE at two more exceptional places --- src/core/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 70227da4b7..5272df3e3f 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -185,7 +185,7 @@ _noreturn_ static void crash(int sig) { (void) kill(pid, sig); /* raise() would kill the parent */ assert_not_reached("We shouldn't be here..."); - _exit(EXIT_FAILURE); + _exit(EXIT_EXCEPTION); } else { siginfo_t status; int r; @@ -231,7 +231,7 @@ _noreturn_ static void crash(int sig) { (void) execle("/bin/sh", "/bin/sh", NULL, environ); log_emergency_errno(errno, "execle() failed: %m"); - _exit(EXIT_FAILURE); + _exit(EXIT_EXCEPTION); } else { log_info("Spawned crash shell as PID "PID_FMT".", pid); (void) wait_for_terminate(pid, NULL); From bb25977244aedd73016778c75d4a7ad7d26c7009 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 20 Nov 2018 13:16:48 +0100 Subject: [PATCH 4/4] main: don't freeze PID 1 in containers, exit with non-zero instead After all we have a nice way to propagate total failures, hence let's use it. --- src/core/main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 5272df3e3f..9469512d4e 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -130,7 +130,14 @@ static uint64_t arg_default_tasks_max = UINT64_MAX; static sd_id128_t arg_machine_id = {}; static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE; -_noreturn_ static void freeze_or_reboot(void) { +_noreturn_ static void freeze_or_exit_or_reboot(void) { + + /* If we are running in a contianer, let's prefer exiting, after all we can propagate an exit code to the + * container manager, and thus inform it that something went wrong. */ + if (detect_container() > 0) { + log_emergency("Exiting PID 1..."); + exit(EXIT_EXCEPTION); + } if (arg_crash_reboot) { log_notice("Rebooting in 10s..."); @@ -238,7 +245,7 @@ _noreturn_ static void crash(int sig) { } } - freeze_or_reboot(); + freeze_or_exit_or_reboot(); } static void install_crash_handler(void) { @@ -2622,8 +2629,8 @@ finish: if (error_message) manager_status_printf(NULL, STATUS_TYPE_EMERGENCY, ANSI_HIGHLIGHT_RED "!!!!!!" ANSI_NORMAL, - "%s, freezing.", error_message); - freeze_or_reboot(); + "%s.", error_message); + freeze_or_exit_or_reboot(); } return retval;