Linuxではハードディスクをパーティションに分割して利用します。それぞれのパーティションにはアクセスするためのデバイスファイルが割り当てられ、各パーティションはそれぞれ独立したファイルシステムを持ちます。ファイルシステムには ext2、ext3、ext4、XFS などがあります。
第一パーティションは bootファイルシステムです。Linuxを起動すると(電源を入れると)ROM内のBIOSがPOST(Power On Self Test:ハードウェアの種々のチェックや初期化を行うこと)をし、ディスクの先頭にあるブートローダーと呼ばれるプログラムを実行します。この領域はMBR(Master Boot Record)と呼ばれ、bootファイルシステムに属しています。MBRにはブートローダーの他に各パーティションの情報を保持したテーブル(パーティションテーブル)が格納されています。
起動されたブートローダーはパーティションテーブルからOSが置かれているパーティションを検索します。そしてそのパーティションの先頭(ブートブロック)にあるプログラムを実行します。この領域はPBR(Partition Boot Record)と呼ばれます。このプログラムがOSを起動させています。
ただ、BIOSによる起動(MBR方式)では以下の問題があります。
- パーティションテーブルに格納できるエントリは4個まで
- MBRで扱えるハードディスクの容量は2TBまで
これらを解消するためにUEFI(GPT方式)が導入されました。GPT(GUID Partition Table)では2TBの制限はなくなりパーティションテーブルのエントリも128個まで拡張されています。UEFIでは「EFI System Partition」と呼ばれるパーティション領域を作成し、そこにブートローダーやパーティションテーブルを格納します。マザーボードに組み込まれたファームウェアがEFIシステムパーティションの内容を読み込み、ブートローダーがOSの起動まで行っています。EFIシステムパーティションはFATベースのファイルシステムでフォーマットされています。
LinuxのブートローダーにはGRUBがあります。GRUBはいくつかのコンポーネントで出来ており、bootファイルシステム(EFIシステムパーティション)、および、ブートブロックに格納されています。
ここからはファイルシステムについて書いてみます。
ファイルシステムはブートブロック、スーパーブロック、iノードリスト、データブロックで構成されています。各パーティションのファイルシステムを確認するには「df -T」コマンドで確認できます。ブートブロックにはOSを起動するプログラムが入っています。
スーパーブロックですが、この領域にはファイルシステムを管理する以下のような情報が格納されています。
- ファイルシステムの大きさ
- 空きブロックに関する情報
- iノードに関する情報
- スーパーブロックが修正されたことを示すフラグなど
2点目の空きブロックに関する情報ですが「空きブロック数」、「使用可能な空きブロックのリスト」、「空きブロックリスト内における次の空きブロックへのポインタ」などがあります。スーパーブロックの詳細を確認したい場合は「dumpe2fs -h デバイスファイル名」のコマンドで確認できます(ただし、root権限が必要)。
3点目のiノードに関する情報ですが、そもそもiノードとは「1つのファイルを管理するのに必要な情報の入れ物」です。この入れ物に関する情報をスーパーブロックで保持しています。具体的には「iノードリストの大きさ(入れ物がいくつあるか)」、「使用可能な空きiノードの数」、「空きiノードのリスト」、「空きiノードリスト内における次の空きiノードへのポインタ」などです。iノードを区別するためにiノードにはiノード番号と呼ばれる番号が割り当てられています。iノードが枯渇するとディスク容量に空きがあったとしてもファイルを作成することはできません。ディスクに空き容量があるのに「空き容量が足りない」旨のメッセージが出た場合は空きiノード数を確認してみてください。iノードに関する情報は「df -i」コマンドで確認できます。ちなみにiノードは「index node」を短縮したものです。
最後のスーパーブロックが修正されたことを示すフラグですが、スーパーブロックの情報はメモリ上で管理されていて定期的にディスクに書き込まれています。システムが正常な手段で停止しなかった場合、スーパーブロックのフラグが立ったままになるので次のシステム起動時にシステムがそのフラグをチェックして不整合を修復するのに使われます。
スーパーブロックの次の領域には、iノードリストがあります。先に説明したようにファイルを管理する入れ物がリスト形式でここに格納されています。この入れ物の中身(すなわち、ファイルを管理するための情報)ですが、以下のものがあります。
- ファイルの種類(一般ファイル、ディレクトリファイル、デバイスファイル)
- ファイルへのリンク数
- ファイルの所有権
- ファイルのアクセス権
- 時間(最終アクセス時刻、最終変更時刻、ステータス変更時刻(iノード自体が最後に変更された時刻))
- バイト単位でのファイルサイズ
- データブロックへのポインタなど
iノードの中身には「ファイル名」も「ファイルのデータ自体」も含まれていません。ファイル名はディレクトリファイルに格納されており、この仕組みは次回書こうと思います。ファイルのデータはiノードリストの次の領域にあるデータブロックに格納されています。
最後に、、この記事を書くにあたり以下の書籍を参考にさせていただきました。僕がずいぶん前に読んだ本ですが読み返してみました。