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.
This commit is contained in:
Lennart Poettering 2024-04-22 17:32:12 +02:00
parent 41fb4dc334
commit 8c081ae84b
2 changed files with 35 additions and 0 deletions

View file

@ -1257,6 +1257,19 @@
details.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
<listitem><para>An <varname>X_SYSTEMD_SHUTDOWN=…</varname> message will be sent out very shortly before
the system shuts down. The value is one of the strings <literal>reboot</literal>,
<literal>halt</literal>, <literal>poweroff</literal>, <literal>kexec</literal> and indicates which kind
of shutdown is being executed.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
<listitem><para>An <varname>X_SYSTEMD_REBOOT_PARAMETER=…</varname> message will also be sent out very
shortly before the system shuts down. Its value is the reboot argument as configured with
<command>systemctl --reboot-argument=…</command>.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
</itemizedlist>
<para>Note that these extension fields are sent in addition to the regular <literal>READY=1</literal> and

View file

@ -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.");