Skip to content

Introduction

Systemd is the new version of initd, and will be the main way of starting up services on newer linuces, at least debian, ubuntu and centos/redhat.

/etc/systemd/user[.conf]

This is convenient for daemons and other services that are commonly run for a single user. So it is not so much for system owned services that run system-wide but services that run for one user only !

/etc/systemd/system

Here are symlinks to scripts in /usr/lib/systemd, if a package is systemd ready that is. Some are and some are not, and some have a script for both:

list clamav
yum list | grep clamav-server

Will list :

output
1
2
3
clamav-server.x86_64                       0.98.7-1.el7                epel      
clamav-server-systemd.noarch               0.98.7-1.el7                epel      
clamav-server-sysvinit.noarch              0.98.7-1.el7                epel     

So you may choose which one to use, let's install the systemd version and view it :

install
yum install clamav-server-systemd

However it's not called the clamav, or clamav-server service, but clamd (sigh!). You can find that by listing the unit files , perhaps through a well aimed grep ? :

list
systemctl list-unit-files | grep clam

You will find they named it :

output
clamd@.service                              static  

There are three possible states for a service: enabled or disabled, and static. Enabled means it has a symlink in a .wants directory. Disabled means it does not. Static means the service is missing the [Install] section in its init script, so you cannot enable or disable it. Static services are usually dependencies of other services, and are controlled automatically.

own systemd script

If we just make a program doing not so much :

test program
#include [visit](stdio.h) 
#include [visit](syslog.h)  
main() {         
    int x=0;          
    while (1) {                 
        sleep(1);                 
        printf("Console %dn", x++);                 
        syslog(LOG_NOTICE, "K. loggert %d", x);         
    } 
}

It will end up as ~/a.out for instance : /home/kees/a.out

Just creating a file called /etc/systemd/system/kees.service will already mention you in : the systemctl list-unit-files :

/etc/systemd/system/kees.service
kees.service                                masked

Though it says masked, because it is empty, or if you just put "error" in it :

invalid
kees.service                                invalid 

Since it won't parse, it will change when you fill it with these contents :

/etc/systemd/system/kees.service
1
2
3
4
5
[Unit]
Description=Kees test service  

[Service] 
ExecStart=/home/kees/projects/a.out  
list-unit-files
kees.service                                static  

So it becomes a static routine service, but if you make it 'wanted by' the multi-user.target :

wanted by
1
2
3
4
5
6
7
8
[Unit]
Description=Kees test service  

[Service] 
ExecStart=/home/kees/projects/a.out  

[Install] 
WantedBy=multi-user.target

We get a line like :

list-unit-files
kees.service                                disabled

So let's enable it :

enable the service
systemctl enable kees.service
ln -s '/etc/systemd/system/kees.service' '/etc/systemd/system/multi-user.target.wants/kees.service' 

Yep, we get :

list-unit-files
kees.service                                enabled

Now watch you system log, on centos

/var/log/messages
tail -f /var/log/messages 

And start your service :

output
systemctl start kees :


May 21 08:17:32 localhost systemd: Starting Kees test service... 
May 21 08:17:32 localhost systemd: Started Kees test service. 
May 21 08:17:33 localhost a.out: K. loggert 1 
May 21 08:17:34 localhost a.out: K. loggert 2 
May 21 08:17:35 localhost a.out: K. loggert 3 
May 21 08:17:36 localhost a.out: K. loggert 4 
May 21 08:17:37 localhost a.out: K. loggert 5 
May 21 08:17:38 localhost a.out: K. loggert 6 
May 21 08:17:39 localhost a.out: K. loggert 7 
May 21 08:17:40 localhost a.out: K. loggert 8 
May 21 08:17:41 localhost a.out: K. loggert 9

Yep, and stop and start, you now it will start at 1 again.

If you ps -elf you will see that a.out runs as root :

ps -elf
4 S root     16015     1  0  80   0 -  1074 hrtime 08:19 ?        00:00:00 /home/kees/projects/a.out

To change this augment kees.service, do a systemctl daemon-reload whenever you change the scripts. If you don't systemctl will tell you :)

kees.service
1
2
3
4
5
6
7
8
9
[Unit]
Description=Kees test service  

[Service] 
ExecStart=/home/kees/projects/a.out  
User=kees

[Install] 
WantedBy=multi-user.target

This will run your service as kees, an alternative is using a system --user session, but as you can imagine, your service will start only when you login where we want it at boot time.

restart crashed

If we now kill process id 16015 :

force crash
kill -9 16015

The log will say :

log
May 21 08:51:04 localhost systemd: kees.service: main process exited, code=killed, status=9/KILL May 21 08:51:04 localhost systemd: Unit kees.service entered failed state.

And the counting stops, but we can alter that by adding :

restart on-abort
[Unit]
Description=Kees test service  

[Service] 
ExecStart=/home/kees/projects/a.out  
User=kees
Restart=on-abort

[Install] 
WantedBy=multi-user.target

Now startup the service again :

restart
1
2
3
4
systemctl daemon-reload
systemctl stop kees
systemctl start kees
systemctl status kees

That last one is a nice on, show the last log messages, as well as the pid we want to kill :

kill
kill -SEGV [visit](pid)

And you will see the service crash, stop (yes..) and start. JUST what i need. Now if you kill i with a TERM signal (that's a kill without signal argument) it will just stop, because this was an intended stop. A SEGV, or KILL (-9) was not.

beware !!

These commands just work without a warning AS USER !!

beware these work as normal user
1
2
3
systemctl reboot
systemctl poweroff
systemctl halt

Why is not clear to me.

Debugging

Systemd does not have text log files , and some more effort is needed to debug problems. I got the information from 'this page visit>'_ but only discuss what i needed so ...

Better diagnostics

Whenever a service start fails systemd gives you a number of advises :

advise to run : 'systemctl daemon-reload' .. IF it says this, .. DO IT ! and retry the startup # systemctl status holodeck.service, this just gives you very few information mostly # journalctl -xe, this will give more text but it seems not more information

But mostly none of these commands will help much. The base scripts still write to syslog so your best guess is to look in /var/log/messages for clues.

If you have a problem during boot-up you can run journalctl with the -b option, so it will show the complete boot process steps :

logging
journalctl -b