Boot Targets vs Runlevels
SysV init used numbered runlevels (0-6) to define what state the system is in. systemd replaces these with named targets that are more descriptive and flexible. Both solve the same problem: defining which services run at any given system state.
SysV Runlevels
| Runlevel | Meaning |
|---|---|
| 0 | Halt — shutdown the system |
| 1 | Single-user mode — root only, no networking, for recovery |
| 2 | Multi-user without networking (Debian) |
| 3 | Multi-user with networking, text mode (standard server) |
| 4 | Unused (user-defined) |
| 5 | Multi-user with networking + graphical desktop |
| 6 | Reboot |
systemd Targets
| systemd Target | SysV Equivalent | What it does |
|---|---|---|
| poweroff.target | Runlevel 0 | Shutdown |
| rescue.target | Runlevel 1 | Single-user rescue shell (root password required) |
| multi-user.target | Runlevel 3 | Multi-user text mode (standard servers) |
| graphical.target | Runlevel 5 | Multi-user + graphical desktop |
| reboot.target | Runlevel 6 | Reboot |
| emergency.target | N/A | Minimal shell — even more stripped than rescue |
Changing Targets
# Check current default target
systemctl get-default
# Change default target
sudo systemctl set-default multi-user.target # boot to text mode
sudo systemctl set-default graphical.target # boot to desktop
# Switch target right now (without rebooting)
sudo systemctl isolate multi-user.target
Rescue Mode and Emergency Mode
What's the difference between rescue.target and emergency.target? rescue.target: mounts all filesystems, starts basic services, gives you a root shell. More functional, good for most recovery tasks.
emergency.target: mounts only the root filesystem (read-only), starts almost nothing. For situations where rescue mode itself won't boot.
emergency.target: mounts only the root filesystem (read-only), starts almost nothing. For situations where rescue mode itself won't boot.
# Boot into rescue mode (two methods):
# Method 1: Append to GRUB kernel line (press 'e' at GRUB menu)
linux /boot/vmlinuz-... root=UUID=... ro systemd.unit=rescue.target
# Method 2: After booting
sudo systemctl rescue
# Emergency mode (even more minimal)
sudo systemctl emergency
# After fixing issues in rescue mode, continue normal boot:
sudo systemctl default # switch to default.target
How Targets Pull in Services
How does systemd know which services belong to multi-user.target?
Through symlinks in
/etc/systemd/system/multi-user.target.wants/. When you run systemctl enable nginx, it creates a symlink there. At boot, systemd reads the .wants/ directory and starts everything linked from it.
ls /etc/systemd/system/multi-user.target.wants/
# nginx.service -> /lib/systemd/system/nginx.service
# ssh.service -> /lib/systemd/system/ssh.service
# ...