Introduction to Initialization systems and creating your first Systemd service

In this post, We will see what is an initialization system and finally we will create a service for one of the popular and modern initialization system ‘Systemd’.

What is an Initialization system?

Init System daemons are the first process spawned by the kernal process when a server boots, which carries major initialization and management of services that are crucial to certain context operations . And also managing services across different runlevels . for example, spawning a getty login shell on startup. There can be custom services too, such as starting ‘ssh’ service on startup.

 Note : Initialization system has process ID = 1  and parent process ID = 0 .

There are many initialization systems available . Few of the popular ones are SysvInit , upstart and systemd.

SysvInit is one of the easy and simplest init system which mainly handles static events such as load all the service once the system boots . This effectively lacks handling dynamic events such as handling Pluggable USB’s , hotplugs , external SSD.  SysvInit initialization system manages different services required based on the default runlevel specified. (default runlevel is runlevel 5 i.e, graphical mode). the services inside the folder /etc/rc.d/rcx.d where x=0,1,2,3,4,5,6  specifies which service scripts has to be run for a particular runlevel on startup .

Note : You can change runlevel of a system using ‘init runlevel’  .

example : ‘init 0’  would effectively halts or shut down the system.

Upstart is another initialization system which was designed to handle dynamic events instead of pre defined sequence of activating services. they use the concept of jobs which effectively initializes and monitors services .

Systemd init system daemons are the recent replacements for other initialization daemons which is complex of them all. Specialty  of this system is that it can start services in parallel. Out of all Systemd manages ‘Units’ .

There are totally 8 type of unit files, out of all we focus mainly on two that is service unit files and target unit files.

service unit files are used to manage different services. And target unit files are a collection of services , which would collectively form run level of a system.

System specific service files reside under ‘/lib/systemd/system’ directory , whereas Custom user service files reside under ‘/etc/systemd/system’ directory.

Main service/target handling commands :

Start a service / target file :  systemctl start unitname.service
or systemctl start unitname.target

ex : systemctl start apache2.service

Stop a service / target file :  systemctl stop unitname.service
or systemctl stop unitname.target

ex :  systemctl stop apache2.service

Status of a service / target file :  systemctl status unitfile.service

ex : systemctl status apache2.service

restart a service unit file :  systemctl restart unitfile.service

ex : systemctl restart apache2.service

enable service on start – up : systemctl enable unitfile.service

ex : systemctl enable ssh.service

disable service on start – up :systemctl disable unitfile.service

ex : systemctl disable ssh.service

Note : .service extension can be omitted and is considered by default.

Now Lets create a custom service unit file and see the required procedure to enable one.

  1. Create a file with extension .service , with the following content.

[Unit]
Description=Trial service

[Service]
Type=oneshot
ExecStart=/bin/sh -c “runtime”
ExecStop=/bin/sh -c “uname -a”
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

 

Above content creates a unit with required unit description , and the attributes of service such as ‘Type ‘ which specifies if the  service is oneshot ,forking , simple, notify or idle . here we have used oneshot which means that it executes some action and exits immediately .This requires another attribute ‘RemainAfterExit’ to be set. ‘ExecStart’ is the attribute which has a process to be executed once this unit is started. ‘ExecStop’ is the attribute which has a process to be executed once this unit is stopped. and finally WantedBy attribute specifies the target file which requires this service for it to initialize.

2. Move the myservice.service unit file to /etc/systemd/system directory . and finally start the service file .

systemctl myservice.service start

Following snaps captures the status of the service once initialized and then stopped.

img (a) : status after starting  the  service, we can see in the systemctl logs from journal logs that the command defined in the ExecStart attribute executed successfully and the output is displayed in the logs.

 

img (b) : status after stopping the  service, we can see in the systemctl logs from journal logs that the command defined in the ExecStop attribute executed successfully and the output is displayed in the logs.

We have successfully created a simple service file and initialized it , now if we want to enable it to start at boot , we can use enable command as described above. this effectively creates a symbolic link to multiuser.target.wants directory with the same service name .

Note : we can also make use other attributes such as ExecStartPre , ExecStopPre etc.

Detailed documentation can be found at  systemd official website :  https://www.freedesktop.org/wiki/Software/systemd/