101.3 Change runlevels / boot targets and shutdown or reboot system¶
runlevels¶
Runlevels define what tasks can be accomplished in the current state of a Linux system - predefined system states, each with its own set of active services.
systemd¶
On systemd, runlevels are replaced by targets - groups of units managed together.
There are targets that correspond directly to each SysV runlevel, from runlevel0.target up to runlevel6.target. Two of the most common named targets are multi-user.target (console only) and graphical.target (console plus graphical login).
systemctl get-default # shows the default target
systemctl status multi-user.target # shows the status of a specific target
You can switch to a different target immediately with isolate:
Besides the regular targets, there are special maintenance/power targets:
rescue- local filesystems mounted, no networking, root only (maintenance mode)emergency- only the root filesystem, read-only, no networking, root only (maintenance mode)reboot,halt,poweroff- restart/shutdown variants
SysV runlevels¶
On a Red Hat-based system we usually had 7:
- 0 - Shutdown
- 1 - Single-user mode (recovery); also called S or s
- 2 - Multi-user without networking
- 3 - Multi-user with networking
- 4 - To be customized by the admin
- 5 - Multi-user with networking and graphics
- 6 - Reboot
And in Debian-based systems:
- 0 - Shutdown
- 1 - Single-user mode
- 2 - Multi-user mode with graphics
- 6 - Reboot
Checking status and setting defaults¶
The runlevel command shows the current runlevel as two values, the previous one and the current one:
N means the runlevel hasn't changed since the last boot.
The default runlevel is set in /etc/inittab, using the special initdefault action:
This value should never be 0 or 6, since either would shut down or restart the system immediately after boot finishes. The default can also be overridden with a kernel parameter at boot.
To switch runlevels on a running system without rebooting, use telinit:
All SysVinit scripts live in /etc/init.d/, and each runlevel has its own directory (/etc/rc0.d/, /etc/rc1.d/, etc.) full of symlinks back to those scripts. The first letter of each symlink's name tells init what to do: K kills the service on entering that runlevel, S starts it.
On systemd systems, the equivalent configuration lives in /etc/systemd/ and /usr/lib/systemd/, as covered in 101.2.
/etc/inittab¶
Still part of the exam, even though it's being phased out by Upstart and systemd. The format is:
id- up to 4 characters, identifies the entryrunlevels- which runlevel(s) this line applies to (empty means all)action- how init should treat the processprocess- the command to run
The available actions: boot and bootwait (run during initialization, the runlevels field is ignored), sysinit (runs after initialization regardless of runlevel), wait (runs for the given runlevels, init waits for it to finish), respawn (restarted if it terminates), and ctrlaltdel (runs when Ctrl+Alt+Del is pressed).
A typical /etc/inittab:
# Default runlevel
id:3:initdefault:
# Configuration script executed during boot
si::sysinit:/etc/init.d/rcS
# Action taken on runlevel S (single user)
~:S:wait:/sbin/sulogin
# Configuration for each execution level
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Action taken upon ctrl+alt+del keystroke
ca::ctrlaltdel:/sbin/shutdown -r now
# Enable consoles for runlevels 2 and 3
1:23:respawn:/sbin/getty tty1 VC linux
2:23:respawn:/sbin/getty tty2 VC linux
After editing /etc/inittab, run telinit q to make init reload it, without needing a reboot.
Stopping the system¶
The shutdown command is the safe way to shut down or restart a system, rather than just cutting the power. It happens in order: first it warns everyone currently logged in, then it blocks anyone new from logging in, then it tells init to switch to the shutdown or reboot runlevel. As part of that, every process is asked to stop on its own first, using signal SIGTERM (signal number 15). Any process still running a moment later is forced to stop with SIGKILL (signal number 9), which cannot be ignored.
time-hh:mm,+m(minutes from now), ornowmessage- text broadcast to logged-in users, sent viawall-h- halt the system-r- reboot the system-c- cancel a pending shutdown
If neither -h nor -r is given, the system goes to runlevel 1 (single-user mode) by default.
Root can restrict who's allowed to reboot via Ctrl+Alt+Del by adding the -a option to the ctrlaltdel line in /etc/inittab. Once set, only users listed in /etc/shutdown.allow are permitted to use that key combination.
Halt, reboot, and poweroff¶
halt- halts the systemreboot- halts the system, then reboots itpoweroff- halts the system, then powers it off (sends an ACPI shutdown signal)
On most distros these are symbolic links to systemctl itself:
$ which poweroff
/usr/sbin/poweroff
$ ls -l /usr/sbin/poweroff
lrwxrwxrwx 1 root root 14 ... /usr/sbin/poweroff -> /bin/systemctl
The systemd-native equivalents are systemctl reboot and systemctl poweroff, both requiring root privileges.
Advanced Configuration and Power Interface (ACPI)¶
ACPI is an open standard that lets the OS discover and configure hardware, perform power management (like putting unused components to sleep), handle auto-configuration such as Plug and Play and hot-swapping, and perform status monitoring. It's the subsystem that lets a command like shutdown actually signal the hardware to power itself down.
On a systemd system, events like suspend and hibernate are normally handled by systemctl suspend and systemctl hibernate, configured through /etc/systemd/logind.conf. If a separate power manager such as the acpid daemon is running instead, it takes over that role, handling finer-grained events like the laptop lid closing or the battery reaching a certain charge level.
Notifying users¶
The wall command sends a message to every logged-in user's terminal:
Other places users see notifications, before and after logging in:
/etc/issue- shown on the local console, before login/etc/issue.net- shown over the network, before login/etc/motd- message of the day, shown after loginmesg- controls whether a user receiveswallmessages (shutdown's own warning messages ignore this setting regardless)
systemctl itself sends wall messages automatically for emergency, halt, power-off, reboot, and rescue events.
Summary¶
I have a Linux system that needs predefined states for different situations, like normal operation versus maintenance. On older SysV based systems, these states are called runlevels, numbered 0 through 6, with the default one set in /etc/inittab using an initdefault line. On systemd systems, the same idea exists as targets, like multi-user.target for a normal console system or graphical.target for a desktop.
I can check my current runlevel with runlevel, switch between them live with telinit, or use systemctl isolate and systemctl get-default for the systemd equivalent. Every runlevel has an /etc/rc[0-6].d/ directory full of S-prefixed (start) and K-prefixed (kill) symlinks pointing back to the real scripts in /etc/init.d/.
When I actually need to shut the system down, shutdown is the safe way to do it. It warns everyone logged in, blocks new logins, and gives running processes a chance to close cleanly with SIGTERM before force-killing anything left with SIGKILL. halt, reboot, and poweroff are the more direct commands, and on most modern systems they're just symlinks to systemctl under the hood.
Finally, I have wall for warning everyone on the system before I do any of this, which is exactly what shutdown uses internally to send its own warnings.