この回答 から、_unshare -p
_を介してLinuxPID名前空間を使用してプロセスサブツリー全体の信頼できる強制終了を実装できることを学びました。
ここに私が理解していない問題があります:
_-f
_/_--fork
_オプションを使用して共有を解除した場合にのみ機能します。
_unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"
_
これを実行し、_kill -9
_そのbash
のPIDを実行すると、必要に応じて、監視、スリープなどがすべて停止します。
しかし、_-f
_なしで使用すると:
_unshare -p -- bash -c "watch /bin/sleep 10000 && echo hi"
_
そして_kill -9
_ bash PIDの場合、watch
はPID1(systemdである私のUbuntu上)に親が変更されるため、すべての子を殺すという望ましい効果はありません。
質問:
--fork
_が必要なのはなぜですか? unshare
がフォークなしでexec()
を使用するだけでは不十分なのはなぜですか?unshare
を開始して作成されたPIDに_kill -9
_を便利に送信して、その下のすべてを強制終了できればと思います。しかし、_--fork
_を使用すると、unshare
を開始したときに返されたpidを強制終了すると、unshare
が強制終了され、bash
がPID1に再ペアレント化されます。これは、unshare
がPID名前空間にないためです。_&& echo hi
_にコマンドを1つだけ与えると、それがexec()
になり、bashプロセスがなくなって(置き換えられ)、強制終了できないため、_bash -c
_が必要であることに注意してください。そのPID。
説明したように この有用な回答で _-n
_(unshare(CLONE_NEWPID)
)の効果は、フォークされた最初の子プロセスに対してのみ作用します。
特に、 man 2 unshare は_CLONE_NEWPID
_について言っています:
PID名前空間の共有を解除して、呼び出し元のプロセスが、既存のプロセスと共有されていない子の新しいPID名前空間を持つようにします。
呼び出しプロセスは新しい名前空間に移動されません。
呼び出しプロセスによって作成された最初の子は、プロセスID 1を持ち、新しい名前空間で
init(1)
の役割を引き受けます。
unshare
にパッチを適用する質問をしてから、ここ数時間で_util-linux
_( ここにリクエストをプル )にパッチを作成し、unshare
に_--kill-child
_フラグを追加しました。 。
編集:これは、util-linux _v2.32
_の一部としてマージおよびリリースされました。
次のように使用できます。
_unshare -fp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"
_
unshare
を強制終了すると、プロセスツリー全体が破壊されます。
root
なしカーネルでユーザー名前空間が有効になっている場合(_CONFIG_USER_NS=y
_)、_-U
_フラグを渡すことにより、root
権限なしで使用することもできます。
_unshare -Ufp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"
_