From this answer we have learned that you can implement reliable killing of entire process subtrees with Linux PID namespaces via unshare -p
.
Here is problem with it that I don't understand:
It only works when I use the
-f
/--fork
option to unshare.unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"
When I run this, and
kill -9
the PID of thatbash
, then watch, sleep etc are all dead, as I desire.But when I use it without
-f
:unshare -p -- bash -c "watch /bin/sleep 10000 && echo hi"
and
kill -9
the bash PID, then thewatch
gets reparented to PID 1 (on my Ubuntu that's systemd), so I don't have the desired effect of killing all children.
Questions:
- Why is
--fork
necessary to get the desired effect? Why isunshare
usingexec()
without fork not enough? - Is there a workaround for this? I would prefer if I could conveniently send
kill -9
to the PID created by startingunshare
to kill everything below it. But when I use--fork
, killing the pid returned when I startedunshare
will, well, simply killunshare
and havebash
reparented to PID 1, becauseunshare
is not in my PID namespace.
Note, the && echo hi
is needed because if you give only one command to bash -c
, it will exec()
it and thus the bash process is gone (replaced) and you can't kill its PID.
-n
(unshare(CLONE_NEWPID)
) only come into acction for the first child process forked. I think that would explain my first question, but the question about what the best workaround is still stands.