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,686
  • 12
  • 50
  • 82
  • 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,686
  • 12
  • 50
  • 82