EXT3-fs error (device dev): ext3_journal_start_sb : Detected aborted journal

先日のことですが、あるサーバで DISK 障害が発生したために DISK 交換を行いサーバのリブートを行いました。すると /var/log/messages に見慣れないエラーメッセージが出力され、DISK が Read Only な状態になってしまいました。

Dec  1 13:34:53 srv01 kernel: ext3_abort called.
Dec  1 13:34:53 srv01 kernel: EXT3-fs error (device sdb1): ext3_journal_start_sb: Detected aborted journal
Dec  1 13:34:53 srv01 kernel: Remounting filesystem read-only

見慣れないエラーを見かけるとちょっとワクワクしちゃうのは変態エンジニアって証拠でしょうか・・・(〃▽〃)
Linux の kernel 系のエラーメッセージを調べるのに便利なサイトが OSS Message Pedia です。

- スポンサーリンク -

ext3_journal_start_sb という文字列で検索してみたところエラーの内容と対処方法について知ることができました。

エラー内容

EXT3(third extended file system)でext3_journal_start_sb関数実行時に異常終了したジャーナルを検知した。そのため,ファイルシステムに設定されているエラー処理を実行する。
カーネルはI/Oエラーなどによってジャーナルが異常終了していたかどうかをチェックする。その際、異常終了していたならば、本メッセージを出力する。
本メッセージ出力後,エラー処理がカーネルパニックするよう設定されていればカーネルパニックを起こす。そうでなければファイルシステムを強制的に読み取り専用にする。

対処方法

ファイルシステムが異常状態である可能性があるため, badblocksコマンド等を利用しハードディスクが壊れていないか確認する。ハードディスクが壊れていない場合は,システムを再起動する。システム再起動後も現象が発生する場合は,対象ディスクのバックアップを取得後,fsckを実施する。それでも回復しない場合は,ファイルシステムを再フォーマットし,バックアップしたデータを復旧する。

オプション設定

tune2fsによりエラー処理を設定することができる。(eオプション)エラー処理の種類は以下の通り。
・ continue:通常の実行を継続する
・ remount-ro:ファイルシステムを読み取り専用でマウントしなおす
・ panic:カーネルパニックを起こす
設定値は,tune2fsのlオプションで見ることができる。(出力時、Errors behaviorの欄を参照)

今回は保守ベンダーの調査からハードウェア障害でないことが確認できているので、DISK を umount して fsck を実行することとしました。ここ重要ポイントです。アンマウントしてからじゃないとファイルシステムが破損する可能性が高いので注意しましょう。

umount /dev/sdb1
fsck /dev/sdb1

実際にファイルの破損がある場合には、修復するかメッセージが表示され、修復したファイルなどは /lost+found 配下に書き出されますが、今回は整合性が崩れていただけで破損箇所はなかったため、fsck を実行してサーバ再起動を行うだけで正常な状態で起動することができました。ファイルが破損していた場合には、相当影響が大きなサーバだっただけに一安心しました。

さて、せっかくの機会なので kernel のソースコードでもエラー箇所を特定しておきました。今回のエラーパターンが発生した箇所を赤文字にしておきました。結局ジャーナルの読み込みでエラーが発生したとしかわかりませんでした。

\linux-2.6.36\linux-2.6.36\fs\ext3\super.c

handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks)
{
	journal_t *journal;

	if (sb->s_flags & MS_RDONLY)
		return ERR_PTR(-EROFS);

	/* Special case here: if the journal has aborted behind our
	 * backs (eg. EIO in the commit thread), then we still need to
	 * take the FS itself readonly cleanly. */
	journal = EXT3_SB(sb)->s_journal;
	if (is_journal_aborted(journal)) {
		ext3_abort(sb, __func__,
			   "Detected aborted journal");
		return ERR_PTR(-EROFS);
	}

	return journal_start(journal, nblocks);
}

\linux-2.6.36\linux-2.6.36\fs\ext3\resize.c

	/* We will update the superblock, one block bitmap, and
	 * one group descriptor via ext3_free_blocks().
	 */
	handle = ext3_journal_start_sb(sb, 3);
	if (IS_ERR(handle)) {
		err = PTR_ERR(handle);
		ext3_warning(sb, __func__, "error %d on journal start",err);
		goto exit_put;
	}
- スポンサーリンク -