Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Systemd + Sys V init.d script: start works, but stop does not

I'm pretty new to writing systemd compatible init scripts. I've tried the following example:

#!/bin/sh
#
### BEGIN INIT INFO
# Provides:          test
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Test.
# Description:       Test. 
### END INIT INFO
#

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

case "$1" in

  stop)
    log_failure_msg "Stop!"
    exit 1
    ;;

  start)
    log_failure_msg "Start!"
    exit 1
    ;;

  restart)
    log_failure_msg "Restart!"
    exit 1
    ;;

  status)
    log_failure_msg "Status!"
    exit 1
    ;;

  *)
    echo "Usage: $SELF start|stop|restart|status"
    exit 1
    ;;
esac

# Some success paths end up returning non-zero, so exit 0 explicitly. See bug #739846.
exit 0

So far, so good. Now, I install the init script like so:

update-rc.d test defaults
update-rc.d test enable

Again, so far, so good. I've setup this init script specifically to fail (I had to do so during my testing to confirm the issue I was having.)

If I run /etc/init.d/test start, it fails as expected, and I can see the error message in my log.

If, however, I run /etc/init.d/test stop, I get nothing in my log, and the script returns successfully.

It seems like systemd is doing some kind of black magic behind the scenes and is hijacking stop somehow, but I can't figure out how, and I've been Googling around forever without success. Can anyone help me to understand why passing stop to my init script doesn't execute the corresponding code in my case block?

As a side note, the status option also doesn't work (systemd just outputs its own status info.)

I'm attempting to run this on Ubuntu 16.04. Thank you!

like image 332
Crankycyclops Avatar asked Apr 05 '26 21:04

Crankycyclops


1 Answers

You'll notice the top of your script loads /lib/lsb/init-functions. You can read the code in there and the related code in /lib/lsb/init-functions.d to understand the related code you are pulling in.

A summary is that your script likely being converted to a systemd .service in the background and is subject to a whole host of documented incompatibilities with systemd

There is inherit extra complexity and potential problems when you ask systemd to emulate and support the file formats used by the legacy Upstart and sysVinit init systems.

Since you are writing new init script from scratch, consider writing a systemd .service file directly, removing all the additional complexity of involving additional init systems.

A minimal .service file to go in /etc/systemd/system/ could look like:

[Unit]
Description=Foo

[Service]
ExecStart=/usr/sbin/foo-daemon

[Install]
WantedBy=multi-user.target

More details in man systemd.service. Some additional learning now will save you some debugging later!

like image 192
Mark Stosberg Avatar answered Apr 10 '26 02:04

Mark Stosberg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!