Converting /etc/init.d service to systemd
I am in the process of converting an existing /etc/init.d service to systemd. It seemed to be working but I have encountered a strange issue. The systemd service will happily start with the command "systemctl start service_name" and stop with "systemctl stop service_name" but it doesn't seem to be stopping cleanly. The underlying application checks if it is already running and terminates immediately if this is the case. This is what is happening.
Here is an equivalent snippet from the old /etc/init.d script:
kill_process() { pkill -SIGINT service_name sleep 1 if [ -n "$(pgrep service_name)" ]; then pkill -SIGTERM service_name sleep 1 fi if [ -n "$(pgrep service_name)" ]; then pkill -SIGKILL service_name sleep 1 fi if [ -z "$(pgrep service_name)" ]; then rm -f /var/lock/subsys/service_name fi
}
start() { action $"Starting Service: " /sbin/service_name
}
stop() { action $"Stopping Service: " kill_process
}
restart() { stop start
}And this is my initial attempt at the systemd equivelent:
[Unit]
Description=Service Name
[Service]
ExecStart=/sbin/service_name
[Install]
WantedBy=multi-user.targetMy understanding was that the systemd service would handle the process termination using SIGTERM but I have experimented with other values for KillSignal and ExecStop. However, I have yet to understand this difference in the termination behaviour. Furthermore, if I kill the application manually using SIGINT it doesn't kill the service cleanly either. I am wondering if /etc/init.d is doing something else behind the scenes.
Any suggestions appreciated.
71 Answer
I just wanted to draw a line under this post in case it is of interest to anyone else.
The C application that runs as part of the service was previously using fork() if getppid() was not already 1 (i.e. not already forked). It seems that when the application is run by systemd it already has a parent PID of 1. Our application did not have explicit SIGTERM handling before but did shut down gracefully when reacting to SIGINT in the context of /etc/init.d. I have added a specific SIGTERM handler and the service now behaves as expected.