Systemd: boot process and unit files
What is systemd? βοΈ
Systemd - an initialization and service management system for Linux systems that replaced the traditional SysV init.
There has been and still is much criticism regarding the use of systemd. Personally, Iβm a big fan of systemd itself I like it and use it wherever I canβ¦ it's 2025, not 2005
Here I discuss the system in the context of Linux on servers and desktops. Systemd is not useful in places where the device is supposed to perform a specific task without unnecessary extras, e.g., in embedded systems, containers (Alpine Linux), etc.
Main differences between systemd and SysV init:
Feature | Systemd | SysV init |
---|---|---|
Service startup | Parallel | Sequential |
Dependencies | Automatic management | Numeric runlevels |
Configuration format | Unit files | Shell scripts |
Logging | Journald | Syslog |
Boot process with systemd π
Early Boot
The boot process with systemd proceeds as follows:
- BIOS/UEFI β hardware initialization and reading the disk's MBR/GPT
- Bootloader (GRUB2) β loading the kernel and initramfs into RAM
- Kernel + initramfs β initialization of basic hardware drivers
- systemd (PID 1) β launched as the first process in the system
- Mounting filesystems β mounting filesystems according to the hierarchy
- Starting system services β initializing processes, daemons, and services
- User login prompt β the final stage of the boot process
Systemd starts in several stages:
a. sysinit.target
Basic system preparation:
- Activation and mounting of the root partition (
/
) in read-only mode - Initialization of pseudo-filesystems (
/proc
,/sys
,/dev
,/run
) - Handling of encrypted filesystems (
cryptsetup
,LUKS
) - Unlocking encrypted partitions from
/etc/crypttab
- Creating mapper devices for unmapped partitions
- Starting
udev
for hardware detection - Loading required kernel modules
- Configuring in-memory virtual filesystem
- Setting hostname, loopback
- Preparing dynamic code generator
At this stage, systemd mounts filesystems in a specific order:
/etc
and/usr
β mounted first, contain configuration files and binaries- The root filesystem (
/
) is remounted as read-write - Local filesystems from
/etc/fstab
b. basic.target
- Initialization of basic system services
- Activation of system sockets and timers
- Initialization of system logging (
journald
) - Configuration of system clock
- Swap activation
- Preparation of systemd unit generators
At this stage /var
becomes available, allowing services that write data to start
c. multi-user.target (usually default.target)
- Starting standard system services
- Full network activation
- Starting user services
- Activation of sshd and other remote access services
- Starting local login terminals
All filesystems from /etc/fstab
are mounted and available
d. graphical.target (optional)
- Starting the graphical environment (X11 or Wayland)
- Login manager (gdm, lightdm, sddm, etc.)
- Graphical services and user interface
This target is an extension of multi-user.target and is the default on desktop systems
Types of systemd unit files π
Systemd manages the system through unit files. Below are the different types of units:
Systemd namespace
Systemd searches for unit files in a specific order and locations:
/etc/systemd/system/
β local configuration files (highest priority)/run/systemd/system/
β files generated at runtime/usr/lib/systemd/system/
β files installed by packages
Systemd automatically recognizes the unit type based on the file extension (.service, .socket, .timer, etc.) and places them in the appropriate namespace. Each namespace is managed by a dedicated systemd controller.
1. Services (.service) β‘
Standard system services:
[Unit]
Description=Apache Web Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/httpd -k start
ExecStop=/usr/sbin/httpd -k graceful-stop
ExecReload=/usr/sbin/httpd -k graceful
PrivateTmp=true
[Install]
WantedBy=multi-user.target
2. Timers (.timer) β°
An alternative to cron:
[Unit]
Description=Backup every 6 hrs
[Timer]
OnBootSec=15min
OnUnitActiveSec=6h
AccuracySec=1min
[Install]
WantedBy=timers.target
Corresponding service:
3. Mount points (.mount) πΎ
Mounting filesystems:
[Unit]
Description=Mount NFS Share
After=network.target
Before=remote-fs.target
[Mount]
What=192.168.1.100:/shared
Where=/mnt/shared
Type=nfs
Options=defaults,noatime,_netdev
TimeoutSec=10
[Install]
WantedBy=multi-user.target
For each entry in /etc/fstab
, systemd automatically generates a .mount
file. The unit file name must strictly correspond to the mount path, with /
replaced by -
(e.g., for /mnt/data
, the unit name is mnt-data.mount
).
Some important options of the [Mount] section:
What
β source (device, network resource)Where
β mount point in the filesystemType
β filesystem type (ext4, nfs, btrfs, etc.)Options
β mount optionsDirectoryMode
β permissions for the mount pointSloppyOptions
β whether to ignore unknown mount optionsLazyUnmount
β whether to use lazy unmountingForceUnmount
β whether to force unmountingReadWriteOnly
β whether to mount as read-write only
4. Sockets (.socket) π
Socket units allow services to be activated only upon the first connection, which saves system resources.
Each socket is linked to a service with the same base name (e.g., sshd.socket with sshd.service). Systemd implements on-demand activation (socket activation), where the daemon does not have to run all the timeβit is started by systemd, which listens on its behalf.
[Unit]
Description=OpenSSH Server Socket
[Socket]
ListenStream=22
Accept=yes
[Install]
WantedBy=sockets.target
5. Paths (.path) π
.path units allow monitoring changes in the filesystem and activating linked services when a specific event occurs.
They can track file creation, modification, or attribute change. They are a great alternative to inotify()
and allow actions to be triggered without loops or monitoring tools.
Note
Not suitable for monitoring changes on NFS
[Unit]
Description=Check /etc/nginx path
[Path]
PathChanged=/etc/nginx/
Unit=nginx-reload.service
[Install]
WantedBy=multi-user.target
Corresponding service:
6. Devices (.device) π¨οΈ
.device units in systemd are created automatically by the system based on udev information and are used to represent hardware devices such as disks or network interfaces