Grub Filter Not Found 修復:系統升級後的引導修復

文章目錄

症狀

如果你在伺服器啟動時遇到了提示 Grub Filter Not Found 並自動進入 Grub Rescue(救援模式)的問題,本文給出了 完整的解決方案。

昨天晚上我對時隔三五年沒有更新過的伺服器進行了升級, 把 Debian 10 經過兩次更新升級到了 Debian 12。 隨著系統更新,PHP 也從 7.4 升級到了 8.2Nginx1.15 升級到了 1.22.1

升級之後,系統執行一切正常,所有網站也都能正常訪問。 為了保證長期執行的穩定性(我的伺服器常年不重啟),我打算 在伺服器升級後順道重啟一次。結果這下可好,重啟後直接無法使用了。

首先是 SSH 無法連線,然後透過雲伺服器的 Web 終端登入後, 發現螢幕顯示內容如下:

error: symbol 'grub_file_filters' not found. 
Entering rescue mode... 
grub rescue>

原因分析

迅速分析和查閱了相關的資料,發現這個問題應該是在系統更新 過程中破壞了引導的 grub 配置造成的。網上大部分的資料都 需要掛載系統恢復光碟映象來執行 grub-install,來完成引導 的修復。但對於雲伺服器,這是不可行的, 因為你無法插入 修復光碟映象。

如果你和我一樣無法掛載系統恢復光碟映象,我提供兩個解決思路。

方法一:雲盤掛載在救援主機

阿里雲、AWS 等伺服器支援掛載雲盤到其他主機。而有些雲伺服器, 例如青雲,提供了救援主機功能。你可以利用這些功能把受損的 系統盤掛載在一個可以正常啟動的伺服器上,然後在這個伺服器上修復 你的引導。

具體步驟如下:

# 切換到 root 許可權
sudo su

# 查詢被掛載的損壞的系統盤的盼復
fdisk -l

# 把損壞的系統盤的一些內容掛載到可以正常啟動的伺服器
# 這裡假設你在 fdisk 中查詢到的系統碟符為 sdc,
# 且系統掛載在其中的 sdc1:
mount /dev/sdc1 /mnt
mount --bind /dev /mnt/dev
mount --bind /dev/pts /mnt/dev/pts
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys

chroot /mnt

# 執行引導修復
grub-install /dev/sda

假如一切順利,系統會提示:

Installation finished. No error reported.

此時別忘了取消掛載:

# 退出 chroot
exit

# 取消掛載
umount /mnt/dev/pts
umount /mnt/dev
umount /mnt/proc
umount /mnt/sys
umount /mnt

然後把雲盤重新掛載回損壞的主機,重啟該主機,應該可以進入系統。

方法二:手工引導系統

如果你和我一樣倒黴,在執行 grub-install 時不成功,或者你沒法 掛載系統盤到其他可用的主機,還有一個辦法,那就是手工透過 grub 引導 進入系統,然後在系統內修復 grub 安裝。

首先執行你的主機,在出現下面的提示時:

error: symbol 'grub_file_filters' not found. 
Entering rescue mode... 
grub rescue>

又或者你進入的是 grub 命令列,而不是 grub rescue,也是可以的:

grub>

小心地按照下列步驟執行命令。

首先執行一個可以讓長輸出進行分頁的指令:

grub> set pager=1

不要有多餘的空格。

然後列出自己的磁碟:

grub> ls
(hd0) (hd0,msdos2) (hd0,msdos1)

怎麼出來了一個 msdos?這說明你的磁碟使用的是以前的 MS-DOS 分割槽模式,而不是 GPT 模式。這不重要。

我們的重點是找到你的啟動盤。比如我們嘗試 (hd0,1) 這個盤:

grub> ls (hd0,1)/
lost+found/ bin/ boot/ cdrom/ dev/ etc/ home/  lib/
lib64/ media/ mnt/ opt/ proc/ root/ run/ sbin/ 
srv/ sys/ tmp/ usr/ var/ vmlinuz vmlinuz.old 
initrd.img initrd.img.old

透過 ls 指令,你可以確認這個盤的內容以分析它是不是我們的啟動盤。 你也可以透過 cat 指令進一步確認系統的版本號:

grub> cat (hd0,1)/etc/issue
Ubuntu 14.04 LTS n l

假如你有多個系統或者多個碟符,一定不要搞錯。

接下來手工引導系統(先別急著複製執行,看解釋):

# 看完解釋後再執行哦
grub> set root=(hd0,1)
grub> linux /boot/vmlinuz-3.13.0-29-generic root=/dev/sda1
grub> initrd /boot/initrd.img-3.13.0-29-generic
grub> boot

注意:

  • 這裡的 (hd0,1) 是你要修復引導的實際磁碟,要反覆核實清楚;
  • 這裡的 /boot/vmlinuz-3.13.0-29-generic 只是一個例項, 你執行的時候,打出 /root/vmlinuz,然後按 Tab 鍵選出你 實際的 linux 核心版本號,不要照抄。如果有多個核心版本,一般 選最新的。
  • 這裡 /boot/initrd.img-3.13.0-29-generic 同上。

現在你應該可以進入系統了。

注意,這時候別急著高興,趕緊修復 grub 引導,不然下次重啟還是無法正常進入:

# 更新 grub
> update-grub
# 系統可能輸出類似內容:
# Generating grub configuration file ...
# Found background: /usr/share/images/grub/Apollo_17_The_Last_Moon_Shot_Edit1.tga
# Found background image: /usr/share/images/grub/Apollo_17_The_Last_Moon_Shot_Edit1.tga
# Found linux image: /boot/vmlinuz-3.13.0-29-generic
# Found initrd image: /boot/initrd.img-3.13.0-29-generic
# Found linux image: /boot/vmlinuz-3.13.0-27-generic
# Found initrd image: /boot/initrd.img-3.13.0-27-generic
# Found linux image: /boot/vmlinuz-3.13.0-24-generic
# Found initrd image: /boot/initrd.img-3.13.0-24-generic
# Found memtest86+ image: /boot/memtest86+.elf
# Found memtest86+ image: /boot/memtest86+.bin
# done

# 重新安裝 grub
> grub-install /dev/sda
# 可能的輸出:
# Installing for i386-pc platform.
# Installation finished. No error reported.

這時候你的系統應該完全恢復了。

參考資料: Classic SysAdmin: How to Rescue a Non-booting GRUB 2 on Linux

当前页阅读量为: