diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 4484e87831..213f434fe7 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -1847,6 +1847,35 @@ After=sys-subsystem-net-devices-ens1.device
+
+ Hotkeys
+
+ When invoked in interactive mode (i.e. the default ), 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.
+
+
+
+ Ctrl-] Ctrl-] Ctrl-]
+ Immediately terminate the container, killing all processes.
+
+
+
+ Ctrl-] Ctrl-] r
+ Issue a reboot request to the container.
+
+
+
+
+ Ctrl-] Ctrl-] p
+ Issue a shutdown request to the container.
+
+
+
+
+
+
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 1737d1ef0a..952516bc78 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -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());
}
diff --git a/tools/command_ignorelist b/tools/command_ignorelist
index aca6b8c93b..65602aab8a 100644
--- a/tools/command_ignorelist
+++ b/tools/command_ignorelist
@@ -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-]"]