systemd

Systemd – How it starts Your system

Systemd was developed when developers found that starting the system in parallel was not possible. The older systems goes through their system startup files one by one. This can cause the boot to stop when waiting for resources that are slow. One example of this is when a process needs to have the network running. Using the network is very slow, other resources should not have to wait. This problem can be mitigated in other ways but with systemd, all startup is made in parallel where possible. The result should be a much faster startup for complex systems, which includes your desktop system.

Systemd: Father of all other processes

A Linux, and any other *nix, system always starts a process that is the father of all other processes. When you use Systemd, that process is systemd, the process is always called ‘init’ irrespective of init system. Once systemd is running, it will start the daemons that run the subsystems. The daemons control what resources you have and what systems are open. Your login prompt is a service managed by systemd. Systemd starts many other services and it also mounts all your disks, including the snap mounts.

How do you control what starts?

First of all, the earliest init system had runlevels that many readers will recognise. Runlevel 1 was single user mode, 2 multi-user mode without networking and 3-5 multi-user and graphical. Setting the runlevel to 0 meant halt and 6 meant reboot. Developers of systemd found these levels to be unclear so changed it to be called targets. Targets are not exactly the same but has a similar function. When a specific target is running, a specific collection of units are running. More on units later.

Setting the “runlevel”, called a target.

You can change the target while running, for example you could use a terminal to set your target to multi-user. This would stop your GUI, X or Wayland but let you and others, log in with a text console. Use the following command.

$ systemctl isolate multiuser.target

Or, if you want to start your desktop, use the following command instead.

$ systemctl isolate graphical.target

What you are really interested in is how to start the correct level, you can find out what you have right now this way.

$ systemctl get-default

To change the default set it.

$ systemctl set-default graphical.target

This command actually makes a lot of units and services start as you boot your computer. You may want to start or stop a single service though.

STARTING, stopping, enabling and disabling a service.

This is where you have a chance to change what goes on at boot and during normal operation. In contrast to the targets, units are special for a particular service. To stop a service you use ‘systemctl stop’, equally you can use ‘start’ and ‘restart’. To make a service start at boot you use ‘enable’, to stop it ‘disable’. Pick a service and start and stop it while it is running.

$ systemctl status cups.service

This command shows the status of the service, it also shows a list of actions taken by the system regarding the service. To stop the service, use the command below.

$ systemctl stop cups.service

The service is now stopped for your current session. To change it to not starting at the next boot use disable.

$ systemctl disable cups.service

Notice that you could only disable the service, this would have no effect on your current situation. The service just keeps on running. At the next boot though, it will not start the service.

Systemd also controls mounts, devices, sockets and more. Units are lower down and easier to understand, if you have dealt with a Linux before. You can also set these yourself but the most effect on boot is to control services.

How do you add your own scripts?

You can add your own scripts quite easily, the details that are interesting to know is how you make your script or service to depend on others. This is neatly demonstrated in this wifi-resume service file.

[Unit]
Description=Restart networkmanager at resume
After=suspend.target
After=hibernate.target
After=hybrid-sleep.target
 
[Service]
Type=oneshot
ExecStart=/bin/systemctl restart network-manager.service
 
[Install]
WantedBy=suspend.target
WantedBy=hibernate.target
WantedBy=hybrid-sleep.target

This code creates a service that happens once (oneshot) after the three targets mentioned in the code. The code that is executed is in this case a single command. You can just as well point ExecStart to a script of your choosing.

Conclusion

Changing your system, especially how it boots, you can do yourself but beware that this has many consequences for each service so make sure that your code is stable and quick to execute.

About the author

Mats Tage Axelsson

Mats Tage Axelsson

I am a freelance writer for Linux magazines. I enjoy finding out what is possible under Linux and how we can all chip in to improve it. I also cover renewable energy and the new way the grid operates. You can find more of my writing on my blog.