nh2*_*nh2 7 process kill namespace unshare
从这个答案中我们了解到,您可以通过 Linux PID 命名空间实现对整个进程子树的可靠终止unshare -p。
这是我不明白的问题:
仅当我使用-f/--fork选项取消共享时它才有效。
unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"
Run Code Online (Sandbox Code Playgroud)
当我运行这个时,kill -9那个的PID bash,然后观看,睡眠等都死了,正如我所希望的那样。
但是当我使用它时没有-f:
unshare -p -- bash -c "watch /bin/sleep 10000 && echo hi"
Run Code Online (Sandbox Code Playgroud)
和kill -9bash PID,然后将其watch重新设置为PID 1(在我的Ubuntu上是systemd),所以我没有达到杀死所有孩子的预期效果。
问题:
--fork必须要达到预期的效果?为什么不unshare使用exec()fork 还不够?kill -9而创建的 PID 。unshare但是当我使用 时--fork,杀死我开始时返回的 pidunshare将简单地杀死unshare并bash重新设置为 PID 1,因为unshare它不在我的 PID 命名空间中。请注意,&& echo hi是必需的,因为如果您只向 发出一个命令bash -c,它就会执行exec()此操作,因此 bash 进程会消失(被替换),并且您无法杀死其 PID。
正如这个有用的答案中所描述的-n(unshare(CLONE_NEWPID)仅对分叉的第一个子进程起作用。
特别是,man 2 unshare说CLONE_NEWPID:
取消共享 PID 命名空间,以便调用进程为其子进程拥有一个新的 PID 命名空间,该命名空间不与任何先前存在的进程共享。
调用进程不会移动到新的命名空间中。
调用进程创建的第一个子进程
init(1)将具有进程 ID 1,并将承担新命名空间中的角色。
unshare以使查杀工作可靠自从提出我的问题以来,在过去的几个小时里,我编写了一个补丁util-linux(此处拉取请求),--kill-child为unshare.
编辑:现在已作为 util-linux 的一部分合并并发布v2.32。
你可以这样使用它:
unshare -fp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"
Run Code Online (Sandbox Code Playgroud)
并且终止unshare将按预期撕毁整个进程树。
root如果您的内核通过传递标志root启用了用户命名空间 ( ) ,您甚至可以在没有特权的情况下使用它:CONFIG_USER_NS=y-U
unshare -Ufp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"
Run Code Online (Sandbox Code Playgroud)