Published on: December 17, 2018 by Daniel Wren
Init and systemd are both system and service managers associated with Linux systems. They are responsible for booting the machine once the kernel is loaded, and their tasks range from mounting the original file system, identifying the runlevel or target and loading the operating system accordingly along with activating the services associated with that runlevel and finally displaying the login screen. Init was present in Linux distributions like Redhat 6, CentOS 6 but it got replaced with Systemd in linux distros like Redhat 7, CentOS 7 ,Ubuntu 16.04 etc.
To appreciate the importance of service managers in Linux an overall idea of the Linux booting process is required which is covered in the following section:
The process of booting begins with POST (Power On Self Test) where the hardware components of the system are checked for any kind of defects. If any component failure or wrong connection is detected, the booting will fail. Once this stage is cleared, next the firmware is detected which will be BIOS or UEFI. Once the firmware is detected the boot device is selected from boot priority, which is harddisk normally.
The MBR (Master Boot Record) is then read. MBR consists of 512 bytes which are divided as 446 bytes for bootloader, 64 bytes for mounting table information and 2 flag bytes, meant for error checking and correcting purposes. The bootloader (GRUB 2) contains instructions to load the kernel image (vmlinuz). When the bootloader is loaded we get an interface where we can select the kernel version out of the available ones. The kernel image and the compressed file system image is loaded, then the latter is extracted to obtain a temporary file system. It is required to access the driver software which is essential to detect the original file system and mount it. The initrd and initramfs are two different methods by which the temporary file system is made available to the kernel.
Initrd (Initial ramdisk) was the technique used with earlier linux distros where the compressed image of the entire file system (initrd image) is made available as a special block storage device (/dev/ram) which is then mounted and decompressed. The driver software to access this block storage device is compiled into the kernel. The kernel assumes that the actual file system is mounted and starts /linuxrc which in turn starts /sbin/init. With Initramfs the compressed image is made available as a cpio archive which is unpacked by the kernel using a temporary instance of tempfs which then becomes the root file system. It is followed by executing /init as the first process.
This is the stage where the actual file system is mounted. The OS is booted with the desired runlevel or target. Then the services specific to that runlevel or target are activated and once ready the login screen is displayed. All these activities are taken care of by the service managers in Linux. We will go into the details of the two most popular service managers namely Init and Systemd, in the following section.
Init is the service manager associated with earlier Linux distros. Init stands for Initialization, it is the first process after booting, act as the parent of all other processes and continues till shutdown. It is assigned a PID of 1. Init is a daemon process. A daemon process is one which does not have a controlling terminal.
Once the actual file system is mounted, the runlevel is identified. There are 7 runlevels associated with Init:
0 -> Shutdown or halt
1 -> Single user mode (root user mode used for troubleshooting)
2 -> Multiuser without network service
3 -> Multiuser with network service
4 -> Undefined
5 -> Graphical mode
6 -> Reboot
Once the runlevel is identified the services corresponding to that runlevel is activated and the login screen is displayed.
The main configuration file is /etc/inittab. The default runlevel is specified here. The scripts required by each runlevel is specified in /etc/rc.d/rc* directory, where * refers to the runlevel. In this directory, one could find a list of kill (K) scripts and start (S) script. The kill scripts are executed followed by start scripts. The order of script execution is specified by means of sequence number on the script. The scripts are saved at /etc/rc.d directory.
Init works based on serial booting principle, so even if the main service fails the sub-services are also checked unnecessarily. Even if the service becomes up before the booting has completed it will not be detected by init. For example, network service is essential for NFS or CIFS to function, so there is no meaning in trying to activate dependant services until the main service is up, but Init will still do it. This is a major disadvantage in terms of booting speed and performance.
If due to some reason Init could not start then, no process will be started and the system will reach a state called Kernal Panic where booting fails. This is also an issue with Init.
Systemd is the most recent service manager used in Linux distros. It has the same tasks as Init but the method adopted to achieve the same is quite different. It is based on parallel booting concept where processes and services are started in parallel. This helps to speed up the booting process as services are started in parallel. In Systemd there are no runlevels involved, instead target unit files come into play. Unit files are configuration files what define any entity in systemd environment, whether it is targets or services involved unit files are present for each and every target or service. There are different types of unit files including services, targets, devices, file system mount points and sockets.
With Systemd once the actual file system is mounted, the default target is identified. The targets in systemd are : poweroff.target, rescue.target, multi-user.target, graphical.target and reboot.target. The names somewhat resemble the runlevel naming. Once the target is identified then the services corresponding to that target is activated. Finally the login screen is displayed.
In Systemd /sbin/init is simlinked to /etc/systemd/system/default.target. The default.target file is empty and is simlinked with the presently chosen target file located at /usr/lib/systemd/system/<target name>.target.
Systemd uses a parallel booting mechanism where services and processes are started in parallel thereby speeding up the booting process. Another advantage is that if the main service fails the dependent services are bypassed and if the main service becomes up before booting is completed then the dependent services are checked and activated.
The dependency services for a target is defined inside its unit file. The dependency unit files are listed with directives “Wants and “Requires”, where the former states that the dependency may be run along with the unit, but the success state of the dependency is not essential for the success of the target and the latter implies that the success state of dependency is essential for the success state of the target. By removing the entry of the dependency service we do not require, from the unit file of service we can prevent it from getting loaded or activated.
In the directory /etc/systemd/system we can find “Wants” directories of different targets having the following format : <target-name>.target.wants . Navigate to the desired target where you want to add the new service. The services considered by that target will be listed there.
To make a new service name named netset.service, open a file with the same name and specify the required services by making use of the “Wants”, “requires”,”Before”, “After” appropriately. For example :
[Unit] Description = making network connection up After = network.target [Service] ExecStart = /root/scripts/conup.sh [Install] WantedBy = multi-user.target where “After” specifies that this service must only be activated after network.service. “ExecStart” specifies the path of the script file to be executed. The actions that must take place must be specified in the script file as a BASH script. “WantedBy” specifies that this service will be wanted by multi-user.target . The service is then enabled so that it is simlinked to that service will be created inside multi-user.wants.target. Now this service will be listed inside the target file and will be available when the corresponding target is used.
Run Level Target Units Description
0 runlevel0.target, poweroff.target Shut down and power off
1 runlevel1.target, rescue.target Set up a rescue shell
2,3,4 runlevel.target, multi- user.target Set up a nongraphical multi-user shell
5 runlevel5.target, graphical.target Set up a graphical multi-user shell
6 runlevel6.target, reboot.target Shut down and reboot the system
Category : Linux