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.
- prepare the processes to run:
cat > dumb.sh <<EOF
#!/bin/bash
setsid sleep 1001 &
exec sleep 10001
EOF
chmod a+x dumb.sh
- 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
- 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
- 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.