mountとbindの違い

名前空間を変更するシステムコールとして,mount(2)とbind(2)の二つが提供されていて,カレントプロセス,または同一名前空間グループに属するプロセスの名前空間を変更できる.

int bind(char *name, char *old, int flag)
int mount(int fd, int afd, char *old, int flag, char *aname)
int unmount(char *name, char *old)

どちらのシステムコールもoldは既存のファイルまたはディレクトリである.
bindは以前も書いたけど,UNIXのln -sでシンボリックリンクを張るのに近く,引数nameで渡された別名を追加する.さらに,ディレクトリをbindする場合は,(詳しくは後述するが)複数ディレクトリの集合を一つのディレクトリとして見せるユニオンディレクトリとなる.Plan9において特徴的なのは,シンボリックリンクはその変更が全プロセスから同じように見えるのに対して,bindでは変更の影響はカレントプロセスの名前空間に限定されることである.これは,シンボリックリンクはリンク構造がファイルシステム(ディスク上)のinodeに書き込まれるのに対して,bindはカーネルのメモリ上だけに存在することを意味する.むしろ,bindがあるので,ファイルシステム自体にリンクは不要なのである.メンテナンス性を考えたら,こっちの方が優れてそうだな.

一方,mountは,ファイルサーバが提供するファイルツリーを名前空間に追加する.引数fdはファイルサーバとの通信に使うファイル記述子であり,ここで使うプロトコルはもちろん9Pである.mountが成功した後は,(ファイルサーバが提供する)oldから始まるファイルツリーへのopen-read-write-closeシステムコールは,mnt(3)ドライバを経由して,9Pプロトコルに変換されて,ファイルサーバへ通知される.

mount,bindで変更した名前空間はunmount(2)で元に戻すことができる.

(追記: 2006-04-30) 書き忘れたけど,mountはユーザ権限で実行できってことも重要な違いだ(正確にはPlan9にはスーパユーザという概念がない).Plan9のセキュリティ話はまた別の機会に調べよう.