With both sysvinit
and systemd, shutting the operating system down starts by notifying the init
process (the process with pid 1) that the system should shut down (or reboot, or power off).
sysvinit
does this by using the /run/initctl
FIFO to communicate with init
, asking it to switch to the corresponding runlevel. See the init
manpage for a brief overview.
systemd supports a variety of ways to do this. Various signals can be used to request a shutdown, reboot, etc., in various flavours; it’s also possible to request this over d-bus (the busctl
manpage explains how to explore that).
Once pid 1 has been asked to shut down, it follows its configuration and specification and goes through all the appropriate steps for it. This typically includes notifying all users that a shutdown is in progress, shutting down all the running services (in a managed way with systemd; using shutdown scripts in various forms with sysvinit
), syncing the mounted file systems, possibly unmounting them, killing all remaining processes (with the usual TERM
then KILL
sequence), and finally calling the kernel’s reboot
system call with the appropriate parameters.
This describes the general sequence. There are many more twists to all this, including access control (with Polkit), various available hooks, kexec
, sudden power-off handling, CtrlAltDel handling... The systemd documentation covers many of these details.