如何修复 grub 启动错误:“未找到符号‘grub_calloc’

如何修复 grub 启动错误:“未找到符号‘grub_calloc’

刚刚在 20.04(Xubuntu)上运行了最新一批更新,现在我收到 GRUB 错误:

symbol 'grub_calloc' not found

我进入了“grub 救援”shell,但不知道该做什么才有用。对我来说,“符号未找到”意味着 grub 包存在某种构建错误,但我真的不知道 grub 是如何工作的。我注意到此更新还包含“固件”,不确定这是否相关。我最好的选择是从实时 CD 启动,看看我是否可以以某种方式将更新回滚到 grub?

编辑后添加:

好的,感谢很多人!以下是我认为我现在明白的内容。

  1. 在“非 UEFI”系统上,grub 分为两个独立部分安装。第一个部分(最基础的部分)是在启动时启动的部分。但对于其大部分功能,它需要第二个部分。这两个部分必须对齐 - 任何部分都不能要求另一个部分的任何功能,因为实际上不存在另一个部分。

    当这些部分未对齐且未提供函数 grub_calloc 时,会出现可见的运行时问题。我无法 100% 确定 grub_calloc 是属于第二个较大的部分还是第一个部分。我本来以为是第二个,但 grub 构建系统是一项相当复杂的工作,所以我不知道 :)。

  2. 问题的根本原因是 grub 更新没有确保两个都部分已更新。理想情况下,不这样做会导致 grub 安装失败,并且系统应恢复到安全状态。但这并没有发生。

    这对我来说实际上仍然有点神秘。默认情况下,更新需要做的就是将每个部分放在当前部分所在的位置,因为这显然是有效的。如果安装位置/驱动器是由配置驱动的,并且无法到达其中一个位置,那么配置数据和实际情况之间就会出现不匹配的情况。只要各部分之间没有引入新的依赖关系,这可能不会显示为问题。

所有解决方案都涉及重新安装 grub,以确保两个部分对齐。实际上没有必要返回到以前的版本(尽管这样做可行),因为损坏的不是 grub 运行时本身。有很多方法可以实现这一点,具体取决于您的环境,但运行 Boot-repair live disk 对我来说很有效。

为了避免将来出现这种错位,确保系统上的 grub 安装程序配置为安装到正确的设备可能会很有用。

本次更新修复了一些重要的错误(请参阅 Ubuntu 安全通知 4432)。如果您已恢复 grub 来解决此问题,请注意您会遇到这些问题。

答案1

在简单的 2 个分区安装中使用 Linux Mint 19.3 bios grub 设置在简单的 2 个分区安装中。

GRUB2 更新后,机器在重启时崩溃并进入救援模式。

error: symbol 'grub_calloc' not found    

为了恢复 GRUB,我启动了 Linux Mint 19.3 Live USB 驱动器并在终端中发出以下命令:

sudo mount /dev/sda1  /mnt    
sudo grub-install --root-directory=/mnt/  /dev/sda    

重新启动后桌面即可正常显示。

答案2

我和 Rick N 的情况一样。有 2 个磁盘,但它们不在 RAID 中。我使用了这个工具https://sourceforge.net/p/boot-repair-cd/home/Home/

我在 Ubuntu 帮助页面找到了这个工具https://help.ubuntu.com/community/Boot-Repair

它似乎安装了一些以前没有的 GUI 功能(据我所知,这个系统一直是仅限 CLI 的),但我再次运行,这是重要的部分。

在此感谢其他人的指导。

答案3

这是我们为解决这个问题所做的一些工作AzureUbuntu 18.04 服务器

问题似乎是升级 grub 失败。安全升级后无人值守重启时会发生问题。

然后,我们从针对此问题的 Ubuntu 错误上发布的评论中找到了以下说明:https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1889509/comments/16

请注意,我对此做了一些修改,下面是我在稍后对该错误的评论中提到的修改版本(https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1889509/comments/45

对于 Azure 用户(同样适用于任何云,只需进行少量更改)在寻找此错误时,恢复步骤如下:

使用 AzCli 部署恢复虚拟机,或者将受影响的操作系统虚拟机磁盘的副本附加到救援虚拟机。完成后,连接到救援虚拟机并:

$ sudo su -
# lsblk <-- this will identify the attached disk, usualy /dev/sdc, but can be /dev/sda or /dev/sdb
# mkdir /rescue
# mount /dev/sdc1 /rescue <-- this assumes /dev/sdc is the attached data disk
# for fs in {proc,sys,tmp,dev}; do mount -o bind /$fs /rescue/$fs; done
# cd /rescue
# chroot /rescue
# grub-install /dev/sdc <-- this assumes /dev/sdc is the attached data disk
# exit
# cd /
# for fs in {proc,sys,tmp,dev}; do umount /rescue/$fs; done
# umount /rescue
# rmdir /rescue

现在您应该能够将修复后的磁盘交换回受影响的虚拟机。

首次尝试修复

我们发现以下 Azure 文档链接很有用:

好的,一步一步来:

部署恢复 VM

这是什么类型的虚拟机?尝试创建一个常规的 Ubuntu 18.04 LTS 虚拟机。这就是你想要的 - 创建一个与损坏的服务器相匹配的恢复虚拟机

除了连接到现有磁盘外,一切正常。看起来您无法连接到磁盘,除非您先以某种方式将其从另一台机器移走(将其分离)。

将受影响的操作系统虚拟机磁盘的副本附加到救援虚拟机。

要创建副本,您可以拍摄磁盘的只读快照,然后基于快照创建新的托管磁盘。

您需要快照的唯一磁盘是操作系统磁盘,而不是数据磁盘。

您可以创建没有数据磁盘的恢复虚拟机,只需自动创建的操作系统磁盘。

然后,您可以将托管磁盘操作系统快照作为数据磁盘添加到恢复虚拟机。

然后您可以登录恢复虚拟机并按照上述步骤操作。

所有步骤均顺利完成 - 我们可以复制并粘贴准确的消息

关键行正在运行grub-install您应该看到以下内容:

root@recoveryVM:/# grub-install /dev/sdc
Installing for i386-pc platform.
Installation finished. No error reported.

然后注销并停止虚拟机。

然后,您可以进入损坏的虚拟机,并在虚拟机的“磁盘”部分下选择“交换操作系统磁盘”。

Reddit 迷你帖子解释了所需的坐骑:https://www.reddit.com/r/Ubuntu/comments/i0vlf0/repair_grub_boot_error_symbol_grub_calloc_not/

重复上述步骤

  1. 对“损坏的”操作系统磁盘进行快照(postfix _snap
  2. 从快照创建托管磁盘 -这必须与旧的操作系统磁盘相同等级因为我们将用这个(后缀_recovery)完全替换旧的操作系统磁盘 - 源类型快照并使用刚刚创建的快照
  3. 将托管操作系统磁盘附加到恢复虚拟机(无需停止/启动恢复虚拟机)
  4. 通过 SSH 登录,运行恢复步骤,再次注销
  5. 从恢复虚拟机中分离托管操作系统磁盘(编辑虚拟机磁盘并分离恢复操作系统磁盘)
  6. 停止“损坏的”虚拟机(可能没有必要,因为操作系统磁盘交换会停止它)
  7. 在“损坏”的虚拟机磁盘中,单击“交换操作系统磁盘”,然后选择恢复操作系统磁盘作为替换
  8. 启动“恢复”的虚拟机
  9. 清理快照 - 但暂时保留损坏的操作系统磁盘 - 提醒大约一个月后也将其删除

最后关闭恢复虚拟机并在一个月后将其删除

某些服务器存在问题

我们遇到了一个问题,即两个服务器的修复都不起作用。所有命令都成功完成 - 但在启动虚拟机时我们遇到了相同的 grub 错误。

进一步调查显示/dev/sda/dev/sdb/dev/sdc在恢复虚拟机上发生了变化。我不知道为什么会发生这种情况。

这就是你应该lsblk在 sudo(但非 chroot)模式下运行时获取(注意sda是恢复 VM 操作系统,并且sdc附加了要恢复的数据磁盘):

NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda       8:0    0   30G  0 disk
├─sda1    8:1    0 29.9G  0 part /
├─sda14   8:14   0    4M  0 part
└─sda15   8:15   0  106M  0 part /boot/efi
sdb       8:16   0   16G  0 disk
└─sdb1    8:17   0   16G  0 part /mnt
sdc       8:32   0   30G  0 disk
├─sdc1    8:33   0 29.9G  0 part
├─sdc14   8:46   0    4M  0 part
└─sdc15   8:47   0  106M  0 part
sr0      11:0    1  628K  0 rom

答案4

这里与 linux mint 20 cinnamon 和 bios(而不是 EFI)grub 设置相同。

有人能提供帮助吗?

编辑:我找到了问题的根本原因和解决方案。我的情况的根本原因是我有一个由 4 个磁盘组成的 RAID5,我猜想,软件包升级期间的自动 grub 安装仅更新了“disk2”。由于我的 bios 是从“disk1”启动的,因此它有一个较旧的 grub,因此无法启动。我将 bios 更改为一次从每个磁盘启动(即:“disk1”、“disk2”、“disk3”、“disk4”),唯一正常工作的是“disk2”。

为了解决这个问题,我只是从“disk2”启动并执行:

sudo grub-install /dev/sda  
sudo grub-install /dev/sdc  
sudo grub-install /dev/sdd  
# ("disk2" is /dev/sdb and it was already working properly so I didn't install grub in that disk)  
sudo update-grub  
sudo reboot  

然后重新配置我的 BIOS 以从“磁盘 1”重新启动。这样,每次更新 grub 时我都会遇到类似的问题,这将提醒我 grub-install、grub-update 其余磁盘。

我希望这能帮助其他处于同样境况的人。

相关内容