There are times when your brain’s autopilot misfires and you suddenly find yourself reading about how cannibals eat their own babies. So one such thing happened and this article was written. So, do not think of this article as a tutorial or a man-page. This article just discusses the power of Systemd as an init system and primarily focuses on putting forward the most important and heavily used aspects of managing services in an operating system. You are strongly encouraged to read Chapter 8 of Redhat System Administrator’s Guide if you would prefer a complete hard-core technical tutorial. Let’s get started.
An Init System, eh?
First things first. Systemd is basically a new init system. So before understanding systemd, it is of paramount importance that there is no confusion about what an init system is. I am sure many of you would be aware of what init systems are, but for the rest of us, let’s go through the basics quickly.
First of all, do me a favor and run this command in your Linux terminal.
Now, the first process that you see would be a process called systemd, or init. An init system is the first process that your kernel starts upon being loaded by the bootloader when your system starts, and naturally, gets a PID 1.
You can also see the whole process tree with this command
You will see init or systemd as the root process. If you don’t, you are in serious trouble, pal.
The role of an init system is not very well defined, and depends heavily on the very init system you are using. However, there are certain things that an init system must do. This includes starting, stopping and restarting essential services like the networking service to start listening to a particular port.
Moreover, now that they are assigned PID 1, their responsibility also increases. Kernels make the process at PID 1 immediately adopt all orphaned processes. So the init system adopts all the orphaned processes.
A wise man once said, Jiska koi nahi, uska init
Of all the functionalities that an init system provides, the functionality which happens to be of utmost importance to users happens to be the way an init system allows a user to view the status of services, and restart the service whenever (s)he wishes to.
The two most popularly used init systems are
SysV init and
systemd. Another init system, called
Upstart is used in some Ubuntu versions including the popular 14.04, which is quite like SysV init and for the sake of clarity, I am going to refer to both of them as SysV init in this article.
Let’s make an attempt to understand how the two are different.
Systemd vs SysV init
Although it has been long in debate that whether or not SysV init should be replaced with the newer systemd, no definite conclusions have been reached. However, the general trend is that more in-action distro maintainers like those of ArchLinux, and Redhat had readily adopted systemd and are now debating whether or not it pull it down, while the relatively playing-it-safe ones like those of Ubuntu took a long time to decide but have finally rolled out full-on systemd with their 16.04. This also means that Ubuntu 14.04 derivatives like Elementary Freya still use the older versions. However, Ubuntu 15.* series provides an option to switch between Upstart and Systemd as the init system.
System V init was developed in 1982 with its contemporary computing situation, using the features provided by a UNIX system in 1982. Obviously, it has undergone improvements since then. In contrast, systemd was developed by a Redhat maintainer as a hobby some 30 years later, to address the situation 30 years later, and using the features provided by a UNIX system some 30 years later, which clearly were not available in 1982. No one can say newer means better, but let us look into how it affects us.
systemd is a much bigger software suite and provides many more functionalities as opposed to SysV init, which apparently has been one of the strongest points of its haters that it is bulky. But as bulkier as it gets, it now delivers as many more services like the journald daemon which is an event-logging system and happens to be very useful in zeroing down code leakages. It now, as an init system, also manages virtual device files when they are hot-plugged.
Whether all of that makes sense to you or not, it doesn’t matter, but one difference that you are going to see while moving from SysV init to systemd is that your system will boot slightly faster.
The simple reason behind systemd being faster is parallelization of a lot of tasks, exploiting the powers of a modern-day computing system (well, a computer). Although systemd was not designed for speed but for getting the things done neatly which in turn avoids all the unnecessary delay.
In essence, systemd is basically a modern-day foster of your processes who also extends nanny services to you.
Managing services with systemctl
Before we dirty our hands by handling services with systemd, it must be noted that systemd is backward compatible with SysV init and Upstart, so you can try it out by installing it on any Linux that uses SysV init or Upstart (leaving apart certain adamant Ubuntu versions).
Let’s start with a plain ‘systemctl’ command without any options.
When we use systemd, our target is usually a
unit, which is basically a resource you have on your computer; be it a service, or a device, or a socket, or possibly something else. These units are defined in special files called
unit files. The type can be inferred from the file’s suffix. For instance, service files have names of the type
Now that we know about what kind of files we will be dealing with, let’s get started and learn about monitoring and controlling services. I am going to use the
getty@tty5 service to play around with, since I generally do not use it as much and playing with it is mostly harmless. Feel free to replace it with the service of your choice, but make sure you know what that service does. As far as tty5 is concerned, it is the fifth terminal session in a Linux operating environment. A typical Linux distribution by default runs 7 terminal sessions (tty1 through tty7) and the desktop environment (the GUI of your OS) typically runs on tty7.
To scroll through them, just try pressing
Ctrl+Alt+(Fn)+<F1 to F7>.
To keep a tab on the results of what we are doing, an essential systemd option is the
systemctl status email@example.com
This will give you an overview of the current health of a service. Mostly you will see that the service is loaded but inactive, unless you have been using
tty5 previously. Let’s start the service and check again.
As simple as it can be, to start a service, we just write
systemctl start firstname.lastname@example.org
You may also choose to omit the
systemd is smart enough to add that on its own.
This works, just as well.
systemctl start getty@tty5
Now try checking the status again. Since we just have to see whether the service was activated or not, you can just check that by doing
systemctl is-active getty@tty5
Obviously, you can also check the way we did previously with
status as we did previously.
Let’s not waste too much time on trivial commands and get it straight. The following two are pretty well self-explanatory. They do just what you are thinking what they do.
systemctl stop getty@tty5
systemctl restart getty@tty5
However, a point of caution here. Realize that restarting stops the service and starts it again. However, if that is not necessarily required (as will usually be the case), you can use
systemctl reload <service_name>
Reloading is basically telling a service to keep running, but just re-read the configuration files.
Also, if you are not sure whether or not a restart is required, just key in
systemctl reload-or-restart <service_name>
Gotcha! Systemctl got your back.
But, you know what? Starting and stopping services is boring. If you have been using Linux as your primary operating environment, then you must have done so while following instructions from some internet forum after breaking some part of your system.
Shout out to the Ubuntu people who have broken their
Unityand have done all this for their
Things get interesting with automation. Think about auto-starting services. Once you start writing your own services, sky is the limit. You can put your services on autostart at boot time, by simply doing
systemctl enable <service_name>
In a nutshell, it creates a symlink from the service file to the location where systemd looks for service files to start at boot time.
Take a moment and realize the difference between
start, well it just starts the unit then and there; while
enable will anchor the specified unit file to a relevant place so that it automatically starts on boot or when relevant hardware is hot-plugged (depending on the contents of the unit file).
enable does not start a service at that time, though.
While we are at it, you can disable a service using
systemctl disable <service_name>
Pro Tip: Try looking for enabled services and disable unwanted services (after reading about them) for faster boot times.
One of the most useful functionalities that systemctl provides is that you can view failed services. This helps in finding root causes of mysterious problems.
You guys know of those times when something starts working again after a simple restart? Well, that is many times, because some service would have failed and when you restart, your system starts all the services again. So the next time something stops working suddenly, just quietly check for failed services and you will find your way by restarting that service, without needing to restart the entire system. The restarting feature comes quite handy when you are playing with the networking service upon tweaking your IP configurations. A lot of people will ask you to restart the computer for changes to take place, but now you know the workarounds.
Of the many functionalities that systemd provides, one of my favorites is
In essence, it blames different components, that are initialized while booting your system (popularly known as the userland components), for the time they took.
I think now we can move on to understanding unit files for init systems.
Systemd Unit Files
Enjoying the true power of Linux comes with the freedom to tweak programs by supplying desired parameters via configuration files (which are more lovingly called ‘the config files’). In the context of init system management, they prefer to call them
unit files. Let us have a quick look at some standard unit files that are already there in our systems.
Unit files are typically placed in
/usr/lib/systemd/system, where they are mostly written to by package developers, or
/etc/systemd/system/, where they are written to by administrators. Admin-authored files enjoy the privilege of high precedence over package-installer written files.
More often than not, we would want to overwrite only specific directives. We do that by creating a directory named after the unit file and appending a
.d to it. Within this directory, we create a file with
.conf to extend or override the attributes of the main file.
If you didn’t while reading the last few paragraphs, go and have a look. You would have noticed that these unit files are of the form
These unit files usually assume one of these identities as type_extension’s
|Service unit||.service||A systemd service. Describes how to manage a service.|
|Target unit||.target||A group of systemd units. Provides synchronization point for other units when booting up or changing states.|
|Device unit||.device||A device file recognized by the kernel.|
|Socket unit||.socket||An inter-process communication socket. Describes a network or IPC socket that systemd uses for socket-based activation. These always have an associated
|mount unit||.mount||It defines a mount point on the system to be managed by
Well, actually I cut the table short. Complete list here.
For closure, let’s take a quick look at some common unit file, say the dhcpcd service. Most of you would be aware that this service is used to procure the IP address from the DHCP server when one connects to a LAN or a Wi-Fi network.
[Unit] Description=dhcpcd on all interfaces Wants=network.target Before=network.target [Service] Type=forking PIDFile=/run/dhcpcd.pid ExecStart=/usr/bin/dhcpcd -q -b ExecStop=/usr/bin/dhcpcd -x [Install] WantedBy=multi-user.target
These files are very straight-forward and mostly do what you think they will do. A unit file is divided into named sections where these names are enclosed in those grumpy square brackets.
The most critical part of this service file is the
ExecStart tag. It tells the init system what command/script to run when you start executing this service.
To conclude, it comes out that having a good hold over units and unit files makes system administration a lot more comfortable and fun. Systemd has a fairly simple declarative syntax which is quick and easy to follow and manipulate services. Power and freedom are best utilized when you wield them.
I would strongly recommend interested readers to do a quick go-through of Chapter 8 of Redhat System Administrator’s Guide to understand how to write their own unit files and best practices.
Do realize that if you encounter any confusion with any of these things, just RTFM and you will be back on your way. Play around. Once you are done with the man page, go and read up systemd’s Arch Wiki page for closure. Read about masking and isolating unit files, and doing power management with systemctl. And once done with that, to quote another wise man, go and watch Fight Club.