Linux為什麼
為什麼 nsenter
需要在 exec
之前呼叫 fork
以確保任何孩子也將在新進入的 PID 命名空間中?
我假設
nsenter
作為 的子程序執行的bash
,利用setns
系統呼叫加入現有的命名空間,然後使用 執行指定的程序exec
。但是,如果在 ‘ing之前
nsenter
已經呼叫過,為什麼需要係統呼叫來確保子程序也將在輸入的命名空間中?setns``exec``fork
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.
... -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.
解釋在“PID 命名空間”部分給出
man nsenter
:子程序將有一組 PID 來處理與程序分開的映射
nsenter
。nsenter
如果更改 PID 命名空間,將預設分叉,以便新程序及其子程序共享相同的 PID 命名空間並且彼此可見。如果--no-fork
使用,新程序將在不分叉的情況下執行。(手冊有些混亂;我已經清理了上面引用的部分,下一個版本
util-linux
將包含一個修復。)輸入 PID 命名空間不會將目前程序移動到該命名空間,它只會導致在該命名空間中創建新的子程序。因此,目前程序(呼叫 的程序
setns
)對新命名空間中的子程序不可見。為了避免這種情況,nsenter
進入新的命名空間,然後分叉,這會在新nsenter
的命名空間中產生一個新的,然後呼叫exec
; 結果,被執行的程序位於新的命名空間中。另請參閱 PID 命名空間的描述
man setns
:如果fd引用一個 PID 命名空間,其語義與其他命名空間類型有些不同:將呼叫執行緒與 PID 命名空間重新關聯只會更改呼叫者後續創建的子程序的 PID 命名空間;它不會更改呼叫者本身的 PID 命名空間。
您將在命名空間條目中看到這一點
/proc
:/proc/.../ns
有兩個 PID 條目,pid
(程序的命名空間)和pid_for_children
(用於新子程序的命名空間)。(
exec
它本身不會創建新程序。)