Yelp/dumb-init

trouble in managing subprocess with setsid executed

jschwinger233 opened this issue · 5 comments

as showed in code https://github.com/Yelp/dumb-init/blob/master/dumb-init.c#L66, dumb-init only forward signals to child process group, but there is no guarantee all forked processes are in the same process group.

let me demonstrate it.

  1. prepare the processes to run:
cat > dumb.sh <<EOF
#!/bin/bash
setsid sleep 1001 &
exec sleep 10001
EOF
chmod a+x dumb.sh
  1. prepare a clean env for dumb-init
docker run -it --name dumb-init -v ./dumb.sh:/dumb.sh python:3.7 bash
# inside container
pip install dumb-init
dumb-init /dumb.sh
  1. check
$ ps -ef --forest
root       163     1  0 08:27 ?        00:00:00 dumb-init ./dumb.sh
root       164   163  0 08:27 ?        00:00:00  \_ sleep 10001
root       165   164  0 08:27 ?        00:00:00      \_ sleep 1001
  1. send SIGINT to dumb-init
$ kill -2 163
$ ps -ef --forest
root       165     1  0 08:27 ?        00:00:00 sleep 1001

as displayed the setsid-ed process kept intact.

to my understanding, there's no way to forbid the setsid (or setpgid) invocation, but in my humble opinion could we make the flat management to child processes? that's to say all the children are forked from dumb-init so that no more descendent problem caused, even if the children are off the process group and session, dumb-init still holds their pids and is capable to manage.

I'm not sure this actually matters in practice -- you'd be running dumb-init as pid1 and so the 165 process would get reparented to dumb-init. plus, when dumb-init exits your container is gone.

can you provide a demo where dumb-init is correctly pid1? your example above has bash as your init system

even if the setsid-ed process could be managed properly while dumb-init is of pid 1, the signal is still yet to forward as expect... I don't think the disowned process is able to receive SIGTERM after docker stop

anyway, I'll do more experiment and thank you.

As far as I'm aware there's no way to reliably signal an entire process tree, so the best we can do is either signal the direct child or the process group (dumb-init supports both of those modes).

If you strace pstree for example to see how it works (since we'd need to do something similar), it has to scan /proc to figure out the process tree which is slow, full of race conditions, and OS-specific :(

you are correct about no reliable approach to forward signal to ptree, so as I mentioned before, flat management might be a way to make it better;

however the obstacle is dumb-init has no way to specify multi command as child process respectively; hypothetically we can use it like dumb-init -- 'cmd1' 'cmd2' 'cmd3', and cmd[123] will be the direct child processes of dumt-init, then problem solved.

(I believe a config file of yaml is much better to specify multi commands

As far as I'm aware there's no way to reliably signal an entire process tree, so the best we can do is either signal the direct child or the process group (dumb-init supports both of those modes).

If you strace pstree for example to see how it works (since we'd need to do something similar), it has to scan /proc to figure out the process tree which is slow, full of race conditions, and OS-specific :(

Ah, I see. I think that proposal could work, but I don't think it's something we'd want to adopt for dumb-init -- we're really trying to have a single focus and be as simple as possible (hence the name "dumb"-init 😄).

You might be able to use a tool like runit for this use-case. I don't know much about runit specifically, but my understanding is that it can be used as an init system and can supervise multiple children with a config file, which might satisfy your requirements.