環境
OS:Ubuntu 22.04.5 LTS
✅ TL;DR(結論)
Ubuntuのカーネルアップデートに伴い、新カーネル用の initrd.img が /boot に生成されておらず、GRUBはそれを使おうとして起動に失敗しました。
LiveUSB + chrootで以下のコマンドを実行することで修復できます:
sudo mount /dev/nvme0n1p3 /mnt
for d in /dev /proc /sys /run; do sudo mount --bind $d /mnt$d; done
sudo chroot /mnt
以下のコマンドでGRUBで使おうとしているカーネルのバージョンを確認.
cat /mnt/boot/grub/grub.cfg | grep -Ei 'menuentry|linux|initrd'
menuentry 'Ubuntu' ... {
...
linux /boot/vmlinuz-6.8.0-64-generic root=/dev/nvme0n1p3 ro quiet splash $vt_handoff
# この次に initrd /boot/initrd.img-6.8.0-64-generic という行があるべき
}
この出力の6.8.0-64-generic がカーネルのバージョンにあたり,それに対応するinitrdが存在する必要がある.以下のように実行し,再構築する.
update-initramfs -c -k 6.8.0-64-generic # カーネルのバージョンに合わせる
update-grub
再起動すれば復旧するはずです。
症状
GPUでの処理が上手く動作しなかったため,再起動し,OSを選択(Ubuntu)すると黒画面でフリーズしてしまう.
試したこと
1. セーフグラフィックスモードで起動
- セーフグラフィックスモードとはグラフィックドライバ関連で起動できない時に問題を回避するための応急処置用の起動オプション.
-
nomodesetという特殊な設定をカーネルに渡すことでGPUのドライバを読み込むのをやめ,CPUで描画する.
手法
- PC起動後,「OS選択(Ubuntu)」の画面で止まったら
Escキーを連打
⇒GRUBメニュー - 「Ubuntu」で選択した状態で
eキーを押して編集モードへ -
linuxで始まる行の最後にquiet splashをnomodesetに変更 -
F10またはCtrl + Xで起動
結果
/dev/root: Can't open blockdev
VFS: Cannot open root device "/dev/nvme0n1p3" or unknown-block(0,0): error -6
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
と表示され、カーネルパニックで停止した.
これはカーネルが/dev/nvme0n1p3(ルートパーティション)を認識できず,ファイルシステムをマウントできないという問題だそう.
2. initramfsの再構築(失敗)
この問題の原因として考えられるのが,initramfsにNVMeドライバが含まれていないということ.Ubuntu起動時,カーネルはrootファイルシステムを読み込む前にintiramfsという一時的なRAMディスクを展開し,中に含まれるNVMeドライバを読み込んでNVMeドライブにアクセスする.しかし,今回何らかの理由でinitramfsの中にNVMeが含まれていなかったか,ファイルが壊れている可能性がある.
そのため,このinitramfsを再構築して解決を試みる.
まずはLiveUSBで修復してみる.USBブートで起動後「Ubuntuを試す(Try Ubuntu)」を選択する.が,以下のようなメッセージが出てしまった.
Oh no! Something has gone wrong
これはGUIの起動に失敗したときに表示されるらしい.そこで,再び1の手法で回避してみる.
手法
-
1. セーフグラフィックスモードで起動と同様の方法でLiveUSBで起動 -
ターミナルを開いて,以下のコマンドでパーティションを確認
lsblk -f/dev/nvme0n1p3のようなエントリがext4で表示されていれば,それがUbuntuのルートパーティションである. -
パーティションをマウント
# Ubuntuルートをマウント sudo mount /dev/nvme0n1p3 /mnt # 必要なシステムディレクトリもマウント for dir in /dev /proc /sys /run; do sudo mount --bind $dir /mnt$dir done -
ルート環境に入る
sudo chroot /mnt -
修復
# initramfs(初期RAMディスク)を再生成 update-initramfs -u -k all # GRUBの設定を再構築 update-grub -
セーフグラフィックスモードで再起動
結果
解決せず,全く同じKernel panic -not syncing: VFS: Unable to mount root fs on unknown-block(0,0)が出力されてしまった.
3. GRUBの設定ファイル確認
OSの起動に関する具体的な指示が書かれているGRUB設定ファイル(grub.cfg)を確認した.
手法
設定ファイルから起動部分を抜粋
cat /mnt/boot/grub/grub.cfg | grep -Ei 'menuentry|linux|initrd'
結果
menuentry 'Ubuntu' ... {
...
linux /boot/vmlinuz-6.8.0-64-generic root=/dev/nvme0n1p3 ro quiet splash $vt_handoff
# この次に initrd /boot/initrd.img-.... という行があるべき
}
GRUB設定ファイルの一番重要な通常の起動メニュー(menuentry 'Ubuntu’)の中に本来あるべきinitrdという行が欠落していた.initrdはディスクを読み込むためのNVMeドライバなど,軌道に不可欠なドライバ群を読み込むための重要な命令である.この行がないため,カーネル(vmlinuz)が読み込まれた後,ドライバが一切読み込まれていなかった模様.
今回はカーネルのバージョンからinitrd.img-6.8.0-64-generic が必要である.
4. initrdが存在するか確認
手法
以下のコマンドを実行した.
ls -lR /mnt/boot
結果
initrd.img
initrd.img-6.8.0-60-generic
initrd.img.old
どうやらバージョンの古いものしかなかったよう.カーネルのアップデートが不完全に終わり,GRUBの設定と実際のファイルに不整合が生じた可能性がある.
5. initrdファイルの再生成(成功)
手法
-
1. セーフグラフィックスモードで起動と同様の方法でLiveUSBで起動 -
パーティションをマウントし,ルート環境に移動
# Ubuntuルートをマウント sudo mount /dev/nvme0n1p3 /mnt # 必要なシステムディレクトリもマウント for dir in /dev /proc /sys /run; do sudo mount --bind $dir /mnt$dir done # ルート環境に入る sudo chroot /mnt -
修復
# 存在しない initrd.img-6.8.0-64-generic を再生成 update-initramfs -c -k 6.8.0-64-generic # GRUBの設定を再構築 update-grub -
再起動
結果
上手く再起動できた.
まとめ
今回のKernel Panicが生じていた原因は新しいカーネルのinitrd.imgが/bootに存在しなかったためである.
おそらくapt updateなどによってlinux-image-6.8.0-64-generic がインストールされたが,このときinitrd.img-6.8.0-64-generic の生成が失敗していた可能性がある.
その原因として考えられるのは,
-
/bootが容量不足 -
initramfs-toolsの不具合 - インストール途中で中断
などがあるようである.