The systemd system and service manager is relatively new for our Enterprise Linux operating systemd but has been under development by Redhat since 2010 on the Fedora platform. It was created by Redhat developers Lennart Poettering and Kay Sievers to provide a standard process for controlling which programs start when a Linux system boots. In one of our previous articles, we talked about the sysVinit system and service manager. In this article, we will introduce you to systemd and describe the advantages which have led systemd to replace sysVinit.
What is systemd?
Like sysVinit, systemd is a system and service manager which means it controls how different services are started and stopped during system boot and shutdown respectively. It also controls how new services (usually daemon-based services) are added to the system and managed thereafter. Systemd also replaces the concept of run levels which was part of sysVinit with targets which we will discuss in this article.
How does systemd work?
First, let’s mention that systemd replaces init as the process with the PID 1. We can verify it by using the top command as shown below:
[root@linuxnix ~]# top -p 1 -n 1 top - 03:55:41 up 17 min, 1 user, load average: 0.01, 0.02, 0.05 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.3 us, 0.5 sy, 0.0 ni, 98.2 id, 0.9 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 1865988 total, 1568488 free, 121016 used, 176484 buff/cache KiB Swap: 2097148 total, 2097148 free, 0 used. 1568864 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 125628 4200 2484 S 0.0 0.2 0:02.00 systemd
Systemd makes a server boot quicker because it uses fewer scripts and tries to run more tasks in parallel, Systemd calls them units. Under systemd, services are now defined in what is termed as unit files which are text files that contain all the configuration information a service needs to start, including its dependencies. Target units represent run levels and service units represent services. Unit files with the extension .target represent boot targets and unit files with the extension .service represent unit files for services. All processes started by a service unit are tagged with the same cgroup. In this way when the service shuts down, it makes it easier to ensure that all related processes are also shut down. Service units can be activated on other events such as hardware detection and not just by transitioning to a different run level. Resource management is controlled and limited through the cgroup created for each service. Therefore, control groups provide a way in which related tasks or processes can be aggregated or partitioned for management. Service units i.e the services themselves are started in parallel. We can have dependencies among different services.
As we mentioned earlier, with systemds’ parallel service startup the system boots up very quickly. We can, in fact, check the time it took to boot the system using the following command:
[root@linuxnix ~]# systemd-analyze Startup finished in 2.035s (kernel) + 2.749s (initrd) + 21.993s (userspace) = 26.778s [root@linuxnix ~]#
We can also check the time taken by individual services to startup with the systemd-analyze blame command as shown below:
[root@linuxnix ~]# systemd-analyze blame 5.690s NetworkManager-wait-online.service 4.774s systemd-udev-settle.service 4.165s kdump.service 3.051s tuned.service 2.877s lvm2-monitor.service 2.803s dev-mapper-cl\x2droot.device 2.317s polkit.service 2.053s NetworkManager.service 1.931s abrt-ccpp.service 1.560s postfix.service ---------------------output truncated for brevity
Systemd Target units
The targets in systemd correlate to what we call run levels in sysVinit. We’ll be using the term run level and target interchangeably since they imply the same thing. For example, the poweroff.target is equivalent to run level 0. Given below is the systemd target name corresponding to the sysVinit run level.
When booting through grub, we can still use numbers to boot to a particular run level as well as the systemd target.
Rather than using the /etc/inittab file to set the default run level, we can set it from the command line.
To list the current default run level set on the system, use the following command:
[root@linuxnix ~]# systemctl get-default multi-user.target [root@linuxnix ~]#
The multi-user.target corresponds to run level 3 according to the sysVinit system. We can verify the same by executing the runlevel command as shown below:
[root@linuxnix ~]# runlevel N 3
As expected, the result is run level 3.
To change the default run level in the system, we use the systemctl command with the set-default sub-command followed by the target name.
[root@linuxnix ~]# systemctl set-default multi-user.target Removed symlink /etc/systemd/system/default.target. Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target. [root@linuxnix ~]#
To change the current run level, we use the systemctl command with the isolate followed by the target name.
For example, to gracefully restart the system, we use the below command:
[root@linuxnix ~]# systemctl isolate reboot.target Connection to 192.168.188.131 closed by remote host.
The above command would have the same effect as that of executing “init 6” on an operating system controlled by sysVinit.
Systemd Service units
Service units represent service scripts in systemd. The systemctl command unifies the functionality provided by the service and chkconfig commands into a single utility. We use systemctl to enable/disable services on boot and also to manually start, stop, restart or reload services.
To enable a service type:
systemctl enable <service name>
Let’s demonstrate the command on the crond service.
[root@linuxnix ~]# systemctl enable crond
To disable a service type:
systemctl disable <service name>
Let’s demonstrate the command on the crond service.
[root@linuxnix ~]# systemctl disable crond Removed symlink /etc/systemd/system/multi-user.target.wants/crond.service.
Disabling the service removed the symbolic link which ensured that the service would be started when the system transitioned to the multi-user target. Enabling the service will reinstate the symbolic link.
[root@linuxnix ~]# systemctl enable crond Created symlink from /etc/systemd/system/multi-user.target.wants/crond.service to /usr/lib/systemd/system/crond.service.
To stop a service type:
systemctl stop <service name>
To start a service type:
systemctl start <service name>
We can also use the systemctl status command to view the current status of a service. Let’s demonstrate this with the crond service.
[root@linuxnix ~]# systemctl status crond ● crond.service - Command Scheduler Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2018-01-19 04:38:35 IST; 4s ago Main PID: 2080 (crond) CGroup: /system.slice/crond.service └─2080 /usr/sbin/crond -n Jan 19 04:38:35 linuxnix crond: (CRON) INFO (RANDOM_DELAY will be scaled with factor 71% if used.) Jan 19 04:38:35 linuxnix systemd: Started Command Scheduler. Jan 19 04:38:35 linuxnix crond: (CRON) INFO (running with inotify support) Jan 19 04:38:35 linuxnix systemd: Starting Command Scheduler... Jan 19 04:38:35 linuxnix crond: (CRON) INFO (@reboot jobs will be run at computer's startup.)
Along with the systemctl status command, we can use the systemctl show command to view some attributes of a service. We’ll demonstrate by using it on the sshd service.
[root@linuxnix ~]# systemctl show sshd Type=forking Restart=on-failure PIDFile=/var/run/sshd.pid NotifyAccess=none RestartUSec=42s TimeoutStartUSec=1min 30s TimeoutStopUSec=1min 30s WatchdogUSec=0 WatchdogTimestampMonotonic=0 StartLimitInterval=10000000 -------output truncated for brevity
Notice that I don’t need to write crond.service in order for the systemctl commands to work. This is because when we use the systemctl commands with the enable/disable/stop/start/status sub-commands, it’s impplied that we are executing the command on a service unit. The scripts corresponding to the service units are located in the /lib/systemd/system directory. These scripts are added by the package manager when we are installing the applications that provide a particular service. We can make changes to the running system through modification of the /etc/systemd/system directory contents. When we modified the default target on our system, a soft link was created in that location.
The systemd ecosystem of *ctl commands
Along with the essential systemctl tool to manage target and service units, systemd provides a coupld of other useful utilities which we will talk about briefly now.
The timedatecl command
This command provides a useful interface for changing the date and time zone information for a system.
[root@linuxnix ~]# timedatectl Local time: Fri 2018-01-19 03:56:51 IST Universal time: Thu 2018-01-18 22:26:51 UTC RTC time: Thu 2018-01-18 22:26:51 Time zone: Asia/Kolkata (IST, +0530) NTP enabled: no NTP synchronized: no RTC in local TZ: no DST active: n/a [root@linuxnix ~]#
The hostnamectl command
This command allows us to persistently change the hostname of a system without having to edit any files.
[root@linuxnix ~]# hostnamectl Static hostname: linuxnix Icon name: computer-vm Chassis: vm Machine ID: bca7534af004465fa35d176e2a1018c7 Boot ID: 28e151b4f42748eeba4f9575ab136743 Virtualization: vmware Operating System: CentOS Linux 7 (Core) CPE OS Name: cpe:/o:centos:centos:7 Kernel: Linux 3.10.0-693.11.6.el7.x86_64 Architecture: x86-64 [root@linuxnix ~]#
The localectl command
This command allows us to change the system locale settings.
[root@linuxnix ~]# localectl System Locale: LANG=en_US.UTF-8 VC Keymap: us X11 Layout: us
The loginctl command
loginctl may be used to introspect and control the state of the systemd login manager systemd-logind.service.
[root@linuxnix ~]# loginctl SESSION UID USER SEAT 2 0 root 3 0 root 2 sessions listed.
The journalctl command
It is used to query the contents of the systemd(1) journal as written by systemd-journald.service. Journalctl is a powerful tool for doing just about everything you can think of with log files. Because journald writes logs as a binary file and you need journalctl to interact with those logs. Here’s a quick snippet of the journalctl command executed without any arguments.
[root@linuxnix ~]# journalctl -- Logs begin at Fri 2018-01-19 03:38:26 IST, end at Fri 2018-01-19 03:57:07 IST. -- Jan 19 03:38:26 linuxnix systemd-journal: Runtime journal is using 8.0M (max allowed 91.1M, trying to leave 136.6M free of 903.1M a Jan 19 03:38:26 linuxnix kernel: Initializing cgroup subsys cpuset Jan 19 03:38:26 linuxnix kernel: Initializing cgroup subsys cpu Jan 19 03:38:26 linuxnix kernel: Initializing cgroup subsys cpuacct Jan 19 03:38:26 linuxnix kernel: Linux version 3.10.0-693.11.6.el7.x86_64 (firstname.lastname@example.org) (gcc version 4.8.5 20150623 Jan 19 03:38:26 linuxnix kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-693.11.6.el7.x86_64 root=/dev/mapper/cl-root ro crashkernel=a Jan 19 03:38:26 linuxnix kernel: Disabled fast string operations Jan 19 03:38:26 linuxnix kernel: e820: BIOS-provided physical RAM map:
In this article, we discussed the different aspects of systemd and how it’s different from sysVinit in providing a more transparent and simplified approach towards managing services on the system. We hope that you’ve found the explanation on systemd useful and we look forward towards your feedback and suggestions.
Latest posts by Sahil Suri (see all)
- Enabling passwordless authentication for chrooted sftp users in Linux - August 15, 2018
- GitHub and git integration: using ssh instead of https - August 14, 2018
- How to use bash aliases over ssh in Linux - August 9, 2018
- Troubleshooting chrooted sftp account setup in Linux - August 8, 2018
- Using ShellCheck to write better shell scripts - August 6, 2018