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 という文字列で検索してみたところエラーの内容と対処方法について知ることができました。
エラー内容
カーネルはI/Oエラーなどによってジャーナルが異常終了していたかどうかをチェックする。その際、異常終了していたならば、本メッセージを出力する。
本メッセージ出力後,エラー処理がカーネルパニックするよう設定されていればカーネルパニックを起こす。そうでなければファイルシステムを強制的に読み取り専用にする。
対処方法
オプション設定
・ 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; }
コメントやシェアをお願いします!