Targets — systemd's Answer to Runlevels
systemd in Depth
Chapter 5 · Targets — systemd's Answer to Runlevels
systemd1-4 defined a target as a synchronization point without going further. This chapter goes further — and resolves grub1-4's own unexplained systemd.unit=rescue.target kernel parameter along the way.
What a Target Actually Is, Formally
systemd1-4 established that a target doesn't "do" anything itself. Formally: a target unit is a named grouping of other units — often implemented as essentially an empty unit that other units Want=/Require=/order themselves relative to. "Reaching a target" means every unit that target itself requires or wants, directly or transitively, has actually been started.
The Common Targets, Mapped to Legacy Runlevels
| systemd target | Legacy runlevel | Meaning |
|---|---|---|
| poweroff.target | 0 | Shut down |
| rescue.target | 1 | Single-user/minimal recovery mode |
| multi-user.target | 3 | Full multi-user, no GUI |
| graphical.target | 5 | Multi-user + display manager/GUI |
| reboot.target | 6 | Reboot |
graphical.target itself Wants=multi-user.target, since graphical mode is a strict superset — everything multi-user mode provides, plus a display manager on top.
The Default Target
Which target boots by default is determined by a symlink — /etc/systemd/system/default.target pointing at the chosen target — genuinely similar in spirit to systemd1-3's own WantedBy= symlink mechanism, just applied to the top-level boot target rather than an individual service. A headless server typically defaults to multi-user.target; a desktop distro typically defaults to graphical.target.
systemctl isolate — Switching Targets Live
Run on a live graphical system, this stops everything not required by multi-user.target — the display manager included — and starts anything multi-user.target requires that wasn't already running. A genuine live runlevel-style switch, no reboot required. A real, practical use: temporarily dropping out of a graphical environment to troubleshoot a display/GPU driver issue, then isolating back to graphical.target once fixed.
Direct Legacy Comparison
systemd1-1's own System V material named telinit 3 as the legacy way to switch runlevels live. That maps directly to systemctl isolate multi-user.target — the same real-world action, but a genuinely different, more expressive mechanism underneath: an actual dependency-resolution operation, not a legacy numbered switch with no explicit relationship to what it starts or stops.
Resolving grub1-4's Own rescue.target
grub1-4 taught appending systemd.unit=rescue.target at the GRUB menu to reach a recovery shell, without explaining what that parameter actually meant. Now it's clear: this tells systemd to boot straight to this target instead of the normal default, bypassing graphical.target/multi-user.target's own much larger set of Wants=/Requires= dependencies entirely, landing in a genuinely minimal environment with far fewer units started — exactly why it's usable for recovery even when something elsewhere in the normal boot chain is broken.
systemctl list-units --type=target lists every target currently active on the system — a concrete way to see this chapter's own material reflected in real, live system state rather than only reasoning about it abstractly.
rescue.target on a live production system stops nearly everything non-essential immediately — network services included, in many configurations. Genuinely disruptive to anyone actively using the system; not something to run casually just to "see what happens."
Hands-On Exercises
Write the command that sets a headless server's default boot target to multi-user.target, and explain why a headless server should never default to graphical.target.
📄 View solutionExplain what happens to a running display manager when an administrator runs systemctl isolate multi-user.target on a desktop system currently in graphical.target, and why.
📄 View solutionExplain, in terms of this chapter's own material, why booting with systemd.unit=rescue.target (grub1-4's own kernel parameter) can succeed even when something is broken elsewhere in the normal boot chain that would prevent reaching graphical.target or multi-user.target.
📄 View solutionChapter 5 Quick Reference
- A target is a named synchronization point — "reached" once everything it requires/wants has started
- poweroff.target (0), rescue.target (1), multi-user.target (3), graphical.target (5), reboot.target (6) — direct legacy runlevel mapping
- graphical.target Wants= multi-user.target — a strict superset, GUI on top of full multi-user mode
systemctl get-default/set-default— controlled by a symlink, the same mechanism as an individual unit's own WantedBy=systemctl isolate TARGET— a live runlevel-style switch, the modern equivalent oftelinit N- grub1-4's own systemd.unit=rescue.target works precisely because it skips graphical/multi-user's own much larger dependency set
- isolate is immediately disruptive on a live system — never run casually