Shu*_*eng 4 linux process debian namespace containers
我假设nsenter,它作为 的子进程运行bash,利用setns系统调用加入现有的命名空间,然后使用exec.
但是,如果在'ing之前nsenter已经调用了,为什么还需要系统调用来确保子进程也将在输入的命名空间中?setnsexecfork
setns(2)
The setns(2) system call allows the calling process to join an
existing namespace. The namespace to join is specified via a
file descriptor that refers to one of the /proc/[pid]/ns files
described below.
Run Code Online (Sandbox Code Playgroud)
...
-F, --no-fork
Do not fork before exec'ing the specified program. By
default, when entering a PID namespace, nsenter calls fork
before calling exec so that any children will also be in the
newly entered PID namespace.
Run Code Online (Sandbox Code Playgroud)
解释在“PID命名空间”部分给出man nsenter:
子进程将有一组 PID 来处理与进程分开的映射
nsenter。nsenter如果更改 PID 命名空间,默认情况下将分叉,以便新程序及其子程序共享相同的 PID 命名空间并且彼此可见。如果--no-fork使用,新程序将被执行而不会分叉。
(手册在那里有些混乱;我已经清理了上面引用的部分,下一个版本util-linux将包含一个修复程序。)
输入 PID 命名空间不会将当前进程移动到该命名空间,它只会导致在该命名空间中创建新的子进程。因此,当前进程(调用 的进程setns)对新命名空间中的子进程不可见。为避免这种情况,nsenter进入新的命名空间,然后 fork,在新的命名空间中产生一个 new nsenter,然后调用exec; 结果,被执行的程序位于新的命名空间中。
另请参阅 PID 命名空间的描述man setns:
如果fd指的是 PID 命名空间,语义与其他命名空间类型有些不同:将调用线程与 PID 命名空间重新关联只会更改随后创建的调用者子进程的 PID 命名空间;它不会改变调用者本身的 PID 命名空间。
您将在/proc命名空间条目中看到这一点:/proc/.../ns有两个 PID 条目,pid(进程的命名空间)和pid_for_children(用于新子进程的命名空间)。
(exec本身不会创建新进程。)