A little over a week ago I decided it would be fun to try to write my own multi-threaded init system in c. Without going into too much detail (I’ll write a blog post that introduces it once it’s further along), I needed to find a way to shutdown and restart my system from c (init 0 and 6, respectively).
I looked around the internet and had a surprisingly difficult time finding what I was looking for. Every post I found indicated I should use the system function to call "shutdown -h -P now". While not a wrong or a bad answer, it wasn’t the answer I was looking for. I wanted to know how the shutdown and reboot commands worked, or how my current init system executed runlevels 0 and 6, respectively.
Remembering something I found a ways back about kernel triggers found in and /sys/power/ for controlling acpi states, I started searching for something similar. After a bit of time, I found /proc/sysrq-trigger. For further reading beyond this post, please see the Wikipedia Article.
The usage of sysrq-trigger is fairly simple. Before we get into exact usage for the purposes of shutting down or rebooting though, please note that output from /proc/sysrq-trigger can only be seen from an actual tty, and not from within a terminal emulator.
That said, execute the following command to find out all of the options available to you from sysrq.
# echo h > /proc/sysrq-trigger
If you don’t see output from that, either sysrq isn’t enabled, or you aren’t executing from within a tty.
To check if it is enabled, ensure that the following command yields a 1.
# cat /proc/sys/kernel/sysrq
Reboot and Shutdown Sequences
If you executed the echo h statement above, you likely saw the output of supported commands. Among them you should havE seen b and o, for reboot and poweroff, respectively. Note that it is a bad idea to execute either of these right now.
If you read around the internet for what these two do, you’ll see that both cause a hard stop. Neither polietly asks processes to exit. They are roughly equivelant to the hardware reset and power buttons. If rebooting or powering off, we want b or o to be the last command sent to have as graceful a stop as possible.
Here is the list of commands that should be sent to sysrq-trigger, in order, for both a shutdown and a reboot.
echo r > /proc/sysrq-trigger
(unRaw) Takes back control of keyboard from X
echo e > /proc/sysrq-trigger
(tErminate) Send SIGTERM to all processes. If you aren’t familiar with process signals, this is basically a friendly kill command for every process.
echo i > /proc/sysrq-trigger
(kIll) Send SIGKILL to all processes. If you aren’t familiar with process signals, this is basically a kill -9 command for every remaining process.
echo s > /proc/sysrq-trigger
(Snc) Sync all cached disk operations to disk
echo u > /proc/sysrq-trigger
(Umount) Umounts all mounted partitions
The previous commands all get us to a ready to shutdown or reboot state. To shutdown or reboot, execute one of the following.
echo o > /proc/sysrq-trigger
(pOweroff) Powers off the system
echo b > /proc/sysrq-trigger
(reBoot) Reboots the system
The entire list in order, using the reboot command…
# echo r > /proc/sysrq-trigger # echo e > /proc/sysrq-trigger # echo i > /proc/sysrq-trigger # echo s > /proc/sysrq-trigger # echo u > /proc/sysrq-trigger # echo b > /proc/sysrq-trigger