What Is Start-Stop-Daemon in Linux Scripting

What is start-stop-daemon in linux scripting?

It is a program to manage the start and stop of system level background processes (daemons). You use it by passing in parameters (such as the pid file to create/check) and command arguments for the process you want to launch.

Then, you do one of two things:

start-stop-daemon -S [other arguments] something

start something, if something wasn't already running. If it was running, do nothing.

start-stop-daemon -K [other arguments] something

stop something. If something wasn't running, do nothing.

The man page provides more information on the various arguments. Typically a template is provided in /etc/init.d/ which has other commands for the init process that controls the running of background processes.


What does it mean?

start-stop-daemon --start --background -m --oknodo
--pidfile ${PIDFILE} --exec ${DAEMON} -- ${TARGETDIR}

  • --background = launch as a background process
  • -m = make a PID file. This is used when your process doesn't create its own PID file, and is used with --background
  • --oknodo = return 0, not 1 if no actions are taken by the daemon
  • --pidfile ${PIDFILE} = check whether the PID file has been created or not
  • --exec = make sure the processes are instances of this executable (in your case, DAEMON)

start-stop-daemon with --background vs running using & option

If you use start-stop-daemon --background then start-stop-daemon will fork off a process to run in the background and then start-stop-daemon immediately exits. Among other things this means you can check the exit status of start-stop-daemon.

If you use start-stop-daemon & then the shell forks off a background process and runs start-stop-daemon in it. You won't be able to check its exit status as it won't actually exit (until the thing it runs exits).

In most cases start-stop-daemon --background is a better choice.

What is the proper way to terminate a script using start-stop-daemon?

The issue was with the --exec that I used for matching the process name. As per the start-stop-daemon documentation :

   -x, --exec executable
Check for processes that are instances of this executable
(according to /proc/pid/exe).

In my case as my script is Perl script, /proc/pid/exe is symlinked to /usr/bin/perl; therefore the exec couldnt match the process name. I removed the exec so that it matches only the PID. Now I can properly stop my process.

start-stop-daemon run with external script condition

Inside the /etc/init.d directory is the file with the service we want to modify, for example the emqx service. We will have something like this:

do_start()
{
start-stop-daemon --start \
--name emqx \
--user emqx \
--exec /usr/local/bin/checkconditionandrun.sh emqx -- start \
|| return 2
}

case "$1" in
start)
log_daemon_msg "Starting emqx"
do_start
case "$?" in
0|1) log_end_msg 0 ;;
2) log_end_msg 1
exit 1
;;
esac
;;
stop)
log_daemon_msg "Stopping emqx"
do_stop
case "$?" in
0|1) log_end_msg 0 ;;
2) log_end_msg 1
exit 1
;;
esac
;;

The key to all this is in two things:

  1. In the do_start() function, the start-stop-daemon --start command should not directly call the "emqx start" command. A script must be called to verify what we need to verify and then that script will or will not execute the command passed as parameter.

  2. Now if we want our service to restart automatically if it has failed, as would be done through a .service with the inputs Restart=always and RestartSec=10, we must know the following:

    a) systemd supports legacy scripts /etc/init.d this way, when systemd loads service definitions, systemd-sysv-generator autogenerates .service files on the fly from the scripts in /etc/init.d.

    b) We can add configuration to an auto-generated service by adding "drop-in" files called "restart.conf" to a folder with the following name: /etc/systemd/system/servicename.service.d/

As explained above and assuming that our service is called "emqx", we can create a file in the following folder:

/etc/systemd/system/emqx.service.d/restart.conf

with the following content:

[Service]
Restart=always
RestartSec=10

In this way we achieve that a service contained in init.d can control both its startup and its subsequent reboot retry by systemd itself.

For more information about it:

https://singlebrook.com/2017/10/23/auto-restart-crashed-service-systemd/

https://www.freedesktop.org/software/systemd/man/systemd.service.html

https://www.digitalocean.com/community/tutorial_series/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot

start-stop-daemon starting multiple processes

The man page of start-stop-daemon contains a special warning on the usage of the --exec option with scripts.

-x, --exec executable

Check for processes that are instances of this executable. The executable
argument should be an absolute pathname. Note: this might not work as
intended with interpreted scripts
, as the executable will point to the
interpreter.

When you run a script, the process that is actually launched is the interpreter noted in the shebang line of the script. This confuses the start-stop-daemon utility.

BTW, you can use the -t option to debug that kind of issues with start-stop-daemon.

Linux start-stop-daemon directory error calling shell/python script

Try calling cd using an absolute path, for example /home/alexjg/ instead of ~/; the reason it was broken before is that in your example you're using sudo which keeps the home directory of the user running it. However when you're calling the bash script from init it will use root's home directory instead which doesn't contain test.py.

The file is created because the redirection is still succeeding; however because starting Python failed there was no output.

Why start-stop-daemon needs privileges?

start-stop-daemon can also set the user ID for the daemon process.

That said, you'd generally use start-stop-daemon from a script in /etc/rc.d, which is run with root privileges either from the init system that is being used this week (sysvinit, upstart, systemd, ...) and/or from the service(8) command.

So, if a user should be able to start/stop the service (which is a rather uncommon scenario), you'd use the sudoers file to grant them access to the service command, with the name of your service as a mandatory first argument.

In general though, write your service so it can be simply started at boot or during installation, and used by users as long as it's running. If the user needs to be able to start and stop instances of the service, then your daemon is in the business of managing instances, and the instance manager should be continually running, and users then contact this service via a socket (so users don't need sudo at all, which would make the lives of many administrators who don't install sudo quite a bit easier).

Not able to stop init script using start-stop-daemon

Regarding your comment, if you're willing to extend the shellscript you are running, you can use a pidfile. In practice, maybe you want to make it an option to your script, but as an example, this line would be sufficient:

echo $$ >/var/run/dev-myapp.sh.pid

Then, use these matching parameters for start-stop-daemon, if necessary replacing /bin/bash with whatever shell executes your script:

-p /var/run/dev-myapp.sh.pid -x /bin/bash

(To clarify: The process name of the script is that of the script interpreter, in your case, the shell)



Related Topics



Leave a reply



Submit