Basics of runlevel vs. targets
In sysV (init) runlevels were simply a number, 0-6. A system could only be set to a specific runlevel, typically 3 (network + console) or 5 (X windows). These runlevels in sysV merely were states that the main process,
init could be in at any given time. With systemd, targets serve a similar purpose, but multiples can be applied simultaneously.
systemd uses targets which serve a similar purpose as runlevels but act a little different. Each target is named instead of numbered and is intended to serve a specific purpose with the possibility of having multiple ones active at the same time. Some targets are implemented by inheriting all of the services of another target and adding additional services to it. There are systemd targets that mimic the common SystemVinit runlevels so you can still switch targets using the familiar telinit RUNLEVEL command.
Given this ability, in systemd, a typical system where there's networking, but no X running is in target
$ systemctl get-default
But a target is an encapsulation (groupings) of many targets. This is one of the key advantages of systemd over sysV. You can see this if you look at the target files.
systemd.target man page
A unit configuration file whose name ends in ".target" encodes information about a target unit of systemd, which is used for grouping units and as well-known synchronization points during start-up. ....
.... They exist merely to group units via dependencies (useful as boot targets), and to establish standardized names for synchronization points used in dependencies between units. Among other things, target units are a more flexible replacement for SysV runlevels in the classic SysV init system. (And for compatibility reasons special target units such as runlevel3.target exist which are used by the SysV runlevel compatibility code in systemd. See systemd.special(7) for details).
$ grep target /usr/lib/systemd/system/anaconda.target
NOTE: Here the
basic.target to have run, and it has to run after
From my CentOS 7.x system we can see what targets are loaded:
$ systemctl list-units --type=target
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
cryptsetup.target loaded active active Local Encrypted Volumes
getty-pre.target loaded active active Login Prompts (Pre)
getty.target loaded active active Login Prompts
local-fs-pre.target loaded active active Local File Systems (Pre)
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User System
network-online.target loaded active active Network is Online
network.target loaded active active Network
nfs-client.target loaded active active NFS client services
paths.target loaded active active Paths
remote-fs-pre.target loaded active active Remote File Systems (Pre)
remote-fs.target loaded active active Remote File Systems
rpc_pipefs.target loaded active active rpc_pipefs.target
slices.target loaded active active Slices
sockets.target loaded active active Sockets
swap.target loaded active active Swap
sysinit.target loaded active active System Initialization
timers.target loaded active active Timers
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
19 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
What's a unit in systemd?
Unit files in systemd are merely configuration files that define one of 5 things. Units can be, for example:
- services (.service)
- mount points (.mount)
- devices (.device)
- sockets (.socket)
- targets (.target)
You can see these unit files under this directory on CentOS 7.x:
$ for i in target socket service device mount;do ls -l /usr/lib/systemd/system | grep $i | head -3;done
-rw-r--r-- 1 root root 415 May 3 16:05 anaconda.target
-rw-r--r-- 1 root root 517 Apr 11 03:36 basic.target
drwxr-xr-x. 2 root root 4096 Jul 28 14:56 basic.target.wants
-rw-r--r-- 1 root root 874 Apr 10 23:42 avahi-daemon.socket
-r--r--r-- 1 root root 131 Apr 11 01:03 cups.socket
-rw-r--r-- 1 root root 102 Apr 11 03:23 dbus.socket
-rw-r--r-- 1 root root 275 Apr 27 10:53 abrt-ccpp.service
-rw-r--r-- 1 root root 380 Apr 27 10:53 abrtd.service
-rw-r--r-- 1 root root 361 Apr 27 10:53 abrt-oops.service
-rw-r--r-- 1 root root 169 Apr 12 15:28 clean-mount-point@.service
-rw-r--r-- 1 root root 670 Apr 11 03:36 dev-hugepages.mount
-rw-r--r-- 1 root root 590 Apr 11 03:36 dev-mqueue.mount
When a system that is constructed with systemd boots, it's processing the unit files to construct mounts, set up sockets, and start services. The ordering of these things is governed by the unit files.