3

The actual server process is spawned by a shell script

I am trying to write an init script for djb daemontools within Entware on a router running busybox 1.24 (ash shell). The daemontools way to start itself, is using the svscanboot shell script. Note that I have removed readproctitle from svscanboot.

PATH=/opt/sbin:/opt/bin:/bin:/sbin:/usr/bin:/usr/sbin
exec </dev/null
exec >/dev/null
exec 2>/dev/null
/opt/bin/svc -dx /opt/service/* /opt/service/*/log
env - PATH=$PATH svscan /opt/service 2>&1

The parent shell script process spawns a (descendant) svscan child process, which is the actual running server process.

The TERM signal is received by the shell process

Running svscanboot & (in background) and killing the parent process results in the child process running:

# ps l | grep svscan
S     0  1526     1  1560   404 0:0   22:57 00:00:00 {svscanboot} /bin/sh /opt/bin/svscanboot
S     0  1528  1526   976   252 0:0   22:57 00:00:00 svscan /opt/service
# killall svscanboot

But svscan will continue to run

# ps l | grep svscan
S     0  1528     1   976   252 0:0   22:57 00:00:00 svscan /opt/service

Executing svscanboot (in foreground) and killing the parent process also results in the child process still running:

# ps l | grep svscan
S     0   676   671  1560   400 pts1  23:41 00:00:00 {svscanboot} /bin/sh /opt/bin/svscanboot
S     0   678   676   976   252 pts1  23:41 00:00:00 svscan /opt/service
# killall svscanboot
# ps l | grep svscan
S     0   678     1   976   252 pts1  23:41 00:00:00 svscan /opt/service

Busybox is quite limited, killall only has flags -l and -q and ps only has wide, long and show Threads.

And when quitting the foreground version with Ctrl + C both parent and child processes are terminated.

How to stop both the parent and the child process in this case, preferably using killall and eventually by modifying svscanboot?

Pro Backup
  • 4,924
  • 1
    Running svscan* processes forever is normal behaviour. Do you have any special reason to stop them? – Ipor Sircer Nov 29 '16 at 09:47
  • @IporSircer Most init scripts have actions like: start, stop, restart, kill, etcetera. For the sake of having an init script that works the way most users do expect it to, I do want to stop deamontools (svscan*). – Pro Backup Nov 29 '16 at 12:46
  • 1
    svscan has a similar job like systemd, so it is the recommended way to leave it run forever. If you don't wanna use its features, then remove it completely and start your services directly from initscripts. – Ipor Sircer Nov 29 '16 at 13:09

1 Answers1

0

To exec

After I read the question and answer of Meaning of "exec env COMMAND " a possible solution could be to prefix the env … with an exec. That will prevent the spawning of a child process. However ps outputs {svscanboot} /bin/sh /opt/bin/svscanboot. That name will change to svscan /opt/service after the exec.

Or to trap signals

The other way to handle this is via a trap that propagates the signals to the child process. Like Forward SIGTERM to child in Bash or the in more detail explained http://veithen.github.io/2014/11/16/sigterm-propagation.html The issue with this solution route is that SIGKILL a.k.a. signal number -9 can not be trapped.

Exec with a name change workaround

For not being able to trap the KILL signal, I will choose for the exec route:

…
exec env - PATH=$PATH svscan /opt/service 2>&1

This does still make things complicated to stop/kill/reconfigure "svscanboot" within the Entware init system because of the changed name. That exec process name change will need a workaround.

Mimic svscanboot

The entware-daemontools-init-script can be changed to mimic svscanboot, like:

ENABLED=yes
#PRECMD="exec </dev/null;exec >/dev/null;exec 2>/dev/null;/opt/bin/svc -dx /opt/service/* /opt/service/*/log"
PROCS="svscan"
ARGS="/opt/service 2>&1"
PATH=/opt/sbin:/opt/bin:/sbin:/bin:/usr/sbin:/usr/bin
PREARGS="env - PATH=$PATH"
DESC="daemontools"

The commented PRECMD makes that svscan will not be started.

Pro Backup
  • 4,924