はじめに
この連載では"ファイルシステムの作り方"をご紹介します。第1回目の今回は簡単なイントロダクションと単純なHello Worldファイルシステムの作り方を説明します。次回以降で詳しい解説と本格的なファイルシステムの作り方をご紹介しようと思います。
ファイルシステムとは
まず、この連載で作るファイルシステムとは一体どのようなものか簡単に説明します。ファイルシステムとは、一言でいえばオペレーティングシステム(OS)が持つコンピュータ資源管理機能の一つです。少し詳しく述べると、ハードディスクなどの補助記憶装置に格納されたデータ(資源)にアクセスするためのインターフェイスを持つ抽象モデルを提供するコンピュータシステム、を指します。代表的なファイルシステムとして、WindowsのNTFS、Linuxのext3、Mac OSのHFS などのファイルシステムがあります。
今回の連載では、簡単にするため、つぎに示す「パス」、「ファイル」、「ディレクトリ」という3つの用語を使ってファイルシステムを定義します。
- パス
ファイルやディレクトリを指し示す文字列。
(C:\Windows\System32\cmd.exeや/var/log/httpdなど) - ファイル
データ(バイト列)の読み書きなどができるオブジェクト。 - ディレクトリ
ファイルやディレクトリの一覧の取得などができるオブジェクト。
ファイルシステムとは、パスを指定することでファイルやディレクトリを指定し、さらにそれらのオブジェクトを使って、データの読み書きやファイル一覧の取得など実現する仕組み、ということになります。
図1:ファイルシステムの仕組み
普段何気なくエクスプローラを使ってディレクトリを移動してファイルを保存したり開いたりする行為も、ファイルシステムによって実現されているのです。
なぜファイルシステムを作るか
次になぜファイルシステムを作るのか説明をしたいと思います。これは言い換えれば、「どうして今さらファイルシステムを作る必要があるのか?」ということです。
この疑問はとても自然です。というのも、ファイルシステムは単純にデータを管理するための手段で、私たちが日常コンピュータを利用する上で、すでに十分なファイルシステムは提供されています。もちろん、一昔前は扱えるファイルサイズやファイル名の長さなどに幾分厳しい制限があり、不満を感じた人もいるかもしれません。ですが、最近のファイルシステムに対してそういった意味で問題を感じることはほとんどないと思います。
そういった意味でファイルシステムを新しく作る必要性はないように思えます。
ところが、実は近年、ファイルシステムの進歩は留まるどころかむしろ加速している、というのが著者の見解です。
最近登場した新しいOSに、ファイルを過去の状態に復元する機能が相次いで搭載されました。たとえばWindows VistaのシャドウコピーやMac OS Xのタイムマシーンがそうです。実はこれらの機能はファイルシステムによって実現されています。この他にも、最近のファイルシステムには暗号化や圧縮といった機能が搭載されていることが珍しくありません。
ここで浮かび上がってくるのが次の疑問です。
なぜファイルシステムに機能を付加するのか?
上であげたような機能は、ファイルシステムでなくとも、専用のアプリケーションやシステムで実現することが可能です。実際、多くのそういったアプリケーションやシステムが存在します。
複数の選択肢の中でなぜファイルシステムとして機能を実現するのでしょうか?その答えは、ファイルシステムがだれでも使える「インターフェイス」だからです。ファイルシステムをインターフェイスと言うことに違和感を感じるかもしれませんが、要するに、エクスプローラ(やコマンドラインのシェル)を使って、ファイルやディレクトリを操作できるというのは、「パソコンが使える」人であればまず備えている基本中の基本スキルだからです。
誰でも使える「ブラウザ」を通じて機能を提供する「Webサービス」がインターフェイスとして広く受け入れられたのと同じ理由で、ファイルシステムも非常に優れたインターフェイスになりうるのです。
このインターフェイスとしてのファイルシステムに注目したシステムにDecasがあります。Decasは著者らによって開発された、2006年度下期 IPA未踏ユース採択プロジェクト「データ管理システム」の開発成果です。この連載で利用するDokanライブラリもこのプロジェクトの開発成果になります。Decasはバックアップや暗号化、バージョン管理といった機能をモジュールとして動的にファイルシステムに追加できるようにした、新しいタイプのシステムです。ファイルシステムとして実現することで、利用者に特別な操作を強いることなく、自然な形でファイルの管理を実現しています。
図2:データ管理システムDecas(バージョン管理機能)
Hello Worldファイルシステム
では、いよいよファイルシステムの作り方について説明します。今回紹介するのはDokanライブラリとそのRubyバインディングを使ってファイルシステムを開発する方法です。
Rubyバインディングはとても簡単にファイルシステムを開発できる反面、あまり処理効率の良いものは作れないことに注意してください。より実用的なファイルシステムの開発については次回以降で解説します。
Dokanライブラリのインストール
まずは、今回の主役、Windows用ユーザモードファイルシステムライブラリDokanのインストールです。Dokanライブラリは現在オープンソースで開発が進められており、誰でも自由に利用することができます。このDokanライブラリの詳しい仕組みについては次回で解説します。ここでは単にファイルシステムを実現するためのライブラリと捉えておいてください。
サイト(http://dokan-dev.net/)から圧縮ファイルをダウンロードして展開するとWindows Vista用とWindows XP用のインストーラが含まれていますので、適切な方を実行してください。基本的にインストーラの指示に従って進めばインストールが完了します。
もし、すでに古いDokanライブラリをインストール済みで新しいものにアップデートする場合は、1)古いライブラリをアンインストール、2)OSを再起動、3)新しいライブラリをインストールする必要があります。
インストールが完了したら、正しくDokanライブラリが機能しているかを確認します。コマンドプロンプトを起動して、Dokanライブラリをインストールしたディレクトリ(ここではC:\Program Files\Dokan\DokanLibrary)に移動して、次のコマンドを実行してください。
> dokanctrl.exe /v
dokanctl : Jun 7 2008 17:11:58
Dokan version : 166
Dokan driver version : 166
Dokanライブラリが正しくインストールされていれば、上のようにバージョン番号が表示されます。
Rubyバインディングの入手
Rubyバインディングとは、RubyからDokanライブラリの機能を呼び出して、Rubyでファイルシステムを簡単に作るためのRubyの拡張ライブラリです。ですので、実行には別途Rubyの実行環境が必要になります。Windowsで動作するRuby環境はhttp://www.ruby-lang.org/の情報を参考に導入してください。今回はActiveScriptRuby1.8.7(p22)を使用しました。
RubyバインディングはDokanライブラリと同じサイトから提供されています。インストールは特に必要なく、圧縮ファイルを展開してできたファイルのうち、dokanfs.rbとdokan_lib.soをRubyの実行環境から読める位置(Rubyスクリプトと同じディレクトリ)に置けば動作します。
Hello Worldファイルシステムの実行
以上で開発の準備が整いました。今回開発するHello Worldファイルシステムのコードはとても短いので、まずは入力して実行してみましょう。
require 'dokanfs' class HelloFS def contents path ["hello.txt"] end def file? path path =~ /hello.txt/ end def directory? path path == "/" end def read_file path "hello world" end def size path "hello world".length end end DokanFS.set_root(HelloFS.new) DokanFS.mount_under("r") DokanFS.runhellofs.rb
プログラムの起動:
> ruby hellofs.rb > hellofs.log
プログラムの終了:
> dokanctl.exe /u r
図3: HelloFSの実行結果
スクリプトを実行するとRドライブが出現し、そのRドライブにあるhello.txtを開くとhello worldと表示されます。もしすでにRドライブを割り当てている場合、スクリプトは失敗してしまうので、コードの26行目の"r"を適宜修正してください。
Hello Worldファイルシステムの解説
無事にファイルシステムが作れたところで、それぞれのメソッドについて解説をします。
- file?
指定されたパスで指定されているオブジェクトがファイルかどうかを返します。ここでは、hello.txtであればtrueを返すようにしています。 - directory?
指定されたパスで指定されているオブジェクトがディレクトリかどうかを返します。ここでは、/(最上位のディレクトリ、ルートディレクトリ)であればtrueを返すようにしています。 - contents
指定されたパス(ディレクトリを仮定)に含まれるファイルやディレクトリの一覧を返します。ここでは、無条件にhello.txtを1つのみを含むリストを返しています。本来ならディレクトリごとに異なった内容を返すべきですが、今回はルートディレクトリにhello.txtが1つだけある状態を作り出すファイルシステムなのでこれでOKです。 - read_file
指定されたパス(ファイルを仮定)のデータを読み込んで返します。ここでは、無条件に"hello world"という文字列を返しています。 - size
指定されたパス(ファイルを仮定)のサイズを返します。ここでは、無条件に"hello world"という文字列のサイズを返しています。
では次に、実際にファイルシステムがどのように動作したのかを見てみましょう。Rubyバインディングはログを出力するようになっているので、hellofs.logを見ることで、どのような順番でメソッドが呼び出されたかを知ることができます。
#open /autorun.inf #open /autorun.inf #opendir / #cleanup / #open /AutoRun.inf ... #opendir / #readdir / #stat /hello.txt #cleanup / #open /desktop.ini #open /desktop.ini #opendir / #opendir / #cleanup / ... #open /hello.txt #read /hello.txt #close /hello.txt ...
図4: hello worldが表示されるまでの流れ
上のリストはエクスプローラでRドライブを開き、次にhello.txtを開くという動作のみを行ったときのログを抜粋したものです。また、ログを元にhello worldが表示されるまでの流れを図解したものを図4に示します。たったこれだけの操作を実現するために非常に多くのメソッドが実行されていることがわかります。ただ、このログの多さはエクスプローラがユーザの操作とは別に「先読み」をするためでもあります。同様の操作をコマンドプロンプトから実行した場合のログと比べてみるとエクスプローラがいかに貪欲に「探索」しているかがわかります。
以上で、第1回目はおしまいです。この記事で少しでもファイルシステムについて興味を持って頂ければ幸いです。次回は詳しい仕組みと実用的なファイルシステムの作り方をご紹介します。どうぞお楽しみに。
著者について
荒川 淳平(あらかわ じゅんぺい): 東京工業高等専門学校情報工学科を卒業したのち、電気通信大学情報工学科の3年次に編入学し同学科を卒業。その後、東京大学大学院情報理工学系研究科にて創造情報学を専攻。専門はソフトウェアデザイン、システムソフトウェア。DecasやDokanを含むプロジェクト「データ管理システム」は情報処理推進機構(IPA) 2006年度下期 未踏ソフトウェア創造事業(ユース)に採択され、天才プログラマー/スーパークリエータの認定を受ける。現在、東京大学大学院博士後期過程に在籍中。情報理工学修士。また、電気通信大学在学中に株式会社インフォクラフトを設立。現在、同社代表取締役。