systemd the system daemon is a replacement for sysvinit. There is some controversy about it, since it is replacing many beloved system tools as loggers, cron, ntp.
Today, systemd is used in most of the Linux distributions as the start up method.
Linux for embedded systems often do not use systemd yet.
Using systemd makes the different Linux distributions very similar. What stays different is the package handling and management.
The most used command is systmctl
The package manager installs in /usr/lib/systemd and customizations are done in /etc/systemd
If the same occurs in both location /etc/systemd has priority.
systemd also has introduced services run by the user and not as system service
/etc/mtab is handled differently since systemd does mounting. For backward compatibility do or check ln -sf /proc/self/mounts /etc/mtab
systemd does not require a udev package since it includes it (this has put the pressure to distributions using OpenRC to fork udev in a separate package).
systemd replaces ConsoleKit
Dealing with /etc/fstab additional .mount and .swap units can be automatically created
comment=systemd.automount
can be added to the drives in /etc/fstab to convert them to automount drives and not have the system waiting until such typically network drives are ready.
Since systemd is running all the time also a gui tool systemadm is available.
systemd-analyze tells how long the boot process was taking
There is support to make a svg graphics as bootchart systemd-analyze plot > plot.svg or systemd-analyze dot | dot -Tsvg > systemd.svg to convert it first to dot format and then having dot making the dependengy graph. Or simply see the ranking of what took long to start systemd-analyze blame
Keyboard layout can be listed as localectl list-keymaps and loaded as root with loadkeys <keymap as sg> or persistent by localectl set-keymap --no-convert <keymap> this modifies /etc/vconsole.conf obviously /etc/vconsole.conf could also be edited using an editor.
Modules not loaded automatically can be listed (one per line) and added to files like /etc/modules-load.d/<some name>.conf
The network must probably be started. In case of dhcp start the client daemon dhcpcd eth0 or start it via its unit systemctl start dhcpcd@eth0.service
The kernel must know to start systemd and not init after it has booted. For grub legacy put
kernel /vmlinuz root=/dev/sda2 init=/usr/lib/systemd/systemd
in /boot/grub/grub.conf and for grub 2 put
GRUB_CMDLINE_LINUX="init=/usr/lib/systemd/systemd"
in /etc/default/grub
The units are text files and have different file extensions as
*.service to start a service (e.g a daemon)
*.mount to mount a filesystem (there is also .automount)
*.socket prepare a socket for a listener and when accessed trigger an action
*.path to monitor accesses to a file or directory and trigger an action
*.timer to create a cron like timer that starts services
Unit files can be found on different locations:
/usr/lib/systemd/system/ installed by the package manager
/etc/systemd/system/ unites adapted for the system by the distribution and system administrator
/etc/systemd/user/ units for all users
~/.config/systemd/user/ units for a dedicated user
systemctl --failed to show what failed
Available units can be seen by
ls /usr/lib/systemd/system
systemctl --all --full
systemctl list-units or simply systemctl
systemctl list-units --all
systemctl list-unit-files
systemctl | grep running
systemctl list-unit-files | grep enabled
systemctl is-enabled rpi-connect.service to see if it is enabled
sudo systemctl enable syncthing@<username>.service is a system service that requires a user being passed after the @ character
Customization can be made by copying and modifying those files to /etc/systemd/system
systemd calls more or less it units in parallel. If a unit calls an other that is not ready, then systemd buffers the request using sockets.
Systemd can create automatically additional units as when devices are plugged in. Therefore it uses in udev rules
TAG+="systemd"
The unit files have different extensions but the file content has sections that are equal.
This section therefore descripes what is common and this will therefore not repeated in the dedication unit type sections.
[Unit] Description=<bla bla>After=<*>.service
The unit section can hold:
After starts after the named service
Before starts before the named service
Wants starts the named service
Requires starts named service and when alive starts itself. It would terminate when the named service would die
The install section holds usually
[Install]WantedBy=multi-user.target
This line is used with systemctl enable <unit name>.<extension>
It creates a symlink in the multi-user.target.wants directory
When later the multi-user.target is started it looks into this directories
WantedBy lets the system continue n faillure RequiredBy would stop.
systemd targets are used to group units and have them started together and form therefore something similar as runlevels in a sysvinit system.
*.target files can include other *.target files
/etc/systemd/system/default.target is a symlink to the default target
systemctl get-default shows this default targets that is run at boot
Common default targets are: multi-user.target, graphical.target, rescue.target
systemctl list-unit-files --type=target lists the unit files that are targets
systemctl set-default graphical.target sets the graphical desktop target
systemctl set-default multi-user.target sets the command line target
systemctl list-dependencies multi-user.target show what depends on it.
systemctl isolate multi-user.target will stop all targets except the multi-user.target
systemctl poweroff or poweroff turns off the computer
systemctl reboot or reboot reboots it.
More precise systemctrl calls the unit poweroff.target that is in /usr/lib/systemd/system
To have a place where data can be persistent saved add:
[Service] User=<user that runs the service if not root>StateDirectory=<subdirectory created under /var/lib>WorkingDirectory=/home/<username>RuntimeDirectory=<subdirectory in /run>RuntimeDirectoryMode=0755
For security reasons it is advised to run the service as a user
Adding a services to the list of being started at boot (the boot.target) is more uniform:
systemctl enable <name>.service enable automatic start at boot
systemctl enable --now <name>.service does two things enable automatic start at boot and starts it now
systemctl disable <name>.service disable automatic start at boot
systemctl is-enabled <name>.service shows if the service is enabled to automatic start at boot
systemd handle services as known from sysvinit systems:
systemctl start <name>.service starts a service
systemctl stop <name>.service stops a service
systemctl restart <name>.service stops and then starts a service
systemctl reload <name>.service similar to restart is reload however normal functionality of the service keeps maintained.
systemctl status <name>.service shows the status
systemctl mask <name>.service the service can no be started even if the the system tries it
systemctl --user status <name>.service shows the status of a user service
systemctl cat <name>.service to read the file without dealing with its path
systemctl list-dependencies <name>.service or systemctl list-dependencies --all <name>.service to see its dependencies
systemctl show <name>.service to see the low level details
Type= defines when the service is considered to be successful. Values are:
exec it must running
simple as exec but not detail time consuming checking if it is well running. It is the default and therefore does not have to be declared.
oneshot it is normal that it runs and then terminates
The command follows ExecStart=
It is possible to add ExecStartPre and ExecStartPost= to add additional commands
Restart=OnFailure allows to restart the command. There are also option to configure the restart behavior
There are many options to make it more secure:
User=_
DynamicUser=yes
NoNewPrivileges=yes
ProtectHome=
ProtectSystem=
PrivateDevices=
ReadOnlyPaths=
PrivateNetworks
Instead of modifying a service file installed by the system to /usr/lib/systemd/system/ and risk to have it overwritten with the next update or risk a disaster, an override can be applied with systemctl edit <name>.service<name>.service
The original file /usr/lib/systemd/system/ stays untouched<name>.service
The result will end up in /etc/systemd/system/ <name>.service.d/override.conf
additional *.conf files can be added and are executed in alphabetical order
systemctl cat <name>.service to see the result of the override
systemctl daemon-reload and systemctl restart <name> to have it applied.
To revert delete the /etc/systemd/system/ or systemctl revert <name>.service.d/override.conf<name> and run systemctl daemon-reload and systemctl restart <name>
sytemd-timesyncd is a time framework that handles the system clock and can also replace cron.
timedatectl should be run to see it NTP is enabled, if not timedatectl set-ntp true will enable it.
timedatectl timesync-status will show if it is happy
To have it permanently active check and edit /etc/systemd/timesyncd.conf
NTP=0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org FallbackNTP=ntp.ubuntu.com
An other NTP services as chronyd are not required and might cause conflicts.
For backward compatibility reasons crontab is usually still working on systemd systems. The systemd way is however using timer unit files.
Those are *.timer files
[Unit] Description=example timer [Timer] OnCalendar=Mon 09:00:00 [Install] WantedBy=timers.target
The *.timer file starts a *.service file having the same name. The service file should contain
[Service]Type=oneshot
So systemd knows it will be normal to run and then terminate. On other services this behavior might be considered as a crash and cause a restart.
timers.target starts all *.timer files after boot
The [Timer] section allows different settings as:
OnCalendar= to set a calendar date supporting with * wildcards and with commas lists as Mon,Wed,Fri or ranges as Mon..Fri. https://systemd.guru/ lets play with. systemd-analyze calendar "Mon 09:00:00" will also show what it would do with the calendar string
OnBootSec= starts x seconds after boot
OnUnitActiveSec= starts x seconds after the service unit starts
OnUnitInactiveSec= starts x second after the unit has terminated, so no reentered service unit will happen
Persistent=true will check if unit calls have been missed during the time the system was not powered and if so, start the service unit
Unit= has to be use it the *.timer has an other name as the *.service file to be called.
systemctl <start,stop, status, enable> *.timer is used to operate the timer.
systemctl list-timers will show the active timers
Directories as or <xxx>.<target, service>.wants exist. This is a second and dynamic way to add dependencies to units. <xxx>.<target, service>.requires
A user-created.service might have
[Install] WantedBy=multi-user.target
if enabled systemctl enable user-created.service then
ls -la /etc/systemd/system/multi-user.target.wants/
will show a symlink to /etc/systemd/system/user-created.service
systemd does not need a logger since it includes the logger journal. It can be configured via /etc/systemd/journald.conf
To have the log stored on the disk /var/log/journal
Storage=persistent
or mkdir -p /var/log/journal
To set maximum size on disk
SystemMaxUse=50M
Limits to 50MByte if this is missing it will be limited to 10% of the partition size.
The log is binary and not ASCII and can be read via journalctl
For just the current boot journalctl -b
For the kernel messages journalctl -k.
journalctl -eu <name>.service
will show what has been logged for a service and with e jump to the end of the log.
The journal can feed a classic logger by systemctl enable syslog-ng so the log becomes ASCII again.
journalctl -b --no-pager | grep <word to be in the line>