Linuxカーネルとtarファイルの構造を理解し、オリジナルのファイルシステム「tarファイルシステム」の設計をはじめよう
前回「素晴らしきファイルシステムのデータ管理」で、“ありがたい”ファイルシステムのデータ管理の説明が一通り終わりました。携帯電話やデジタルカメラなどの組み込み機器といえども、大量のデータを扱う場合は、このようなファイルシステムがないと不便なのです。
それでは、今回から腕試し(?)として、オリジナルのファイルシステム「tarファイルシステム」を作っていきましょう。まずは、Linuxカーネルの構造、およびtarファイルの構造について説明し、そして、tarファイルシステムの設計方法を解説していきます。
もしかすると、“tarファイルシステム”と聞いても、ピンとこない方がいらっしゃるかもしれませんので、ここで少し補足します。
tarファイルシステムとは、tarファイルをマウントして、tarアーカイブ内のファイルを参照できる(読み込み専用)ようにするためのファイルシステムです。
以下に、tarファイルをマウントするときのコマンドを示します。マウントが成功すると、tarファイル内のすべてのファイルにアクセスできるようになります。
$ sudo mount -t tarfs tarfile mnt
※ -t tarfs:ファイルシステムタイプとしてtarファイルシステム(tarfs)を指定 ※ tarfile:tarファイル ※ mnt:マウントポイント |
では、tarファイルシステムを使用するメリットはどこにあるのでしょうか。以下に、3つのメリットを挙げてみました。
(1)tarファイルを展開しないため、HDDのディスク資源を余計に使用しない(注1)
(2)tarファイルに大量のファイルがあっても、短時間でマウントでき、ファイルを参照できる
(3)アーカイブ内のファイルを、使い慣れたLinuxコマンドで操作できる
いかがでしょうか? これで「tarファイルシステムのありがたみをお分かりいただけましたよね?」といっても、やはり実感ないですよね……。そんな皆さんのために、tarファイルシステムの試作モジュールを使った簡単なデモを紹介します(動画1)。
デモの内容は、以下のとおりです。
1.gzipで圧縮されたtarファイル(注2)を、/mntにマウント
2.マウント成功後、/mnt配下のディレクトリに対して、lsを実行
3.dfコマンドで、tarファイルシステムの資源の使用状況を表示
4.find(注3)コマンドで、以下の2種類のファイル検索
(a)ヘッダファイル(*.h)の検索
(b)ファイルサイズが100kbytes以上のファイルの検索
5.viコマンドで、ファイルのデータを参照
6.tarファイルシステムをアンマウント
動画1 tarファイルシステムの試作モジュールの様子 |
それでは、tarファイルシステムについて、感触をつかんでいただいたところで、このtarファイルシステムを作るうえで必要となる以下の前提知識について説明していきます。
そして、これらの前提知識を基に、tarファイルシステムの設計案を3つ考案し、それら設計案を比較検討します。
先ほどのデモで、ファイルシステムを操作するコマンドを使いましたが、このコマンドから実際にHDDへのアクセス処理が行われるまでに、Linuxカーネル内ではさまざまな処理が行われています。
具体的には、はじめに、コマンドから「システムコール(注4)」というカーネルインターフェイスが呼び出されます。そして、システムコールから「仮想ファイルシステム(VFS:Virtual File System)」の処理が行われるわけですが、この処理の中で「ローカルファイルシステム(LFS:Local File System/ext3など)」が呼び出される、といった仕組みになっています(注5)。
tarファイルシステムをLinuxカーネルに登録するためには、このVFSの処理とローカルファイルシステムの処理を理解する必要があります。以下で詳しく見ていきましょう。
Linuxには、非常に多種多様なファイルシステムが存在します。一方、ファイルシステムの操作という点では、これらのファイルシステムの間で共通した操作というものも多くあります。
ここで、以下に示す2つのファイルシステムを例に、dfコマンドの操作を考えてみましょう。
(1)HDDにデータを記録しているファイルシステム(ext4など)
(2)メモリにデータを記録しているファイルシステム(Ramfsなど)
(1)はこれまで見てきたように、HDDにユーザーのデータを保存するファイルシステムです。一方、(2)はデータの保存先がメモリになっているファイルシステムです。このため、データは永続化されておらず、電源が切れると消えてなくなります。主に、一時的なデータ管理用のファイルシステムとして利用されます。
これら2つのファイルシステムのdfコマンド操作は、以下のようになります(表1)。
ext4 | Ramfs | |
---|---|---|
① | 対象となるファイルシステムを検索する | 対象となるファイルシステムを検索する |
② | HDDに登録されているスーパーブロック情報を取得する | メモリ上に存在するスーパーブロック情報を取得する |
③ | ファイルシステム使用状況をユーザーに返す | ファイルシステム使用状況をユーザーに返す |
表1 2つのファイルシステムのdfコマンド操作 |
上記を見ていただければ、②のスーパーブロック情報の取得処理は、ファイルシステムごとに違いますが、①と③の処理はまったく同じ操作であることが分かりますよね。このため、①と③を共通の処理とすると、各ファイルシステムで同じコードを書く必要がなくなり、ソースコード量がぐんと減らせます(表2)。
ext4 | Ramfs | |
---|---|---|
① | 対象となるファイルシステムを検索する | |
② | HDDに登録されているスーパーブロック情報を取得する | メモリ上に存在するスーパーブロック情報を取得する |
③ | ファイルシステム使用状況をユーザーに返す | |
表2 ①と③を共通の処理に |
Linuxでは、①と③のような共通処理のところをVFSと呼び、②のようなファイルシステム固有の処理のところをLFSと呼びます。オブジェクト指向をご存じの方であれば、VFSが“抽象クラス”、LFSが“サブクラス”だと理解してもらえばイメージしやすいと思います。
つまり、tarファイルシステムをLinuxカーネルに追加するには、VFSのサブクラスとして、②のような固有の処理を追加するだけで済みます。従って、このサブクラスの実装は、オブジェクト指向的な再利用性の恩恵にあずかることができ、比較的容易になるというわけです。実際、tarファイルシステムのカーネルソースコード量はそれほど多くなく、たったの800ステップ程度でした。筆者は、過去のプロジェクトで、あるファイルシステムのテストモジュールをC言語でよく書いていましたが、大抵2000ステップは軽く超えていました。それを考えると、ファイルシステムが1000ステップ以内で書けてしまうことは本当に驚きです。
Copyright © ITmedia, Inc. All Rights Reserved.