前言
周末例行升级 PVE 服务器,apt upgrade 跑完一切正常——直到重启后,屏幕上赫然出现了:
1 | GNU GRUB version 2.12-9+pmx2 |
所有虚拟机和 LXC 容器全部离线,整个 PVE 宿主机无法引导。这篇文章记录了从发现问题到完全修复的全过程,希望能帮到遇到同样问题的朋友。
故障现象
升级完成后重启,直接卡在 GRUB 命令行界面,无法进入正常的引导菜单。PVE 宿主机(192.168.31.99)ping 不通,上面的所有 LXC 容器和虚拟机全部失联。
升级日志中有一个容易被忽略的线索:
1 | Installing for x86_64-efi platform. |
grub-install 过程中有 file descriptor leaked 警告,说明 GRUB 安装过程中出现了异常。
紧急救援:手动引导进系统
既然卡在 grub> 命令行,说明 GRUB 本身是能加载的,只是找不到正确的引导配置。这意味着我们可以手动指定内核来启动系统。
在 grub> 提示符下执行:
1 | linux /boot/vmlinuz-6.17.13-7-pve root=/dev/mapper/pve-root ro quiet |
系统成功启动!用的是旧版本内核,但至少能进去了。
根因分析
进入系统后排查,发现了问题的根源:
1. proxmox-boot-tool 从未正确初始化
1 | # proxmox-boot-tool status |
这个文件从 PVE 安装那天起就不存在!这意味着每次内核更新后,系统都不会把新内核同步到 EFI 分区。
2. 之前能正常启动全靠运气
没有 proxmox-boot-uuids,EFI 分区上的旧 GRUB 二进制文件和旧 grub.cfg 碰巧还能找到旧内核,所以之前每次重启都没问题。
3. 这次升级把隐患暴露了
升级更新了 shim-helpers-amd64-signed 和 grub-efi-amd64,新的 GRUB 被写入 EFI 分区,但新的 grub.cfg 中引用了 7.x 内核的 LVM 路径,而 GRUB 的 LVM 模块因配置不对无法正确解析磁盘元数据,导致直接掉进 grub> 命令行。
4. 7.x 内核的 initrd 缺失
1 | ls /boot/initrd.img-7.0.2-6-pve |
vmlinuz 存在但 initrd 不存在,即使 GRUB 能找到内核也无法正常引导。
修复过程
Step 1: 初始化 proxmox-boot-tool
这是修复的核心步骤——让 PVE 正确识别 EFI 分区并建立同步机制:
1 | # 先卸载 EFI 分区(已挂载时 init 会报错) |
输出中会看到:
1 | Installing for x86_64-efi platform. |
验证修复:
1 | cat /etc/kernel/proxmox-boot-uuids |
Step 2: 生成缺失的 initrd
1 | update-initramfs -u -k 7.0.2-6-pve |
Step 3: 持久化内核启动参数
当前启动参数(IOMMU、ACS override 等)只存在于 /proc/cmdline,没有持久化配置文件,内核更新后可能丢失:
1 | echo "root=/dev/mapper/pve-root ro nomodeset quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction initcall_blacklist=sysfb_init" > /etc/kernel/cmdline |
Step 4: 清理旧内核
修复后发现 /boot 堆积了 18 个内核,占用 2.2G 空间:
1 | ls /boot/vmlinuz-* | wc -l |
只保留当前运行内核 + 一个备用 + 一个 6.x 回滚内核:
1 | apt purge -y proxmox-kernel-6.14 proxmox-kernel-6.14.11-{1,2,3,4,5,6,8,9}-pve-signed \ |
清理后 /boot 从 2.2G 降到 689M,保留 3 个内核:
| 内核 | 用途 |
|---|---|
| 7.0.2-6-pve | 当前运行(默认) |
| 7.0.2-2-pve | 7.x 备用 |
| 6.17.13-11-pve | 6.x 回滚 |
Step 5: 重启验证
1 | reboot |
重启后 GRUB 引导菜单正常显示,7.0.2-6-pve 内核成功启动,所有 LXC 容器自启动正常。
顺便修复:Locale 问题
修复过程中发现 PVE 的 locale 也有问题,perl 一直报 warning:
1 | perl: warning: Setting locale failed. |
1 | # 安装 locale 和中文字体 |
为什么之前升级没事?
翻看 dpkg 日志,这台 PVE 是从 9.0 全新安装的,之前的升级都是小版本更新(9.0→9.1→9.2),只更新应用包,不动引导层。这次升级恰好更新了 shim-helpers-amd64-signed 和 grub-efi-amd64,触发了 GRUB 重装,才把安装时遗留的隐患暴露出来。
简单说:之前能跑是运气好,这次升级把之前的债还了。
经验总结
- PVE 安装后检查
proxmox-boot-tool status,确保 EFI 分区已正确注册,不要等到出问题才发现 - 升级前看一眼升级内容,涉及 GRUB、内核、shim 的包要特别注意
- 升级后先别急着重启,检查
proxmox-boot-tool status和/boot/efi/EFI/proxmox/的时间戳,确认文件已更新 - 掌握 GRUB 手动引导命令,关键时刻能救命:
1
2
3linux /boot/vmlinuz-xxx root=/dev/mapper/pve-root ro quiet
initrd /boot/initrd.img-xxx
boot - 定期清理旧内核,避免
/boot空间不足和 grub 更新变慢 - 持久化
/etc/kernel/cmdline,确保 IOMMU 等关键启动参数不会丢失



