nspawn: add ability to poweroff container cleanly with ^]^]p

It's sometimes very useful to be able to terminate a container quickly
but cleanly while talking to it. Introduce a hotkey for that: ^]^]p for
powering it off. In similar style add ^]^]r for rebooting it.
This commit is contained in:
Lennart Poettering
2025-03-02 21:43:12 +01:00
parent b1f9d0e46b
commit f0f5d54202
3 changed files with 66 additions and 1 deletions

View File

@@ -1847,6 +1847,35 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
</refsect2>
</refsect1>
<refsect1>
<title>Hotkeys</title>
<para>When invoked in interactive mode (i.e. the default <option>--console=interactive</option>), a few
special keyboard shortcuts are understood that control the container runtime. These shortcuts need to be
typed within 1s to have effect, otherwise they will be forwarded to the container as regular
keypresses.</para>
<variablelist>
<varlistentry>
<term>Ctrl-] Ctrl-] Ctrl-]</term>
<listitem><para>Immediately terminate the container, killing all processes.</para></listitem>
</varlistentry>
<varlistentry>
<term>Ctrl-] Ctrl-] r</term>
<listitem><para>Issue a reboot request to the container.</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
<varlistentry>
<term>Ctrl-] Ctrl-] p</term>
<listitem><para>Issue a shutdown request to the container.</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
</variablelist>
</refsect1>
<xi:include href="common-variables.xml" />
<refsect1>

View File

@@ -4692,6 +4692,37 @@ static void set_window_title(PTYForward *f) {
(void) pty_forward_set_title_prefix(f, dot);
}
static int ptyfwd_hotkey(PTYForward *f, char c, void *userdata) {
pid_t pid = PTR_TO_PID(userdata);
const char *word;
int sig = 0;
assert(f);
switch (c) {
case 'p':
sig = SIGRTMIN+4;
word = "power off";
break;
case 'r':
sig = SIGRTMIN+5;
word = "reboot";
break;
default:
log_info("Unknown hotkey sequence ^]^]%c, ignoring.", c);
return 0;
}
if (kill(pid, sig) < 0)
log_error_errno(errno, "Failed to send %s (%s request) to PID 1 of container: %m", signal_to_string(sig), word);
else
log_info("Sent %s (%s request) to PID 1 of container.", signal_to_string(sig), word);
return 0;
}
static int merge_settings(Settings *settings, const char *path) {
int rl;
@@ -5687,6 +5718,8 @@ static int run_container(
(void) pty_forward_set_background_color(forward, arg_background);
set_window_title(forward);
pty_forward_set_hotkey_handler(forward, ptyfwd_hotkey, PID_TO_PTR(*pid));
break;
default:
@@ -6364,7 +6397,9 @@ static int run(int argc, char *argv[]) {
special_glyph(SPECIAL_GLYPH_LIGHT_SHADE), ansi_grey(), arg_machine, u ?: t, ansi_normal());
if (arg_console_mode == CONSOLE_INTERACTIVE)
log_info("%s %sPress %sCtrl-]%s three times within 1s to kill container.%s",
log_info("%s %sPress %sCtrl-]%s three times within 1s to kill container; two times followed by %sr%s\n"
"%s %sto reboot container; two times followed by %sp%s to poweroff container.%s",
special_glyph(SPECIAL_GLYPH_LIGHT_SHADE), ansi_grey(), ansi_highlight(), ansi_grey(), ansi_highlight(), ansi_normal(),
special_glyph(SPECIAL_GLYPH_LIGHT_SHADE), ansi_grey(), ansi_highlight(), ansi_grey(), ansi_normal());
}

View File

@@ -576,3 +576,4 @@ file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[t
file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/share/"]
file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/state/"]
systemd-measure.xml /refsect1[title="Options"]/variablelist/varlistentry[term="--linux=PATH"]
systemd-nspawn.xml /refsect1[title="Hotkeys"]/variablelist/varlistentry[term="Ctrl-] Ctrl-] Ctrl-]"]