3

次のシナリオを実装しようとしています。

  1. clone()フラグ付きのメイン プロセスCLONE_NEWNS(新しいマウント名前空間を意味します)
  2. mount()子プロセスの新しいファイルシステム
  3. 子プロセスが終了し、このプロセスで作成されたすべてのファイルシステムがアンマウントされました

しかし、期待どおりに動作せず、マウントされたファイルシステムがメイン プロセスに表示されます。私は何を間違っていますか?

ソースはこちらhttps://github.com/dmitrievanthony/sprat/blob/master/src/container.c#L47

システムはデフォルトのAWS Ubuntuで、

ubuntu@ip-172-31-31-112:~/sprat$ uname -a
Linux ip-172-31-31-112 4.4.0-53-generic #74-Ubuntu SMP Fri Dec 2 15:59:10 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
4

1 に答える 1

5

簡単な回答:マウントの伝播の種類が正しく設定されていないようです。


説明

LinuxカーネルはデフォルトですべてMS_PRIVATEマウントを これは、 のオプション フィールドを見ることで確認できます。たとえば、次のようなことが予想されます。MS_SHARED/proc/$PID/mountinfo

$ cat /proc/self/mountinfo
  . . .
25 0 8:6 / / rw,relatime shared:1 - ext4 /dev/sda6 rw,errors=remount-ro,data=ordered
                         ^^^^^^
  . . .

上記の下線付きの (by me)shared:1フィールドに注目してください。これは、/マウント ポイントの現在の伝播タイプがMS_SHAREDであり、ピア グループID がであることを示しています1(この場合、ピア グループ ID はまったく気にしません)。

CLONE_NEWNSフラグを使用するとclone(2)、新しいマウント名前空間が作成され、呼び出し元のマウント名前空間のコピーとして初期化されます。新しい名前空間の複製された新しいマウント ポイントは、呼び出し元のマウント名前空間にあるそれぞれの元のマウント ポイントと同じピア グループに参加します。

親の伝播タイプが である新しいマウント ポイントの伝播タイプMS_SHAREDMS_SHAREDです。したがって、「含まれる」プロセスmount()がループデバイス上のファイルシステムである場合、マウントはデフォルトでMS_SHARED. 後で、その下のすべてのマウントが「メイン」プロセスの名前空間にも伝播されます。これが、「メイン」プロセスがそれらを見ることができる理由です。

要求が満たされるために (「メイン」プロセスが「含まれる」プロセスのマウント ポイントを認識しないようにするため)、求めるマウント伝達タイプは、「含まれる」プロセスのルート マウント ポイントに伝達を受け取るかどうかに応じて、MS_SLAVEまたはです。MS_PRIVATEそれぞれ、他のピアからのイベントかどうか。明らかに、MS_PRIVATEは よりも優れた分離を提供しますMS_SLAVE

したがって、あなたの場合、「含まれる」プロセスのルートマウントポイントの伝播タイプを、残りのファイルシステムをマウントする前に変更するだけで十分であるMS_PRIVATEためMS_SLAVE マウントは「メイン」プロセスの名前空間に伝播されません。


コード

最初は、「含まれる」プロセスがそのルート マウント ポイントを作成するときに、伝播タイプを適切に設定しようとします。

ただし、man 8 mount(引用)で次のことに気付きました。

Linux カーネルでは、単一の mount(2) システム コールで複数の伝播フラグを変更することは許可されておらず、フラグを他のマウント オプションと混在させることはできないことに注意してください。

util-linux 2.23 以降、mount コマンドを使用すると、複数の伝播フラグを一緒に使用したり、他のマウント操作と一緒に使用したりできます。この機能は実験的です。伝播フラグは、前のマウント操作が成功したときに、追加の mount(2) システム コールによって適用されます。

コードを見ると、「含まれる」プロセスはmount()、ループデバイス上のファイルシステムになった後、それに発行chroot()されます。この時点で、次のmount(2)呼び出しを挿入することで伝播タイプを設定できます。

if (chroot(".") < 0) {
    // handle error
}

if (mount("/", "/", c->fstype, MS_PRIVATE, "") < 0) {
    // handle error
}

if (mkdir(...)) {
    // handle error
}

伝播タイプが に設定されたMS_PRIVATEので、「含まれる」プロセスが実行する後続のマウントはすべて伝播されないため、または/で確認できるように、「メイン」プロセスの名前空間には表示されません。/proc/mounts/proc/$PID/mountinfo


資力

于 2016-12-14T21:14:00.097 に答える