ファイルシステム破損の修復 - fsck の安全な実行手順

ファイルシステム破損の修復 - fsck の安全な実行手順

この記事で解決できること

  • fsckデータを壊さずに 実行する手順が分かる
  • マウント中の /(root)を どう検査・修復するか が分かる
  • -n / -y / -f使い分け と ext4 / XFS の違いが分かる

前提(対象環境)

  • ディストリ: Ubuntu / Debian 系を想定(RHEL 系もコマンドはほぼ共通)
  • ファイルシステム: ext4 を主対象(XFS / Btrfs は専用ツールを後述)
  • root 権限がある(sudo 実行)

fsck とは何か、いつ使うのか?

結論: fsck はファイルシステムの整合性を検査・修復するツール。Input/output errorRead-only file system、起動時の fsck 失敗など、メタデータ破損が疑われるときに使う。

fsck(file system check)は、実体としては各ファイルシステム用の検査プログラム(ext 系なら e2fsck、XFS なら xfs_repair)を呼び分けるフロントエンド。スーパーブロック、inode テーブル、ディレクトリ構造、ブロックビットマップなどの整合性を検査し、矛盾を修復する。

使うべき典型的な状況:

  • ファイル操作で Input/output error が頻発する
  • 突然 Read-only file system に切り替わった(カーネルが破損を検知して保護した)
  • 起動時に「fsck failed」「Give root password for maintenance」で停止した
  • 不正なシャットダウン・電源断のあと、念のため整合性を確認したい

ジャーナリング FS(ext4 / XFS)は多くの軽微な不整合をマウント時に自動回復する。手動 fsck が要るのは、ジャーナル再生で直らない構造破損や、ハードウェア起因のケース。

なぜマウント中に fsck を実行してはいけないのか?

結論: マウント中の FS はカーネルがメタデータをキャッシュ・更新し続けている。そこへ fsck が別経路で書き込むと整合性が二重に壊れ、修復どころか致命的な破損になる。

稼働中のファイルシステムは、カーネルがバッファキャッシュ上で inode やビットマップを更新している。fsck はブロックデバイスを直接読み書きするため、両者の認識がずれた状態で fsck が「修復」を書き込むと、生きていた構造まで壊れる。

このため修復モードの fsck は、対象がマウント中だと警告して中断するのが既定動作。安全な経路は次の 3 つ。

  1. アンマウントして実行(データ用パーティション向け)
  2. 読み取り専用(-n)で診断のみ(書き込まないので比較的安全だが修復はしない)
  3. root FS は rescue mode / 起動時 fsck / live USB で実行(後述)
# まず対象がマウントされていないか確認
$ findmnt /dev/sdb1
$ lsblk -f

データ用パーティションを安全に検査・修復するには?

結論: アンマウント → -n で診断 → 必要なら -fy で修復、の順。ハード障害が疑わしいなら修復前に ddrescue でイメージを退避する。

1. アンマウントする

$ sudo umount /dev/sdb1

target is busy で外せない場合は、掴んでいるプロセスを特定する。

$ sudo fuser -vm /dev/sdb1
$ sudo lsof /dev/sdb1

2. まず読み取り専用で診断する(-n

-n はすべての質問に「no」と答え、一切書き込まない。被害状況の把握に使う。

$ sudo fsck -n /dev/sdb1

3. 障害が疑わしければイメージを退避する

物理障害(後述の Input/output error 多発など)が疑わしいときは、修復で状態が悪化する前に ddrescue でセクタを救出する。

$ sudo ddrescue /dev/sdb1 /mnt/backup/sdb1.img /mnt/backup/sdb1.log

4. 強制チェック + 自動修復する(-fy

$ sudo fsck -fy /dev/sdb1
  • -f: ジャーナル的に「clean」と判定された FS でも 強制的に 全チェック
  • -y: すべての修復質問に「yes」(対話なしで完走させる)

-y は対話を省く代わりに、判断を fsck に丸投げする。重要データでは、まず -n の出力を読み、被害が局所的なら個別に応答する fsck(オプションなし)を検討する。

マウント中の root(/)はどう検査するのか?

結論: 稼働中の / はアンマウントできない。①次回起動時に自動 fsck を予約、②fsck.mode=force で起動、③live USB から検査、のいずれかを使う。

root ファイルシステムは使用中なので通常はアンマウントできない。3 つの迂回路がある。

方法 A: 次回起動時に強制 fsck を予約する

systemd 環境では、カーネルパラメータかフラグファイルで起動時チェックを予約できる。

# Ubuntu/Debian: 次回起動時に 1 度だけ強制チェック
$ sudo touch /forcefsck
$ sudo reboot

/forcefsck は systemd の systemd-fsck が読み取り、起動シーケンス中(root がまだ read-only の段階)に検査を実行して自動削除する。

方法 B: GRUB でカーネルパラメータを渡す

起動時に GRUB メニューで e を押し、linux 行末に追記する。

fsck.mode=force fsck.repair=yes

fsck.repair=yes-y 相当(無人修復)、preflight 寄りに留めたいなら fsck.repair=preen-p 相当、安全な自動修復のみ)を使う。

方法 C: live USB / rescue メディアから検査する

root が深刻に壊れて起動できない場合は、Live USB で起動し、マウントせずに 検査する。

# Live 環境で(対象を絶対にマウントしない)
$ sudo fsck -fy /dev/sda2

緊急モード(emergency.target)に落ちた場合、/ が read-only でマウントされていることが多い。読み取り専用なら fsck の実行は比較的安全だが、確実を期すなら mount -o remount,ro / で read-only を明示してから実行する。

fsck の主要オプションをどう使い分けるか?

結論: 診断は -n、無人修復は -y-pclean を無視して全検査するなら -f。これらを状況で組み合わせる。

オプション 意味 使いどころ
-n 何も書かず、全質問に no まず被害把握(読み取り専用診断)
-y 全質問に yes(無人修復) 対話できない / 起動時
-p preen。安全な範囲だけ自動修復 起動時の標準モード
-f clean でも強制的に全チェック ジャーナルで隠れた破損を疑うとき
-c 不良ブロックを検査(badblocks 連携、ext のみ) 物理メディア劣化の疑い
-A /etc/fstab の全 FS を順に検査 起動シーケンスが内部利用
# ext 系は e2fsck が直接呼ばれる。明示する場合:
$ sudo e2fsck -fy /dev/sdb1

# スーパーブロックが壊れたらバックアップスーパーブロックを使う
$ sudo dumpe2fs /dev/sdb1 | grep -i superblock
$ sudo e2fsck -b 32768 /dev/sdb1

-p(preen)と -y同時指定しない。preen は「安全に直せるものだけ自動修復し、判断が要る破損が見つかったら中断してエラーコードを返す」設計。-y と混ぜると意図が衝突する。

ext4 以外(XFS / Btrfs)ではどうするのか?

結論: fsck.xfs は何もしない(XFS は xfs_repair を使う)。Btrfs は btrfs check。FS ごとに正しいツールを選ばないと修復にならない。

ファイルシステムの種類は lsblk -fblkid で確認する。

$ lsblk -f /dev/sdb1
$ sudo blkid /dev/sdb1

XFS の場合

XFS には伝統的な fsck は無い。/sbin/fsck.xfs は存在するが 何もしない(起動を妨げないためのダミー)。実際の修復は xfs_repair

# 必ずアンマウントしてから
$ sudo umount /dev/sdb1
# まずドライラン(-n は変更しない)
$ sudo xfs_repair -n /dev/sdb1
# 修復
$ sudo xfs_repair /dev/sdb1

ログが壊れて xfs_repair が拒否する場合のみ、最終手段として -L(ログのゼロ化)を使う。データ損失リスクがあるため安易に使わない。

Btrfs の場合

$ sudo umount /dev/sdb1
$ sudo btrfs check /dev/sdb1          # 診断
$ sudo btrfs check --repair /dev/sdb1 # 修復(公式は最終手段と位置づけ)

修復後に何を確認すればよいか?

結論: 終了コードを確認し、lost+found に救出されたファイルを点検、再マウントして読み書きを検証する。再発するなら smartctl でディスク健全性を疑う。

1. 終了コードを読む

fsck の終了コードはビットの組み合わせ。

$ sudo fsck -fy /dev/sdb1; echo "exit=$?"
コード 意味
0 エラーなし
1 エラーを修復した(問題なし)
2 修復したが 再起動が必要
4 未修復のエラーが残っている
8 操作エラー

01 なら正常完了。4 以上が残るなら再実行やイメージ退避を検討する。

2. lost+found を点検する

親ディレクトリを失った inode は各 FS ルートの lost+found/ に inode 番号名で回収される。

$ sudo mount /dev/sdb1 /mnt
$ sudo ls -l /mnt/lost+found/
$ sudo file /mnt/lost+found/*

3. 再マウントして読み書きを検証する

$ sudo mount /dev/sdb1 /mnt
$ touch /mnt/.write-test && rm /mnt/.write-test && echo "write OK"

4. 再発するならハードを疑う

$ sudo smartctl -a /dev/sdb | grep -iE 'reallocated|pending|uncorrect'
$ sudo dmesg | grep -iE 'I/O error|ata|medium error'

Reallocated_Sector_CtCurrent_Pending_Sector が増えていれば物理障害。fsck での延命より、ディスク交換とリストアを優先する。

やってはいけないこと(チェックリスト)

結論: マウント中の修復実行、FS 種別の取り違え、無検証の -y、退避なしの -L は事故の典型。

事故パターン

  • マウント中の /dev/... にいきなり fsck(read-write)を実行する
  • XFS に fsck(実体 fsck.xfs)を打って「直った」と誤認する
  • -n の出力を読まずにいきなり -y で全修復する
  • 物理障害が疑わしいのにイメージ退避せず xfs_repair -L を実行する
  • スーパーブロック破損時にバックアップスーパーブロックを試さず諦める

まとめ