From 8c081ae84b5a98df1a18c542a34431c99f59e3ed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 17:32:12 +0200 Subject: shutdown: send an sd_notify() message on shutdown with the shutdown reason and boot param This is kinda nice in containers, to exfiltrate a string from the container on shutdown. --- man/systemd.xml | 13 +++++++++++++ src/shutdown/shutdown.c | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/man/systemd.xml b/man/systemd.xml index abfcc499f08..df0027886c3 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -1257,6 +1257,19 @@ details. + + An X_SYSTEMD_SHUTDOWN=… message will be sent out very shortly before + the system shuts down. The value is one of the strings reboot, + halt, poweroff, kexec and indicates which kind + of shutdown is being executed. + + + + An X_SYSTEMD_REBOOT_PARAMETER=… message will also be sent out very + shortly before the system shuts down. Its value is the reboot argument as configured with + systemctl --reboot-argument=…. + + Note that these extension fields are sent in addition to the regular READY=1 and diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index b709078afed..1ddda009410 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -333,6 +333,26 @@ static void init_watchdog(void) { } } +static void notify_supervisor(void) { + /* Notify VMM/container manager of the desired mode of reboot and the boot parameter */ + _cleanup_free_ char *reboot_parameter = NULL; + int r; + + r = read_reboot_parameter(&reboot_parameter); + if (r < 0 && r != -ENOENT) + log_debug_errno(r, "Failed to read reboot parameter, ignoring: %m"); + + if (reboot_parameter) + (void) sd_notifyf(/* unset_environment= */ false, + "X_SYSTEMD_SHUTDOWN=%s\n" + "X_SYSTEMD_REBOOT_PARAMETER=%s", + arg_verb, reboot_parameter); + else + (void) sd_notifyf(/* unset_environment= */ false, + "X_SYSTEMD_SHUTDOWN=%s", + arg_verb); +} + int main(int argc, char *argv[]) { static const char* const dirs[] = { SYSTEM_SHUTDOWN_PATH, @@ -589,6 +609,8 @@ int main(int argc, char *argv[]) { if (!in_container) sync_with_progress(); + notify_supervisor(); + if (streq(arg_verb, "exit")) { if (in_container) { log_info("Exiting container."); -- cgit v1.2.3-59-g8ed1b From c65bd6cc7eb000fa3a40ebb33718752ac259629c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Apr 2024 10:14:41 +0200 Subject: systemctl: set reboot argument for most forms of shutdown, not just plain reboots This doesn't hurt anyway, and is useful now that we propagate the string via sd_notify() too. --- src/systemctl/systemctl-start-special.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/systemctl/systemctl-start-special.c b/src/systemctl/systemctl-start-special.c index d486b406da5..4b99d0c6294 100644 --- a/src/systemctl/systemctl-start-special.c +++ b/src/systemctl/systemctl-start-special.c @@ -155,14 +155,16 @@ int verb_start_special(int argc, char *argv[], void *userdata) { return r; } - if (a == ACTION_REBOOT) { - if (arg_reboot_argument) { - r = update_reboot_parameter_and_warn(arg_reboot_argument, false); - if (r < 0) - return r; - } + if (arg_reboot_argument && IN_SET(a, ACTION_HALT, ACTION_POWEROFF, ACTION_REBOOT, ACTION_KEXEC)) { + /* If we are going through an action that involves systemd-shutdown, let's set the reboot + * parameter, even if it's not a regular reboot. After all we nowadays send the string to + * our supervisor via sd_notify() too. */ + r = update_reboot_parameter_and_warn(arg_reboot_argument, /* keep= */ false); + if (r < 0) + return r; + } - } else if (a == ACTION_KEXEC) { + if (a == ACTION_KEXEC) { r = load_kexec_kernel(); if (r < 0 && arg_force >= 1) log_notice("Failed to load kexec kernel, continuing without."); -- cgit v1.2.3-59-g8ed1b From d58997e684d4630cf4966157729707fc1e34e59d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Apr 2024 10:14:24 +0200 Subject: update TODO --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 8c52f65b550..163f66f1527 100644 --- a/TODO +++ b/TODO @@ -130,6 +130,9 @@ Deprecations and removals: Features: +* Clean up "reboot argument" handling, i.e. set it through some IPC service + instead of directly via /run/, so that it can be sensible set remotely. + * userdb: add concept for user "aliases", to cover for cases where you can log in under the name lennart@somenetworkfsserver, and it would automatically generate a local user, and from the one both names can be used to allow -- cgit v1.2.3-59-g8ed1b