Grub Filter Not Found 修復:系統升級後的引導修復
文章目錄
症狀
如果你在伺服器啟動時遇到了提示 Grub Filter Not Found
並自動進入 Grub Rescue(救援模式)的問題,本文給出了
完整的解決方案。
昨天晚上我對時隔三五年沒有更新過的伺服器進行了升級,
把 Debian 10
經過兩次更新升級到了 Debian 12
。
隨著系統更新,PHP
也從 7.4
升級到了 8.2
;
Nginx
從 1.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
© 轉載需附帶本文連結,依 CC BY-NC-SA 4.0 釋出。