8

Under Linux, if I issue a reboot command from the shell, what is the sequence of events that lead to the shell (e.g. bash) disconnecting?

I think it's one of the following, but not sure which:

  1. It log me out of the shell before it sends a reboot signal.
  2. It send the signal to reboot and the shell logs me out.
  3. It send the signal to reboot and the shell just terminates abruptly without going through a logout procedure.
5
  • 5
    Reboot causes the init daemon to send SIGTERM to all processes.
    – jordanm
    Commented Mar 31, 2021 at 16:21
  • Is there some particular way it matters which one it is?
    – ilkkachu
    Commented Mar 31, 2021 at 16:56
  • 1
    @jordanm I don't see any duplicates yet; would you consider posting an Answer?
    – Jeff Schaller
    Commented Mar 31, 2021 at 16:58
  • 3
    Actually final behaviour with systemd is probably different than with sys-v init (observable difference: interactive shell history not lost or lost). OP should specify what is the init process.
    – A.B
    Commented Mar 31, 2021 at 17:11
  • 1
    As noted, the normal behavior is that the init process sends SIGERM to all processes. How your shell responds to this is dependent on the shell. Will it do a "log out" on you, or simply terminate and dump your "connection" ungracefully to the bit bucket? IF you really want to ensure certain behavior... Do what you want to be done before issuing the reboot command. Or log out of your current session and start a new shell/console expressly for the purpose of issuing he reboot command.
    – C. M.
    Commented Apr 26, 2021 at 13:48

2 Answers 2

3

This is behaviour that will probably have variations based on distro/shell/configuration. On my system (Gentoo/SysVinit) this is what happens when I run reboot (probably your scenario 3):

The reboot command delegates to shutdown (from man reboot):

If halt or reboot is called when the system is not in runlevel 0 or 6, in other words when it's running normally, shutdown will be invoked instead (with the -h or -r flag). For more info see the shutdown(8) manpage.

All processes (including the shell) get sent a SIGTERM, allowing 3 seconds for cleanup (from man shutdown):

All processes are first notified that the system is going down by the signal SIGTERM. This gives programs like vi(1) the time to save the file being edited, mail and news processing programs a chance to exit cleanly, etc.

-t sec Tell init(8) to wait sec seconds between sending all processes the warning (SIGTERM) and the kill signal (SIGKILL), before changing to another run‐level. The default time, if no value is specified, between these two signals is three seconds. Warning: when shutdown calls init to perform the shutdown (the default behaviour), init checks to see if all processes have terminated and will stop waiting early once its children have all termi‐ nated. When shutdown is called with the -n flag, it waits the full time specified (or three seconds) even if all other processes have terminated.

Bash actually ignores the SIGTERM (from man bash):

When bash is interactive, in the absence of any traps, it ignores SIGTERM (so that kill 0 does not kill an interactive shell)

So init changes the runlevel, (possibly) sending another SIGTERM and then SIGKILL (from man init):

When init is requested to change the runlevel, it sends the warning signal SIGTERM to all processes that are undefined in the new runlevel. It then waits 3 seconds before forcibly terminating these processes via the SIGKILL signal.

TLDR; bash will exit without a graceful shutdown, other programs may, but I wouldn't rely on any particular behaviour.

1

As others already pointed out, this depends deeply on your answer to complex philosophical question what is "Linux" :).

Yes in this case, as in many others, the "GNU/Linux" meme suddenly becomes very important and relevant.

So now let us first look at actual "kernel truth", that is, how the mechanism works for real.

As far as normal kernel is concerned, as long as PID1 is running, everything is fine and dandy. But should PID1 crash, no matter how hardware/software healthy the machine is, this will cause immediate kernel panic, which is equivalent to killing all processes with SIGKILL or has roughly same effect as immediate power loss.

If I remember correctly, most stock Linuces will end up stuck here by default, with PANIC message printed on console waiting with halted CPUs until operator comes and hard resets/shutdowns the machine physically (or virtually, if VM). Some BDS will by default wait 15 seconds in this state and then reboot themselves.

So this is one part of the thing.

The other part is special Linux kernel syscall called reboot(). This syscall is accessible only to root user processes, and allows you to control kernel behaviour: it can kexec from current kernel into next kernel in chain, reboot/reset the machine physically, poweroff the machine physically, halt the machine physically and finally suspend (hibernate) the machine.

Besides hibernate (I am not sure about that one) any of the actions mentioned above is equivalent to kernel panic action in the first case (i.e. all running processes are killed immediately as if by powerloss), the only difference is that kexec will immediately handover control to next kernel in chain, while reboot, poweroff and halt will either reboot all the cpus, shutdown power to the whole computer or halt all cpus in it, without causing a panic :).

Halt state is basically all-software-is-off state, equivalent to how you used to turn off old computers ("You can now safely shutdown the computer") before motherboards grew circuits to power off themselves off autonomously.

The important part to realize is that PID1/init must be running when reboot() is initiated.

Now you understand that these two controls are really quite bare bone. You also now understand, that everything that happens in-between some user command to shutdown and reboot() syscall is completely distribution dependent.

How this sequence is handled usually depends on init package the distribution is using. On majority of modern distributions this is handled by systemd, it's PID1 receives control commands from reboot, poweroff and shutdown commands (these should be really named systemd-reboot, systemd-poweroff and systemd-shutdown, because they don't work with other inits) and do respective actions.

You can dig somewhere on systemd author's site how shutdown protocol is implemented there, as I remember reading that (take it with grain of salt as, systemd is everchanging and most of deep information about it is from timeframe circa 2012~15 and really outdated).

Now we are getting into more exotic realms.

@rhellen gave you somewhat simplified explanantion of crappy sysv init poweroff dance.

runit based distributions have completely different mechanism, and so do nosh and s6 based systems.

So the real answer is it depends on your distribution a lot.

On some ancient sysv based Linux systems for example reboot and poweroff commands are equivalent to their raw syscall counterparts (and I think on BSDs too), so neophyte admin, at least a typical systemd user, has great ability to kill the whole box "the power outage way" :). Similar to killall story on Solaris.

Fortunately shutdown always works the same way on almost all platforms, so when in doubt, always use that one.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .