Skip to content

Commit 2ecc6da

Browse files
committed
readme: create Ctrl-Alt-Del and improve SysRq
1 parent 9cec69d commit 2ecc6da

File tree

3 files changed

+148
-3
lines changed

3 files changed

+148
-3
lines changed

README.adoc

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,24 +3242,144 @@ sendkey shift-pgup
32423242
sendkey shift-pgdown
32433243
....
32443244

3245-
https://en.wikipedia.org/wiki/Magic_SysRq_key Those can be tested through the monitor with:
3245+
===== Ctrl Alt Del
3246+
3247+
Reboot guest:
3248+
3249+
....
3250+
Ctrl-Alt-Del
3251+
....
3252+
3253+
Enabled from our link:rootfs_overlay/etc/inittab[]:
3254+
3255+
....
3256+
::ctrlaltdel:/sbin/reboot
3257+
....
3258+
3259+
Under the hood, behaviour is controlled by the `reboot` syscall:
3260+
3261+
....
3262+
man 2 reboot
3263+
....
3264+
3265+
`reboot` calls can set either of the these behaviours for `Ctrl-Alt-Del`:
3266+
3267+
* do a hard shutdown syscall. Set in ublibc C code with:
3268+
+
3269+
....
3270+
reboot(RB_ENABLE_CAD)
3271+
....
3272+
+
3273+
or from procfs with:
3274+
+
3275+
....
3276+
echo 1 > /proc/sys/kernel/ctrl-alt-del
3277+
....
3278+
* send a SIGINT to the init process. This is what BusyBox' init does, and it then execs the string set in `inittab`.
3279+
+
3280+
Set in uclibc C code with:
3281+
+
3282+
....
3283+
reboot(RB_DISABLE_CAD)
3284+
....
3285+
+
3286+
or from procfs with:
3287+
+
3288+
....
3289+
echo 0 > /proc/sys/kernel/ctrl-alt-del
3290+
....
3291+
3292+
Minimal example:
3293+
3294+
....
3295+
./run -e 'init=/ctrl_alt_del.out' -x
3296+
....
3297+
3298+
When you hit `Ctrl-Alt-Del` in the guest, our tiny init handles a `SIGINT` sent by the kernel and outputs to stdout:
3299+
3300+
....
3301+
cad
3302+
....
3303+
3304+
To map between `man 2 reboot` and the uclibc `RB_*` magic constants see:
3305+
3306+
....
3307+
less out/x86_64/buildroot/build/uclibc-*/include/sys/reboot.h
3308+
....
3309+
3310+
The procfs mechanism is documented at:
3311+
3312+
....
3313+
less linux/Documentation/sysctl/kernel.txt
3314+
....
3315+
3316+
which says:
3317+
3318+
....
3319+
When the value in this file is 0, ctrl-alt-del is trapped and
3320+
sent to the init(1) program to handle a graceful restart.
3321+
When, however, the value is > 0, Linux's reaction to a Vulcan
3322+
Nerve Pinch (tm) will be an immediate reboot, without even
3323+
syncing its dirty buffers.
3324+
3325+
Note: when a program (like dosemu) has the keyboard in 'raw'
3326+
mode, the ctrl-alt-del is intercepted by the program before it
3327+
ever reaches the kernel tty layer, and it's up to the program
3328+
to decide what to do with it.
3329+
....
3330+
3331+
===== SysRq
3332+
3333+
https://en.wikipedia.org/wiki/Magic_SysRq_key
3334+
3335+
We cannot test these actual shortcuts on QEMU since the host captures them at a lower level, but from:
3336+
3337+
....
3338+
./qemumonitor
3339+
....
3340+
3341+
we can for example crash the system with:
32463342

32473343
....
32483344
sendkey alt-sysrq-c
32493345
....
32503346

3251-
or you can try the much more boring method of:
3347+
Same but boring because no magic key:
32523348

32533349
....
32543350
echo c > /proc/sysrq-trigger
32553351
....
32563352

3257-
Implemented in
3353+
Implemented in:
32583354

32593355
....
32603356
drivers/tty/sysrq.c
32613357
....
32623358

3359+
On your host, on modern systems that don't have the `SysRq` key you can do:
3360+
3361+
....
3362+
Alt-PrtSc-space
3363+
....
3364+
3365+
which prints a message to `dmesg` of type:
3366+
3367+
....
3368+
sysrq: SysRq : HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) show-blocked-tasks(w) dump-ftrace-buffer(z)
3369+
....
3370+
3371+
Individual SysRq can be enabled or disabled with the bitmask:
3372+
3373+
....
3374+
/proc/sys/kernel/sysrq
3375+
....
3376+
3377+
The bitmask is documented at:
3378+
3379+
....
3380+
less linux/Documentation/admin-guide/sysrq.rst
3381+
....
3382+
32633383
===== Multiple TTYs
32643384

32653385
Switch between TTYs with:

kernel_module/user/ctrl_alt_del.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#define _XOPEN_SOURCE 700
2+
#include <signal.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <sys/reboot.h>
6+
#include <unistd.h>
7+
8+
void signal_handler(int sig) {
9+
write(STDOUT_FILENO, "cad\n", 4);
10+
signal(sig, signal_handler);
11+
}
12+
13+
int main(void) {
14+
int i = 0;
15+
/* Disable the forced reboot, enable sending SIGINT to init. */
16+
reboot(RB_DISABLE_CAD);
17+
signal(SIGINT, signal_handler);
18+
while (1) {
19+
sleep(1);
20+
printf("%d\n", i);
21+
i++;
22+
}
23+
return EXIT_SUCCESS;
24+
}

kernel_module/user/poweroff.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* https://stackoverflow.com/questions/28812514/how-to-shutdown-linux-using-c-or-qt-without-call-to-system
33
**/
44

5+
#define _XOPEN_SOURCE 700
56
#include <stdio.h>
67
#include <sys/reboot.h>
78
#include <unistd.h>

0 commit comments

Comments
 (0)