Solaris のシステム管理 (基本編)

fsck コマンドでチェックして修復される内容

この節では、ファイルシステムの通常の処理中に発生する問題、原因、fsck コマンド (チェックおよび修復ユーティリティ) で検出される問題、およびそれらの修正方法について説明します。

不整合が発生する原因

就業日には毎日多数のファイルが作成、変更、または削除されます。ファイルが変更されるたびに、オペレーティングシステムは一連のファイルシステムの更新処理を実行します。これらの更新処理がディスクに確実に書き込まれると、ファイルシステムの整合性が保たれます。

ユーザープログラムが書き込みなどの、ファイルシステムを変更する処理を実行すると、書き込まれるデータはまずカーネルのインコアバッファーにコピーされます。通常、ディスクの更新は非同期に処理されます。ユーザープロセスは、書き込みシステムコールが値を返した後すぐに処理を続けることができますが、実際のデータの書き込みは、かなり後に実行されることもあります。したがって、ディスク上にあるファイルシステムは、インコア情報で表されるファイルシステムの状態から常に遅延することになります。

別の目的にバッファーが必要になったり、カーネルが fsflush デーモンを自動的に (30 秒間隔で) 実行すると、インコア情報を反映するようにディスク情報が更新されます。システムがインコア情報を書き込まずに停止すると、ディスク上のファイルシステムの整合性がなくなります。

ファイルシステムの整合性は、さまざまな原因で失われることがあります。最も一般的な原因は、オペレータのエラーとハードウェア障害です。

システムを正しくシャットダウンしなかったり、マウントされているファイルシステムが正しくオフラインにされないと、「クリーンでないシャットダウン」が原因で問題が発生することがあります。クリーンでないシャットダウンを防ぐには、システムをシャットダウンしたり、ディスクをドライブから物理的に取り出したり、ディスクをオフライン状態にする前に、ファイルシステムの現在の状態をディスクに書き込まなければなりません (つまり、同期させなければなりません)。

また、ハードウェアの欠陥が原因で整合性が失われることもあります。ディスクドライブ上ではいつでもブロックが損傷する可能性があり、ディスクコントローラが正常に機能しなくなる可能性があります。

整合性がチェックされる UFS 構成要素

この節では、UFS ファイルシステムの構成要素、つまりスーパーブロック、シリンダグループブロック、i ノード、間接ブロック、データブロックに fsck コマンドが適用する整合性チェックの種類について説明します。

UFS ファイルシステム構造については、「UFS ファイルシステムのシリンダグループの構造」を参照してください。

スーパーブロックのチェック

スーパーブロックには集計情報が格納されており、UFS ファイルシステム内で最も破損しがちな構成要素です。ファイルシステムの i ノードやデータブロックが変更されるたびに、スーパーブロックも変更されます。CPU が停止した場合、直前のコマンドが sync コマンドでなければ、スーパーブロックはほぼ確実に破損しています。

スーパーブロックの不整合は、次の面からチェックされます。

ファイルシステムのサイズと i ノードリストのサイズのチェック

ファイルシステムのサイズは、スーパーブロックと i ノードリストに使用されるブロック数よりも大きくなければなりません。i ノード数は、ファイルシステムの最大許容数よりも小さくなければなりません。i ノードは、ファイルに関するすべての情報を表します。ファイルシステムのサイズとレイアウト情報は、fsck コマンドにとって最も重要な情報部分です。これらのサイズはファイルシステムの作成時に静的に決められるため、実際にチェックする方法はありません。ただし、fsck コマンドを使用してサイズが妥当な範囲内にあるかどうかはチェックできます。ファイルシステムの他のすべてのチェックを行うには、これらのサイズが正確でなければなりません。fsck コマンドが一次スーパーブロックの静的パラメータ内に不正な情報を検出すると、オペレータに代替スーパーブロックの位置を指定するように促します。

UFS ファイルシステム構造の詳細については、「UFS ファイルシステムのシリンダグループの構造」を参照してください。

空きブロック数のチェック

空きブロック数は、シリンダグループのブロックマップに格納されます。fsck コマンドは、空きマーク付きのすべてのブロックがファイルによって使用されていないかどうかをチェックします。すべてのブロックをチェックし終わると、fsck コマンドは空きブロック数と i ノードによって使用されるブロック数の合計がファイルシステム内の合計ブロック数に等しくなるかどうかをチェックします。ブロックマップ内に間違いがあると、fsck コマンドはブロックが割り当てられている状態のままで構築し直します。

スーパーブロック内の集計情報には、ファイルシステム内の空きブロックの合計数のカウントが入っています。fsck コマンドは、このブロック数をファイルシステム内で見つかった空きブロック数と比較します。数が一致しなければ、fsck コマンドはスーパーブロック内の空きブロック数を実際の空きブロック数で置き換えます。

空き i ノード数のチェック

スーパーブロック内の集計情報には、ファイルシステム内の空き i ノード数が入っています。fsck コマンドは、この i ノード数をファイルシステム内で見つかった空き i ノード数と比較します。数が一致しなければ、fsck はスーパーブロック内の空き i ノード数を実際の空き i ノード数で置き換えます。

i ノード

i ノードリストは、i ノード 2 から順番にチェックされます (i ノード 0 と i ノード 1 は予約されています)。各 i ノードの不整合は、次の面からチェックされます。

i ノードのフォーマットとタイプ

各 i ノードには、そのタイプと状態を記述するモードのワードが入っています。i ノードには、次の 9 つのタイプがあります。

i ノードの状態は、次の 3 つに分かれています。

ファイルシステムが作成されると、一定数の i ノードが確保されますが、必要になるまでは割り当てられません。割り当て済みの i ノードとは、ファイルを指す i ノードです。未割り当ての i ノードは、ファイルを指さないので空のはずです。不完全に割り当て済みの状態は、i ノードが正しくフォーマットされていないことを意味します。たとえば、ハードウェア障害が原因で i ノードに不正なデータが書き込まれると、i ノードは不完全に割り当て済みの状態になることがあります。fsck コマンドが実行できる唯一の修正動作は、その i ノードを消去することです。

リンク数のチェック

各 i ノードには、そこにリンクされているディレクトリエントリ数が入っています。fsck コマンドは、ルートディレクトリから順番にディレクトリ構造全体を検査し、i ノードごとに実際のリンク数を計算して、各 i ノードのリンク数を検査します。

i ノードに格納されているリンク数が fsck コマンドによって判断された実際のリンク数と一致しない場合は、次の 3 つの状況が考えられます。

重複ブロックのチェック

各 i ノードには、それが使用するすべてのブロックのリスト、またはリストを指すポインタ (間接ブロック) が入っています。間接ブロックは i ノードによって所有されるので、間接ブロックの整合性が失われると、それを所有する i ノードが直接影響を受けます。

fsck コマンドは、i ノードから使用される各ブロック番号を、割り当て済みブロックのリストと比較します。別の i ノードからすでにブロック番号が使用されていると、そのブロック番号は重複ブロックのリストに入れられます。それ以外の場合は、割り当て済みブロックのリストが更新され、ブロック番号が追加されます。

重複ブロックがあると、fsck コマンドは再び i ノードリストを調べて、各重複ブロックを使用する他の i ノードを検索します。i ノード内に大量の重複ブロックが入っている場合は、ファイルシステムに間接ブロックが正しく書き込まれていない可能性があります。どの i ノードにエラーがあるかを正確に判断することはできません。fsck コマンドは、保持する i ノードと消去する i ノードを選択するように促すプロンプトを表示します。

不正なブロック番号のチェック

fsck コマンドは、i ノードから使用される各ブロック番号をチェックして、その値が最初のデータブロック番号よりも大きく、ファイルシステム内の最後のデータブロック番号より小さいかどうかを調べます。ブロック番号がこの範囲に含まれない場合は、不正なブロック番号と見なされます。

間接ブロックがファイルシステムに正しく書き込まれていないことが原因で、i ノード内に不正なブロック番号が発見されることがあります。fsck コマンドはその i ノードの消去を促すプロンプトを表示します。

i ノードサイズのチェック

各 i ノードには、参照するデータブロック数が入っています。実際のデータブロック数は、割り当て済みのデータブロック数と間接ブロック数の合計です。fsck コマンドはデータブロック数を計算し、そのブロック数を i ノードから使用されるブロック数と比較します。i ノードに不正なブロック数が入っていると、fsck コマンドはその修正を促すプロンプトを表示します。

各 i ノードには、64 ビットのサイズフィールドがあります。このフィールドは、i ノードに関連付けられたファイル内の文字数 (データバイト数) を示します。i ノードのサイズフィールドに整合性があるかどうかは、サイズフィールド内の文字数を使用して、i ノードに関連付けるべきブロック数を計算し、その結果を i ノードから使用される実際のブロック数と比較して概算でチェックされます。

間接ブロック

間接ブロックは i ノードによって所有されます。したがって、間接ブロック内の整合性が失われると、それを所有する i ノードが影響を受けます。不整合は、次の面からチェックされます。

また、間接ブロックに対しても整合性チェックが実行されます。

データブロック

i ノードは、3 種類のデータブロックを直接または間接に参照できます。参照されるブロックは、すべて同じ種類でなければなりません。次の 3 種類のデータブロックがあります。

プレーンデータブロックには、ファイルに格納される情報が入っています。シンボリックリンクデータブロックには、シンボリックリンクに格納されるパス名が入っています。ディレクトリデータブロックには、ディレクトリエントリが入っています。fsck コマンドはディレクトリデータブロックの妥当性しかチェックできません。

ディレクトリは、i ノードの mode フィールド内のエントリによって通常ファイルと区別されます。ディレクトリに関連付けらたデータブロックには、ディレクトリエントリが入っています。ディレクトリデータブロックの不整合は、次の面からチェックされます。

未割り当てディレクトリのチェック

ディレクトリデータブロック内の i ノード番号が未割り当て i ノードを指す場合、fsck コマンドはそのディレクトリエントリを削除します。この状況は、新しいディレクトリエントリが入っているデータブロックが変更されて書き出されたが、i ノードが書き込まれていない場合に発生します。また、警告なしに CPU が停止された場合にも発生します。

不正な i ノード番号のチェック

ディレクトリエントリの i ノード番号が i ノードリストの最後を超える位置を指す場合、fsck コマンドはそのディレクトリエントリを削除します。この状況は、不正なデータがディレクトリのデータブロックに書き込まれると発生します。

不正な「.」と「..」エントリ

.」ディレクトリの i ノード番号は、ディレクトリデータブロックの最初のエントリでなければなりません。また、それ自体を参照しなければなりません。つまり、その値はディレクトリデータブロックの i ノード番号に等しくなければなりません。

..」ディレクトリの i ノード番号は、ディレクトリデータブロックの第 2 のエントリでなければなりません。その値は、親ディレクトリの i ノード番号 (または、ディレクトリがルートディレクトリの場合は、それ自体の i ノード番号) に等しくなければなりません。

.」と「..」ディレクトリの i ノード番号が不正であれば、fsck コマンドは正しい値に置き換えます。ディレクトリへのハードリンクが複数個ある場合は、最初に見つかったハードリンクが「..」が指す実際の親であると見なされます。この場合、fsck コマンドは他の名前を削除するように促すプロンプトを表示します。

切り離されたディレクトリ

fsck コマンドは、ファイルシステム全体で参照関係をチェックします。ファイルシステムにリンクされていないディレクトリが見つかると、fsck コマンドはそのディレクトリをファイルシステムの lost+found ディレクトリにリンクします。この状況は、i ノードがファイルシステムに書き込まれたが、それに対応するディレクトリデータブロックが書き込まれていない場合にも発生することがあります。

通常データブロック

通常ファイルに関連付けられたデータブロックには、ファイルの内容が入っています。fsck コマンドは、通常ファイルのデータブロックの内容が有効かどうかはチェックしません。

fsck 要約メッセージ

fsck コマンドを対話式で実行して正常に終了すると、次のようなメッセージが表示されます。


# fsck /dev/rdsk/c0t0d0s7
** /dev/rdsk/c0t0d0s7
** Last Mounted on /export/home
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
2 files, 9 used, 2833540 free (20 frags, 354190 blocks,  0.0% fragmentation)
# 

fsck 出力の最後の行は、ファイルシステムについて次のような情報を記述します。

# files

使用中の i ノード数 

# used

使用中のフラグメント数 

# free

未使用のフラグメント数 

# frags

未使用の非ブロックフラグメント数 

# blocks

未使用の完全ブロック数 

% fragmentation

断片化の比率。ファイルシステム内の空きフラグメント x 100 / 全フラグメント 

フラグメントについては、「フラグメントサイズ」を参照してください。