ファイルシステム破損の修復 - fsck の安全な実行手順
この記事で解決できること
fsckを データを壊さずに 実行する手順が分かる- マウント中の
/(root)を どう検査・修復するか が分かる -n/-y/-fの 使い分け と ext4 / XFS の違いが分かる
最重要ルール: マウント中(特に read-write)のファイルシステムに fsck を実行しない。稼働中のメタデータを書き換え、正常なファイルシステムまで破壊する。必ず先にアンマウントするか、読み取り専用で診断すること。
前提(対象環境)
- ディストリ: Ubuntu / Debian 系を想定(RHEL 系もコマンドはほぼ共通)
- ファイルシステム: ext4 を主対象(XFS / Btrfs は専用ツールを後述)
- root 権限がある(
sudo実行)
fsck とは何か、いつ使うのか?
結論:
fsckはファイルシステムの整合性を検査・修復するツール。Input/output error、Read-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 つ。
- アンマウントして実行(データ用パーティション向け)
- 読み取り専用(
-n)で診断のみ(書き込まないので比較的安全だが修復はしない) - 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か-p、cleanを無視して全検査するなら-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 -f か blkid で確認する。
$ 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 # 修復(公式は最終手段と位置づけ)
xfs_repair -L と btrfs check --repair はいずれもデータ損失を伴いうる最終手段。実行前にイメージ退避(ddrescue)を強く推奨する。
修復後に何を確認すればよいか?
結論: 終了コードを確認し、
lost+foundに救出されたファイルを点検、再マウントして読み書きを検証する。再発するならsmartctlでディスク健全性を疑う。
1. 終了コードを読む
fsck の終了コードはビットの組み合わせ。
$ sudo fsck -fy /dev/sdb1; echo "exit=$?"
| コード | 意味 |
|---|---|
| 0 | エラーなし |
| 1 | エラーを修復した(問題なし) |
| 2 | 修復したが 再起動が必要 |
| 4 | 未修復のエラーが残っている |
| 8 | 操作エラー |
0 か 1 なら正常完了。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_Ct や Current_Pending_Sector が増えていれば物理障害。fsck での延命より、ディスク交換とリストアを優先する。
やってはいけないこと(チェックリスト)
結論: マウント中の修復実行、FS 種別の取り違え、無検証の
-y、退避なしの-Lは事故の典型。
事故パターン
- マウント中の
/dev/...にいきなりfsck(read-write)を実行する - XFS に
fsck(実体fsck.xfs)を打って「直った」と誤認する -nの出力を読まずにいきなり-yで全修復する- 物理障害が疑わしいのにイメージ退避せず
xfs_repair -Lを実行する - スーパーブロック破損時にバックアップスーパーブロックを試さず諦める