MOUNT_NULL(8)

名称
mount_null - ループバックファイルシステムのマウントおよび、 null ファイルシステム層の利用の仕方のデモ

書式
mount_null [-o options] target mount-point

解説
mount_null コマンドは、null 層を作ります。これは、 ファイルシステムの名前空間の部分木を、グローバルなファイルシステムの 名前空間の別の場所に複製します。 これにより、既存のファイルやディレクトリが別のパス名で参照できるように なります。

このファイルシステムの仮想的なコピーとシンボリックリンクとの違いは、 getcwd(3) が仮想コピー上で正しく動作することと、オリジナルに影響を与えずに 仮想コピー上に別のファイルシステムをマウントできるという点です。 仮想コピーに対する stat(2) は別の番号が返されますが、それ以外ではオリジナルと区別することはできません。

mount_null ファイルシステムは伝統的なループバックファイルシステムとは 2 つの点で 異なっています。1 つは stackable layers という技術を用いて実装しているという 点で、もう 1 つは “ null-node ” が (ディレクトリの vnode の真上でなく) すべての下位層の vnode の上に 積まれるという点です。

オプションは以下のものがあります:

-o  -o のあとに、オプションをカンマで区切って並べて指定します。 指定可能なオプションとその意味は mount(8) を参照してください。

この null 層は 2 つの目的を持っています。1 つは、何もしない層 を提供することでファイルシステムの層の構築のデモを示すことです。 もう 1 つは、null 層をプロトタイプとして提供することです。 層のフレームワークとして必要なことはすべて提供しているので、 ここから新しいファイルシステム層を簡単に作り出すことができます。

このマニュアルの以下の部分では、新しいファイルシステム層を構築するための 基礎として null 層を調べます。

新しい NULL 層の例示
新しい null 層は mount_null で作られます。 mount_null は 2 つの引数をとります。 1 つは下位層の vfs のパス名 (target-pn) で、 もう 1 つは null 層が現れる名前空間内のパス名 (mount-point-pn) です。 null 層が配置された後は、target-pn 部分木の内容が mount-point-pn にエイリアスされます。

NULL 層の操作
null 層は最小のファイルシステム層であり、利用可能なすべての操作を、 それを処理するために単に下位層にバイパスするだけです。 その動作のほとんどはバイパスルーチンに集中しますが、 ほとんどすべての vnode に対する操作はパスします。

バイパスルーチンは下位層で扱う任意の vnode に対する操作を受け付けます。 まず最初に、vnode に対する操作の引数を検査し、 null-node をそれらと同等の下位層のものに置き換えます。 それから、その下位層の操作を起動します。 最後に、引数中の null-node を置き換えます。 もしその操作によって vnode が返ってきたら、 その返ってきた vnode の上に null ノードを積みます。

ほとんどの操作をバイパスしますが、 vop_getattr, vop_inactive, vop_reclaim, vop_print はバイパスしません。 vop_getattr は、返却する fsid を変更しなければなりません。 vop_inactive と vop_reclaim は、null 層特有のデータの解放が出来るようにするため、バイパスしません。 vop_print は、デバッグ情報が過度に出力されないようにするため、バイパスしません。

VNODE スタックの概説
マウントすると、null 層は下位層に連想されます。要するに、2 つの VFS が 積み重なります。 vnode スタックはファイルがアクセスされるたびに必要に応じて作成されます。

最初のマウントでは新しい null 層の根として単一の vnode スタックを作ります。 他のすべての vnode スタックは、このスタックや他の null vnode スタックの 操作の結果として作られます。

vnode を返す操作の結果として新しい vnode スタックが生まれます。 バイパスルーチンは、呼出し側に vnode を返す前に、新しい vnode の上に null-node を積みます。

例えば、以下のようにして null 層をマウントする例を想像します。

    mount_null /usr/include /dev/layer/null

/dev/layer/null にディレクトリを変更すると、null-node の root (null 層をマウントした時 に作られたもの) が割り当てられます。 ここで sys を open することを考えてみます。 vop_lookup は null_node の root で行われます。 この操作は下位層にバイパスされ、この層が UFS の sys を表す vnode を返します。 それから null_bypass は UFS の sys にエイリアスする null-node を構築し、呼出元にこれを返します。 null-node の sys に対するこれ以降の操作では、他の vnode スタックを構築する時には この処理が繰り返されます。

他のファイルシステム層の作成
新しいファイルシステム層を構築する一番簡単な方法は、 null 層のコピーを作り、すべてのファイル、変数の名前を付け直し、 そのコピーを変更することです。 sed を使えば、全ての変数名を簡単に変更できるでしょう。

umap 層は null 層からの派生として作った例のうちの 1 つです。

下位層の操作の起動
操作が完全にはバイパスできない時に 下位層にある操作を起動するための方法が 2 つあります。 それぞれの方法は違った状況に対して適切に使われます。 両方の場合とも、 その操作の引数を下位層用に正しく作成するのはエイリアスする側の層の責任であり、 vnode 引数を下位層にマッピングすることで行います。

最初の方法は、エイリアスする側の層のバイパスルーチンを呼ぶことです。 この方法は、下位層で現在扱っている操作を実行したい時に最も適しています。 これはバイパスルーチンがすでにマッピングされているという利点があります。 この例が、null 層の null_getattr にあります。

2つ目の方法は、 VOP_OPERATIONNAME インターフェースを用いて下位層の vnode の操作を直接起動することです。 この方法の利点は、下位層の任意の操作を実行するのが簡単であるということに あります。欠点は、vnode 引数を手動でマッピングしなければならないことです。

関連項目
mount(8)

UCLA Technical Report CSD-910056, Stackable Layers: an Architecture for File System Development.

歴史
mount_null ユーティリティは 4.4BSD から登場しています。