webdevqa.jp.net

Linux-マウント名前空間とクローンCLONE_NEWNSフラグを理解する

mountclone のマニュアルページを読んでいます。 CLONE_NEWNSが子プロセスのファイルシステムのビューにどのように影響するかを明らかにしたいと思います。

(ファイル階層) 

このツリーをディレクトリ階層と考えてみましょう。 5と6が親プロセスのマウントポイントであるとしましょう。別の 質問 でマウントポイントを明確にしました。

したがって、私の理解は次のとおりです。5と6はマウントポイントであり、以前はmountコマンドを使用してファイルシステム(ディレクトリ階層)を5と6に「マウント」しました(つまり、5と6の下にディレクトリツリーが存在する必要があります)同様に)。

mountのマニュアルページから:

_ A mount namespace is the set of filesystem mounts that are visible to a process. 
_

cloneのマニュアルページから:

_Every process lives in a mount namespace.  The namespace of a process is the data 
(the set of mounts) describing the file hierarchy as seen by that process.  After 
a fork(2) or clone() where the CLONE_NEWNS flag is not set, the child lives in the 
same mount namespace as the parent.
_

また:

_After a clone() where the CLONE_NEWNS flag is set, the cloned child is started in a 
new mount namespace, initialized with a copy of the namespace of the parent.
_

clone()を_CLONE_NEWNS_とともに使用して子プロセスを作成した場合、これは、子がツリー(5および6)のマウントポイントの正確なコピーを取得し、それでもできることを意味しますか?元のツリーの残りの部分にアクセスしますか?また、親プロセスのマウント名前空間の5または6にマウントされているものに影響を与えることなく、子が5と6を自由にマウントできることも意味しますか。

はいの場合、子が5または6とは異なるディレクトリをマウント/アンマウントして、親プロセスに表示される内容に影響を与える可能性があることも意味しますか?

ありがとう。

18
Jake

プロセスの「マウント名前空間」は、プロセスが認識するマウントされたファイルシステムのセットにすぎません。 1つのグローバルマウント名前空間を持つ従来の状況からプロセスごとのマウント名前空間を持つようになったら、clone()を使用して子プロセスを作成するときに何をするかを決定する必要があります。

従来、ファイルシステムをマウントまたはアンマウントすると、すべてのプロセスで見られるようにファイルシステムが変更されていました。すべてのプロセスで見られるグローバルマウント名前空間が1つあり、変更が加えられた場合(たとえば、mountコマンドを使用)、すべてのプロセスが即座に変更しました。 mountコマンドとの関係に関係なく、その変更を確認してください。

プロセスごとのマウント名前空間を使用すると、子プロセスはその親とは異なるマウント名前空間を持つことができます。ここで疑問が生じます:

子によって行われたマウント名前空間への変更は親に伝播する必要がありますか?

明らかに、この機能must少なくともサポートされており、実際、おそらくデフォルトである必要があります。それ以外の場合、mountコマンド自体を起動しても変更は行われません(親シェルから見たファイルシステムは影響を受けないため)。

同様に明確に、この必要な伝播がsuppressedである可能性もある必要があります。そうしないと、マウント名前空間が親とは異なる子プロセスを作成できず、1つのグローバルマウント名前空間が再び存在します(ファイルシステムinitで見られるように)。

したがって、clone()を使用して子プロセスを作成するときに、子プロセスがマウントされたファイルシステムに関するデータの独自のコピーを親から取得するかどうかを決定する必要があります。これは、親に影響を与えることなく変更できます。または、へのポインタを取得します。親と同じデータ構造で、変更できます(シェルからmountを起動する場合のように、変更を伝播して戻す必要があります)。

_CLONE_NEWNS_フラグがclone()に渡されると、子は親のマウントされたファイルシステムデータのcopyを取得します。これは、親のマウント名前空間に影響を与えることなく変更できます。それ以外の場合は、親のマウントデータ構造へのpointerを取得します。ここで、子によって行われた変更は親に表示されます(したがって、mountコマンド自体が機能します)。

CLONE_NEWNSでcloneを使用して子プロセスを作成した場合、これは、子がツリー(5および6)のマウントポイントの正確なコピーを取得し、元のツリーの残りの部分にアクセスできることを意味しますか?

はい。 clone()を呼び出した後、親とまったく同じツリーが表示されます。

また、親プロセスのマウント名前空間の5または6にマウントされているものに影響を与えることなく、子が5と6を自由にマウントできることも意味しますか。

はい。 _CLONE_NEWNS_を使用したので、子は5から1つのデバイスをアンマウントし、そこに別のデバイスをマウントでき、そのデバイス(およびその子)のみが変更を確認できます。この場合、他のプロセスは子によって行われた変更を確認できません。

はいの場合、子が5または6とは異なるディレクトリをマウント/アンマウントして、親プロセスに表示される内容に影響を与える可能性があることも意味しますか?

いいえ。_CLONE_NEWNS_を使用した場合、子で行われた変更を親に戻すことはできません。

hant't used _CLONE_NEWNS_の場合、子はその親と同じマウント名前空間データへのポインターを受け取り、子によって行われた変更は、次のようなプロセスによって認識されます。親を含むこれらのデータ構造を共有します。 (これは、fork()を使用して新しい子が作成される場合にも当てはまります。)

22
Emmet

コメントを追加するのに十分なレピュテーションポイントがないので、代わりにこのコメントを回答として追加します。これは、エメットの答えへの単なる追加です。

AFAICU、CLONE_NEWNSフラグが設定された状態でプロセスが作成された場合、プロセスはFS_USERNS_MOUNTフラグが設定されたファイルシステムのみをマウントできます。また、ほとんどすべてのディスクベースのファイルシステムは、(セキュリティ上の理由から)このフラグを設定していません。 do_new_mountには、次のチェックがあります。

        if (user_ns != &init_user_ns) {
            if (!(type->fs_flags & FS_USERNS_MOUNT)) {
                    put_filesystem(type);
                    return -EPERM;
            }

私が間違っている場合は私を訂正してください

4
user3820535