Solaris で擬似ファイルシステムをつくろう/其の2 (FTPファイルシステム)

目次

ご注意

ここで紹介しているプログラムは、カーネルモジュールを含んでいます。そのため、プログラム上に問題があった場合(可能性大)にはシステムが PANIC し、場合によってはファイルシステムに重大な障害を引き起こす可能性があります。以下のプログラムはテストプログラムで、十分な検証を行ってはいません。したがってあくまで個人の検証ためにお使いいただき、重要なシステム上では動作させないでください。本プログラムの使用により発生したトラブルなど、いかなる損害についても一切の責任を負いかねます。ご利用は自己責任にてお願いいたします。

概要

「Solaris で擬似ファイルシステムをつくろう/其の1」で作成した擬似ファイルシステムをもとに、FTP プロトコルを使って リモートホストのディレクトリをマウントしてローカルファイルのようにアクセスできる FTP ファイルシステムを作成いたしました。イメージ的には NFS のようなものですが、プロトコルとして FTP を使用しますので、リモートホストが NFS で ディレクトリを share していなくても、FTP サーバが稼動していてなおかつその FTP サーバのユーザアカウントを持っている のであれば、リモートホストの任意のディレクトリにマウントし、ファイルにアクセスすることができます。
ただ、残念ながら現時点ではサポートしている環境と機能がかなり限られます。具体的には 64bit sparc Solaris 10上でのみ動作可能で、マウント先のファイルへの書き込みや、プログラムの実行はできません。(32bit/64bit sparc Solaris 9 や 32bit/64bit x86 Solaris 10 上での動作は不可です)

  • 2010/04/29 x86/x64 OpenSolaris(32bit/64bit) に対応しました。
    (でも、マウント先へのファイルの書き込みは不可のままです)

    ※ 現在ではユーザモードアプリでファイルシステムを作成できる FUSE (Filesystem in userland) の OpenSolaris 版が存在するようです。FUSE on OpenSolaris
    Fuse では FTP だけでなく SSH や WebDav などのプロトコルを利用した沢山のファイルシステムが実装されているようですので、本当に FTP などを使ってマウントを行いたいという方は、この Fuse を使われるのが良いかもしれません。

ソースファイルとダウンロード

ソースファイル: iumfs-ftp.tar.gz (最終更新日 2010/04/29 - OpenSolaris に対応しました)

アーカイブ・ファイルに含まれるファイル
iumfs.cIUMFS ファイルシステムモジュール
iumfs_vnode.ciumfs の vnode オペレーションが記述されたコード
iumfs_request.ciumfs の iumfscntlドライバとのインターフェースが記述されたコード
iumfs_cntl_device.ciumfscntl 擬似デバイスドライバ
iumfs.confiumfscntl ドライバの為の driver.conf(4)ファイル
iumfs_devlink.tabiumfscntl の為の devlinks(1M) テーブルファイル
iumfsd.cユーザモードデーモン
iumfs.hヘッダーファイル
iumfs_mount.cIUMFS ファイルシステム用の mount コマンド
Makefile.inMakefile の雛形
configure.inconfigure の雛形
configureconfigure スクリプト
fstest.ciumfs の機能テスト用プログラム
fstestd.ciumfs の機能テスト用デーモンプログラム
test.shテストを実行するスクリプト(マウントとfstest,fstestdの実行)
install-shインストールスクリプト

各ソースコードは以下からも参照いただけます。

http://github.com/kaizawa/iumfs-ftp

動作確認済み Solaris バージョン

OpenSolaris 対応の変更を行った後(2010/4/29) の iumfs ファイルシステム の動作確認状況は以下のようになっています。
Solaris9 以前はテストしてません。Soalris 10 も sparc のみのテストです。

プラットフォーム
Solarisバージョン
Sparc
(32bit)
Sparc
(64bit)
x86x64
Solaris9以前????
Solaris10-??
OpenSolaris-?

○:動作確認済み ×:動作不可 ?:未確認 -:該当なし

プログラムの解説

この FTP ファイルシステムは2つのプログラムで構成されています。1つははカーネルモジュールであるファイルシステムモジュール兼仮想デバイスドライバ、もうひとつはユーザモードのデーモンです。ファイルシステムモジュール自身はユーザプロセスからの read(2) などのシステムコールを受け付けるだけで、実際の FTP プロトコルを使った通信部分はユーザモードのデーモンで行っています。ユーザモードのデーモン(iumfsd)と、ファイルシステム(iumfs) との連絡用に仮想デバイスを作成し、この仮想デバイス(/dev/iumfscntl)経由でユーザモードデーモンとファイルシステムのデータの受け渡しが行われるようになっています。

IUMFS ファイルシステムモジュール

ファイルシステムとしての基本的な枠組みは「Solaris で擬似ファイルシステムをつくろう/其の1」のコードをその まま流用しています。
ファイルの属性や内容、ディレクトリエントリなどの情報はリモートシステムからとってくることが必要 になったため、iumfs_readdir()関数(ディレクトリエントリの読み込み)や iumfs_getattr()関数(ファイルの 属性情報の取得)などを変更し、後述の iumfscntl デバイスを通じて ユーザモードデーモンにリクエストを行うルーチンが追加されています。
また其の1ではユーザプロセスから read(2) 要求があった場合、iumfs_read() 関数は、あらかじめ確保しておいた カーネル空間のアドレスを uiomove(9F) を使って uio 構造体にコピーしていましたが 、其の2の iumfs_read() では segmap_getmapflt() 関数を使ってファイルの 指定領域とカーネルアドレス空間のマップを行い、このマップされたアドレスを uiomove(9F) に渡すようになりました。 そして、segmap_getmapflt() によってマップされたアドレスに対応したをページを読み込むための GETPAGE VNODE オペレーション(iumfs_getpage) が新たに追加されています。

iumfs_readdir() の変更

iumfs_readdir() は getdents(2)システムコールに対応した VNODE オペレーションで、ユーザプロセス からの要求にしたがって、ディレクトリエントリを返す関数になります。
其の1では要求されたディレクトリ自身の iumnode 構造体(ファイルシステム型依存のノード構造体)から リンクされている dirent_t 構造体を読み込むんでユーザプロセスに返すだけでした。 其の2でも同様にローカルのカーネルメモリ内に保持された dirent_t 構造体を読み込むという基本動作は変 わりませんが、要求がきた場合、まず iumfs_request_readdir() 関数を通じて iumfscntl ドライバにリモート ホスト上のディレクトリエントリを読み込むようリクエストし、取得した内容をカーネルメモリ内に一旦保持し、 それをユーザプロセスに返すように変更されています。

iumfs_getattr() の変更

iumfs_getatt() は ファイルのサイズ、変更日、パーミッションなどの属性値を得るための VNODE オペレーションです。
其の1では要求されたファイル・ディレクトリ自身の iumnode 構造体(ファイルシステム型依存のノード構造体)から リンクされている vattr_t 構造体を読み込むだけでしたが、其の2 では iumfs_request_getattr() 関数を通じて iumfscntl ドライバに対してリモートホスト上のファイルの属性情報を読み込みを行うよう要求するように 変更されています。

iumfs_read() の変更と、iumfs_getpage() 追加

其の2での一番大きな変更点は VOP_GETPAGE(ページ取得)の実装です。 其の1の IUMFS ファイルシステムではファイルの全内容はカーネルメモリ空間に常に保持されており、 ユーザプロセスからの読み込み要求(read(2)システムコール)に従って VNODE オペレーションである iumfs_read() 関数がメモリの内容をユーザプロセスに返していただけでした。しかし其の2では iumfs_read() は seg_map セグメントドライバが提供する segmap_getmapflt() という関数を使って ファイルをカーネルアドレス空間にマップすることだけを行います。実際のデータの読み込み は、マップされたカーネルアドレスがアクセスされ、ページフォルトが発生した時点で seg_map セグメント ドライバから呼ばれる GETPAGE VNODE オペレーション(iumfs_getpage) 内で行われます。
iumfs_getpage() はシステムのページサイズ毎に iumfs_getapage(getpage でなく getapage)を 呼び出し、iumfs_getapage() は iumfs_request_read() 関数を通じて iumfscntl デバイスドライバに 対してリモートホスト上のファイルデータの読み込みを行うよう要求します。

ページキャッシュ

其の2のファイルシステムではファイルデータの読み込みは FTP プロトコルを使ってリモートホストからブロック単位 でファイルを読み込むことで行い、基本的にはローカルシステム上ではファイル全体のコピーは保持しません。
その代わり、一回読み込んだファイルデータをカーネル空間上でページキャッシュという仕組みを利用してキャッシュ し、このページキャッシュが有効である限りは再度リモートからデータを読み込む必要がないようになっています。 このページキャッシュという仕組みは UFS や NFS などのファイルシステムでも使われており、(メモリに比べて)低速な ディスク装置やネットワーク経由でのファイルの不要な再読み込み減らし、高速なデータへの参照を実現しています。

iumfscntl デバイスへのリクエスト

前述の iumfs_readdir, iumfs_getattr, iumfs_getapge といった関数は、その中で iumfscntl デバイスドライバに対して各々の VNODE オペレーションに対応したリクエストを要求します。

iumfsの関数名対応するVNODEオペレーションiumfscntl へ要求を行う関数名
iumfs_readdirVOP_READDIRiumfs_request_readir
iumfs_getattrVOP_GETATTRiumfs_request_getattr
iumfs_lookupVOP_LOOKUPiumfs_request_getattr
iumfs_getapageVOP_GETPAGEiumfs_request_read

iumfscntl デバイスへのリクエストを要求するそれぞれの関数(iumfs_request_xxx) は 必ず以下の関数を順番どおりに呼びだすようにしており、複数のリクエストが同時に 実行されないことを保証しています。

1iumfs_daemon_request_enter()リクエストの順番待ちをする
2iumfs_daemon_request_start()リクエストを投げる
3iumfs_daemon_request_exit()リクエストを終了する

もしいずれかのリクエストがあるスレッドにて処理中であれば、他ののスレッドは iumfs_daemon_request_enter() の 中で cv_wait_sig(9F) で待たされます。

iumfscntl デバイスドライバ

其の1には無かった仮想デバイス /dev/iumfscntl のデバイスドライバです。
IUMFS ファイルシステムモジュールと iumfsd ユーザモードデーモンはこの仮想デバイスを通じてデータの要求や データ送受を行います。iumfscntl デバイスはキャラクタデバイスであり、ユーザプロセスからの以下の操作を サポートしています。

オペレーション概要解説
openデバイスのオープン
closeデバイスのクローズ
readデバイスからの読み込みIUMFSファイルシステムからのリクエスト内容の伝達に利用
writeデバイスへの書き込みiumfsd からのリクエストの実行結果の成否の報告に利用
mmapデバイスのユーザメモリ空間へのマップiumfsd からのリクエストの実行結果(ファイルデータ等)の受け渡しに利用
pollデバイスのイベント通知IUMFS ファイルシステムからのリクエストの到着の通知

iumfscntl ドライバ自身は IUMFS ファイルシステムから渡されたリクエストの中身や、iumfsd デーモンから 渡されたファイルデータの中身は頓着していません。ただ中継するだけです。

ちなみに、IUMFS ファイルシステムモジュールと iumfscntl デバイスドライバはインストールされるファイルとしては 同一のファイル(ハードリンク)になっていますが、カーネルにロードされた後では別々の モジュールとして認識されます。

# modinfo |grep -i iumfs
190 7bfb9cc8   3828  24   1  iumfs (file system for iumfs)
190 7bfb9cc8   3828 148   1  iumfs (control driver for iumfs)

iumfd ユーザモードデーモン

socket(3socket) をつかって実際のリモートホストと FTP の通信を行うユーザモードデーモンです。
このデーモンは起動時に /dev/iumfscntl デバイスをオープンし IUMFS ファイルシステムからの要求を 待ち、IUMFS ファイルシステムからファイルや属性情報の読み込み要求がくると、FTP プロトコルを使って 指定されたリモートホスト上のファイルデータやファイル属性情報を取ってきて、/dev/iumfscntl デバイス を通じて取ってきた情報を IUMFS ファイルシステムに返します。
大雑把に言えば、FTP を使って以下の3つの VNODE オペレーションに対応するコマンドを発行し情報を取得します。

VNODE オペレーション対応するFTP プロトコルでのコマンド
readdirNLST -a
readRETR
getattrNLST -dlAL

なお、データセッションについては PASVモード(パッシブモード)のみのサポートとなります。
RFC 959: を参照してはいますが、多くの点で実装に 足りない点があるため、FTP クライアントプログラムと考えた場合、RFC 非準拠です。(泣)

属性情報の読み込み(NLST)

上記表の NLST コマンドで使っている「-a」や「-dlAL」といったオプションは、激しく FTP サーバ側の実装依存になります。 また -l で取得できるファイルの属性情報(といっても /bin/ls -l の出力と等価)の出力フォーマットも FTP サーバ側に 依存します。現在 iumfsd が認識できる NLST -a の出力フォーマットは以下の8種類になります。

  • デバイスファイルの場合
    crw-rw-rw-   1 root  sys   146, 3  Feb  11   00:13 tcp6@0:tcp6
    crw-rw-rw-   1 root  sys   146, 3  Feb  11   2005 tcp6@0:tcp6
    crw-rw-rw-   1 root  sys   146, 3  2月  11日 00:13 tcp6@0:tcp6
    crw-rw-rw-   1 root  sys   146, 3  2月  11日 2005年 tcp6@0:tcp6
  • その他のファイルの場合
    -rwxr-xr-x   1 root  bin      203  Dec  10   00:13  clean.sh
    -rwxr-xr-x   1 root  bin      203  Dec  10   2005   clean.sh
    -rwxr-xr-x   1 root  bin      203  12月 10日 00:13  clean.sh
    -rwxr-xr-x   1 root  bin      203  12月 10日 2005年 clean.sh

世には多くの GUI の FTP クライアントソフトが存在し、どの FTP クライアントも同様の問題を持っている はずだとおもうのですが、みなさんどのようにファイルの属性情報をプログラム側で取得しているので しょう・・単に多くのフォーマットに対応するようにしているだけなのでしょうか? それとも FTP サーバの 実装に依存せずファイルの属性情報をとってくるコマンド等があるのでしょうか・・・?  私には調べきれませんでした。

ちなみに、NLST の「-d」オプションははディレクトリ中身ではなく、ディレクトリ自身の情報を見るために利用しているのですが、マイクロソフト Windows の FTP サーバでは「-d」オプションを期待通りに認識してくれないようです。そのため、Windows の FTP サーバをマウントした場合、ディレクトリの属性が正しく取れません。要改善・・ですがどうすればいいんでしょう?

ファイルデータの読み込み(RETR)

ファイルデータの読み込みではファイルシステムという性質上ブロックモードにてブロック単位で任意の長さの データをとってきたいところです。しかし多くの FTP サーバではストリームモードしかサポートしていないようです。 つまり、ファイルの 100バイト目から 300バイト目までの 200 byte だけを読み込みたいのに、RETR コマンド を使うとファイル全体を読み込んでしまうのです。これはかなり非効率的です。
ですので、iumfsd デーモンでは REST コマンドを使ってまずファイル転送開始のオフセットを指定し、 RETR コマンドを使ってそこから必要バイト分だけ読んだ時点で ABOR コマンドを発行してこれ以上不要なデータの転送を 行わないようにしています。

  • ファイル「hoge」の 100 バイト目から 200 バイト読むためのシーケンス
  1. 転送開始オフセットを指定
    REST 100
  2. パッシブモードを指示
    PASV
  3. ファイル「hoge」の転送指示
    RETR hoge
  4. データセッションにて 200 バイト分だけ読み込む
  5. ファイルの転送中止を指示
    ABORT

ABORT コマンドを発行したとしても、実際の転送が終了されるまでには相当量のデータがデータセッション を通じて流れてきてしまうためやはり非効率なのは否めませんが、ファイル全体を毎々読み込むことに比べれば だいぶ無駄は少ないと考えています。また、ファイル全体を読む必要がある場合(cp コマンドなど)でも、 かならず 8K バイト単位でデータをとりにいきますのでパフォーマンスはすごく悪いです。

同時実行性

このデーモンはシングルプロセスかつシングルスレッドです。なので、一時に処理できるのは1つの処理 だけです。(たとえば、ホストA 上の /var/log/syslog ファイルを 8K バイト読む。など)
IUMFS ファイルシステム自身は、複数のリモートホストのディレクトリへの同時マウントをサポートして ますし、複数のユーザプロセス(cp や vi 等)が同時に多数のファイルに対してアクセスしてきても大丈夫 なのですが、最終的にデータをリモートホストから転送してくる iumfsd デーモンがシングル スレッドプロセスなので、例えば 1つのカーネルスレッドが IUMFS ファイルシステム上のファイルの read(2) を処理している最中は他のカーネルスレッドは cv_wait_sig(9F)にて待たされることになります。
もし、連続してきたリクエストがそれぞれ別々の FTP サーバ上のファイルへの操作の要求であった場合、 状況はさらに悪くなります。iumfsd デーモンは、異なる FTP サーバへの要求を受けるたびに FTP データ セッションの 切断 -> 接続 -> ログイン の処理を繰り返すため、 耐え難いほどのパフォーマンスの低下が予想されます・・・いづれマルチプロセス化、もしくはマルチスレッド化して 少なくとも FTP のデータセッションのつなぎなおしが必要ないようにしたいと考えています。

  • 3つの別々のリモート FTP サーバ上のファイルの読み込み要求が来た場合
  1. ホストAのファイルFILE_Aの0 バイト目から100 byte 分だけ読み込み要求が到着
    1. ホストAとのFTPコントロールセッションを接続・ログイン
    2. REST、RETRコマンドを使ってファイルの指定オフセットから指定バイトだけ読み込み
  2. ホストBのファイルFILE_Bの0 バイト目から100 byte 分だけ読み込み要求が到着
    1. ホストAとのコントロールセッションを切断
    2. ホストBとのFTPコントロールセッションを接続・ログイン
    3. REST、RETRコマンドを使ってファイルの指定オフセットから指定バイトだけ読み込み
  3. ホストCのファイルFILE_A の 100 バイト目から200 byte 分だけ読み込み要求が到着
    1. ホストBとのコントロールセッションを切断
    2. ホストCとのFTPコントロールセッションを接続・ログイン
    3. REST、RETRコマンドを使ってファイルの指定オフセットから指定バイトだけ読み込み

IUMFS ファイルシステム用 mount コマンド

IUMFS ファイルシステム専用の mount コマンドです。
其の1とほぼ同じでものです。mount(1M) コマンドが自動的にこのコマンドを見つけて呼び出してくれるため、 ユーザはこの IUMFS 専用の mount コマンドの存在を意識する必要はありません。ただ -F オプションに「iumfs」 を渡し、ファイルシステムを指定すればよいだけです。
其の1 からの変更点としては、今回はマウントするリソース(マウントの対象)を 指定する必要があるため、引数にリモートホスト名と、マウントするリモートホストのディレクトリを記述 するようになりました。

# mount -F iumfs -o user=root,pass=hoge  ftp://srv.example.com/export/  /mnt
                 ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^
                   オプション            リソース                       マウントポイント

mount コマンド内では渡されたオプションやリソース部分の構文チェックを行い、構文として正しければ mount(2) システムコールを通じて IUMFS ファイルシステムの iumfs_mount() に全引数を渡します。
引数に含まれるホスト名やユーザ名などの情報自身のチェックは行いません。(それらは前述の iumfsd ユーザモードデーモンの中で行われます)

インストール

コンパイル&インストール

configure, make 実行すると環境に応じて 64bit/32bit のファイルシステムモジュール兼、擬似デバイスドライバである iumfs モジュールと、mount コマンド、iumfsd デーモンが作成されます。 コンパイル終了後、make install にてファイルのコピーと、ファイルシステムモジュールのカーネルへのロードが行われます

OpenSolaris での実行例)

# ./configure
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for a BSD-compatible install... /bin/ginstall -c
checking for isainfo... yes
configure: creating ./config.status
config.status: creating Makefile			  
					  
# make
gcc -c -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 -mcmodel=kernel -mno-red-zone 
-D_KERNEL -I. iumfs.c -o iumfs.o
gcc -c -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 -mcmodel=kernel -mno-red-zone 
-D_KERNEL -I. iumfs_vnode.c -o iumfs_vnode.o
gcc -c -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 -mcmodel=kernel -mno-red-zone
-D_KERNEL -I. iumfs_cntl_device.c -o iumfs_cntl_device.o
gcc -c -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 -mcmodel=kernel -mno-red-zone 
-D_KERNEL -I. iumfs_request.c -o iumfs_request.o
ld -dn -r iumfs.o iumfs_vnode.o iumfs_cntl_device.o iumfs_request.o -o iumfs
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 iumfs_mount.c -o mount
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 iumfsd.c -lsocket -lnsl -o iumfsd
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 fstestd.c -lsocket -lnsl -o fstestd
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" 
-DPACKAGE_BUGREPORT=\"\" -g -O2 -Wall -DOPENSOLARIS -DSOL10 -m64 fstest.c -o fstest
					  
# make install								  
/bin/ginstall -c -m 0644 -o root -g sys iumfs /kernel/fs/amd64
/bin/ginstall -c -m 0644 -o root -g sys iumfs.conf /usr/kernel/drv
/usr/bin/ln /kernel/fs/amd64/iumfs /usr/kernel/drv/amd64/iumfs
/usr/sbin/add_drv iumfs
/bin/ginstall -c -d -m 0755 -o root -g bin /usr/lib/fs/iumfs
/bin/ginstall -c -m 0755 -o root -g bin mount /usr/lib/fs/iumfs
/bin/ginstall -c -d -m 0755 -o root -g bin /usr/local/bin
/bin/ginstall -c -m 0755 -o root -g bin iumfsd /usr/local/bin
/usr/sbin/devfsadm -t ./iumfs_devlink.tab -i iumfs

アンインストール

ファイルシステムモジュールおよびコマンドのアンインストールは make uninstall で行います。
もし、インストール時に利用した Makefile がすでに無い場合も、以下のログを参考に各コマンドを マニュアルで実行していただければ同じ結果を得られます。

# make uninstall
pkill -x iumfsd
/usr/sbin/rem_drv iumfs
rm /kernel/fs/amd64/iumfs
rm /usr/kernel/drv/amd64/iumfs
rm /usr/kernel/drv/iumfs.conf
rm /usr/lib/fs/iumfs/mount
rm -rf /usr/lib/fs/iumfs
rm -rf /usr/local/bin/iumfsd

iumfsd が動作していない場合以下のようなエラーがでますが問題ありません。

*** Error code 1 (ignored)

IUMFS ファイルシステムが利用中(マウントされている)の場合、ファイルの削除は可能ですが、モジュール のアンロードは失敗します。この場合システムのリブート後に完全に削除されます。

# make uninstall
pkill -x iumfsd
*** Error code 1 (ignored)
/usr/sbin/rem_drv iumfs
Device busy
Cannot unload module: iumfs
Will be unloaded upon reboot.
rm /kernel/fs/amd64/iumfs
rm /usr/kernel/drv/amd64/iumfs
rm /usr/kernel/drv/iumfs.conf
rm /usr/lib/fs/iumfs/mount
rm -rf /usr/lib/fs/iumfs
rm -rf /usr/local/bin/iumfsd

使い方

IUMFS ファイルシステムの利用方法についてご説明します。

iumfsd デーモンの起動

IUMFS ファイルシステムからのリクエストに従って FTP の通信を行う iumfsd デーモンを起動しておきます。
実際にはこのデーモンの起動と、後述のファイルシステムのマウントの順番は逆でも大丈夫です。ただ、当たり前ですが デーモンを起動していない状態でファイルシステムのマウントしたとしてもリモート FTP サーバ上のファイルを 参照することはできません。

Usage: iumfsd [-d level]
       -d level    : デバッグレベル[0-3]

デバッグレベルを 1 以上にした場合、フォアグランドで実行され、デバッグメッセージを書き出します。

ファイルシステムのマウント

IUMFS ファイルシステムのマウントには通常の mount(1M) コマンドを利用します。

使い方: mount -F iumfs [-o options] ftp://host/pathname mount_point

     ftp://host/pathname
       マウントをする FTP サーバのホスト名と、サーバ上のディレクトリのパスを以下のフォーマットで指定します。
         ftp://      必須
         host        FTP サーバ名
         /pathname   サーバ上のディレクトリ。「/」だけでも可。でも省略はできません。

     -o options
       IUMFS ファイルシステム専用のオプションを指定する。現在サポートしているのは以下の2つ。
          user=ユーザ名     ユーザ名を指定します。デフォルトは「ftp」。
          pass=パスワード   ユーザのパスワードを指定します。デフォルトは「ftp」。

     mount_point
       IUMFS ファイルシステムをマウントするマウントポイント

以下に /mnt ディレクトリに srv.example.com の上の /export ディレクトリをマウントする例を示します。(ユーザ名 をhoge、パスワードをheheとします。)

# /usr/sbin/mount -F iumfs -o user=hoge,pass=hehe ftp://srv.example.com/export /mnt
#

もし、FTP サーバが anonymous アクセスを許可しているならば -o オプションは省略できます。(デフォルトのuser=ftp,pass=ftp が使われます)

# /usr/sbin/mount -F iumfs ftp://srv.example.com/export /mnt
#

確認

# mount
...
...
/mnt on ftp://srv.example.com/export read only/setuid/devices/dev=4840003 on (日)  3月 19 17:30:19 2006
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

可能なファイル操作

ディレクトリの移動、ディレクトリエントリの参照

# cd /mnt
# /bin/ls
file1  file2

各ファイルの属性情報の参照

# ls -la
合計 3
drwxr-xr-x   1 root     root         512  3月 19日  17:55 .
drwxr-xr-x  27 root     root        1024  3月 19日  23:14 ..
-rw-r--r--   1 root     root       54455  3月 19日  17:54 file1
-rw-r--r--   1 root     root      163365  3月 19日  17:55 file2

ファイル属性のうち、ファイルタイプ、ファイルサイズ、ファイルの最終変更日時、 あとパーミッションはオリジナルファイルの情報がそのまま反映されますが、ファイル のオーナー情報だけはリモートホスト側の実際のオーナーに関わらず常にroot:rootと表示されます。

ファイルの読み込み

# head file1
This is a test file
This is a test file
This is a test file
This is a test file
This is a test file
This is a test file
This is a test file
This is a test file
This is a test file
This is a test file
#

ファイルのコピー

# cp file1 /var/tmp
#

不可能な操作

open/read/lseek/getdent以外のファイル操作はほとんどできないと思っていただいてかまいません。 其の2の IUMFS ファイルシステム上のファイルに対してこれら以外の操作を行った場合はエラーが返されます。

ファイルのアクセス権の変更

# chmod 777 file1
chmod: 警告: file1 を変更できません。

ファイルの更新日時を変更

# touch file1
touch: file1 の時間を変更できません。

ファイルのオーナーを変更

# chown nobody file1
chown: file1: 読み取り専用のファイルシステムです。

ファイルに書き込み

# cp /var/adm/messages file1
cp: file1 を作成できません: 読み取り専用のファイルシステムです。

ファイルシステムのアンマウント

IUMFS ファイルシステムのアンマウントには通常の umount(1M) コマンドを利用します。

Usage: umount mount_point

    mount_point : ファイルシステムがマウントされているマウントポイント

他のファイルシステムでもおなじですが、だれかがそのファイルシステム上のファイルを 利用中の場合には BUSY が返り、umount(1M) は失敗します。

アンマウントの成功例)

# umount /mnt
#

ファイルシステムが利用中である為にアンマウントが失敗する例)

# pwd
/mnt
# umount /mnt
umount: /mnt 使用中です。

今後の課題

  1. FTPに加えて、HTTP や他のプロトコル経由でもリモートホストのディレクトリをマウントできるようにする。

  2. 対応するシステムコールを増やす
    前回も増やしたいといっておきながら、逆に対応のシステムコールが減ってしまいました。中でも write(2) システムコール が未対応になったのはファイルシステムとしては痛手だと思っています。しかしながら write(2) をサポートした場合、
    1. IUMFS ファイルシステムのの不具合のせいでリモートホスト上のファイルが破壊される可能性がある。
    2. PUTPAGE VNODE オペレーションを実装するのが大変。
      という2つの理由から実装を見送っています。
  3. Solaris 9 のサポート
    さすがにもう Solaris9 はあきらめました。

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-01-03 (月) 20:25:56