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/--forkoption to unshare.unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"When I run this, and
kill -9the 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 -9the bash PID, then thewatchgets 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
--forknecessary to get the desired effect? Why isunshareusingexec()without fork not enough? - Is there a workaround for this? I would prefer if I could conveniently send
kill -9to the PID created by startingunshareto kill everything below it. But when I use--fork, killing the pid returned when I startedunsharewill, well, simply killunshareand havebashreparented to PID 1, becauseunshareis 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. – nh2 Sep 19 '17 at 15:19