すべての子が新しく入力されたPID名前空間にあるようにするために、「nsenter」が「exec」の前に「fork」を呼び出す必要があるのはなぜですか?

すべての子が新しく入力されたPID名前空間にあるようにするために、「nsenter」が「exec」の前に「fork」を呼び出す必要があるのはなぜですか?

nsenter私はそれが子プロセスとして実行され、システムコールをbash使用してsetns既存の名前空間に参加し、指定されたプログラムを実行するために使用すると仮定しますexec

しかし、nsenter'ing'setnsの前にすでに呼び出されている場合、子プロセスも入力名前空間にあることを確認するためにシステムコールが必要なのはexecなぜですか?fork

man namespaces:

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.

man nsenter:

...
-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.

ベストアンサー1

説明は「PID名前空間」セクションにあります。man nsenter:

nsenter子プロセスには、プロセスマッピング用のプロセスとは別のPIDセットがあります。nsenterPID名前空間を変更すると、デフォルトで新しいプログラムとそのサブルーチンが同じPID名前空間を共有して互いに見えるようにフォークされます。使用すると、--no-fork分岐せずに新しいプログラムが実行されます。

(説明書がちょっと混乱していますね。上で引用した部分をまとめて、の次のバージョンにはutil-linux修正が含まれています。.)

PID名前空間を入力しても、現在のプロセスはその名前空間に移動されず、その名前空間に新しい子プロセスが作成されるだけです。したがって、現在のプロセス(呼び出し process setns)は新しい名前空間の子プロセスには表示されません。これを防ぐには、nsenter新しい名前空間を入力してフォークすると、新しいnsenter名前空間に新しい名前空間が作成され、結果としてexec実行されたプログラムは新しい名前空間になります。

PID名前空間の説明も参照してください。man setns:

もしFD異なる名前空間の種類と多少異なる意味を持つPID名前空間を参照します。呼び出しスレッドをPID名前空間に再接続すると、後で作成された呼び出し元サブプロセスが配置されるPID名前空間のみが変更され、呼び出し元のPID名前空間は変更されません。

名前空間エントリでこれを見ることができます/proc。 2つのPIDエントリ(プロセスの名前空間)と(新しいサブプロセスの名前空間)が/proc/.../nsあります。pidpid_for_children

exec新しいプロセス自体を作成しません。)

おすすめ記事