检查已安装的模块和前缀

检查已安装的模块和前缀

我在运行 Debian wheezy 和 GRUB 1.99-27+deb7u3 的 4 x 1 TB 驱动器的服务器上遇到了问题。

sda 和 sdb 具有使用(Linux 软件)RAID1 镜像的分区,包括/boot。sdc 和 sdd 各有一个分区,镜像数据的 LVM 物理卷。GRUB 安装到 sda 和 sdb。我mdadm以前--fail使用--remove1 TB sdc,并用新的 2 TB ST2000NX0243 替换了旧驱动器(ST91000640NS)。

使用新的驱动器,GRUB 可以

GRUB loading.
Welcome to GRUB!

但无法显示菜单。sdc 上的驱动器指示灯持续亮起,因此 GRUB 核心可能正在尝试读取该驱动器,即使它不需要访问 /boot/grub。我尝试了两个相同型号的驱动器,它们都通过了测试,smartctl结果相同。sdc 驱动器托架为空时,一切正常启动。系统从实时 USB 启动,并且可以访问新驱动器,因此这不是硬件不兼容 (*)。我确信是 sdc 被移除了,并且没有迹象表明 BIOS 重新排序了驱动器。

(*)这可能不是一个安全的假设。查看答案。

因此,我有以下相关问题:

  1. 更改后的逻辑扇区大小(4096 字节而不是 512 字节)是否会导致问题,也许是 GRUB 核心内置的 RAID 支持?为什么我至少没有收到提示grub rescue>?4K 问题是否也会阻止将驱动器用于 Linux RAID?
  2. 解决这个问题最快的方法是什么?[以前的建议包括:我是否需要在新驱动器上重新安装 GRUB,在这种情况下如何安装?GRUB 救援 USB(由同一系统制作)会出现同样的问题吗?这是 GRUB 中已知的错误吗?我应该升级吗?这些问题的答案似乎是:否、是和否。] 我可以永久配置 Debian 使用的 GRUB 映像前缀吗?
  3. 如何调试 GRUB 的这个阶段?它可能对内置的模块很敏感,但如何找出这些模块呢?

我正在考虑使用 debug.cfg 和debug=all类似这样的内容:

grub-mkimage -c debug.cfg -o dcore.img configfile normal raid fs multiboot
grub-setup -c dcore.img /dev/sda

那样有用吗?(我在自己的回答中提到了第 3 点,但在我的案例中,挂起似乎发生在嵌入式配置执行之前。)

更多系统详细信息

为了便于理解,以下是部分lsblk输出:

NAME                             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb                                8:16   0 931.5G  0 disk  
├─sdb1                             8:17   0   957M  0 part  
│ └─md0                            9:0    0 956.9M  0 raid1 /boot
├─sdb2                             8:18   0   9.3G  0 part  
│ └─md1                            9:1    0   9.3G  0 raid1 /
├─sdb3                             8:19   0 279.4G  0 part  
│ └─md2                            9:2    0 279.4G  0 raid1 /var
└─sdb4                             8:20   0 641.9G  0 part  
  └─md3                            9:3    0 641.9G  0 raid1 
    ├─vg0-home (dm-0)            253:0    0   1.4T  0 lvm   /home
    └─vg0-swap (dm-2)            253:2    0    32G  0 lvm   [SWAP]
sdc                                8:32   0 931.5G  0 disk  
└─sdc1                             8:33   0 931.5G  0 part  
  └─md4                            9:4    0 931.5G  0 raid1 
    └─vg0-home (dm-0)            253:0    0   1.4T  0 lvm   /home
sdd                                8:48   0 931.5G  0 disk  
└─sdd1                             8:49   0 931.5G  0 part  
  └─md4                            9:4    0 931.5G  0 raid1 
    └─vg0-home (dm-0)            253:0    0   1.4T  0 lvm   /home
sda                                8:0    0 931.5G  0 disk  
├─sda1                             8:1    0   957M  0 part  
│ └─md0                            9:0    0 956.9M  0 raid1 /boot
├─sda2                             8:2    0   9.3G  0 part  
│ └─md1                            9:1    0   9.3G  0 raid1 /
├─sda3                             8:3    0 279.4G  0 part  
│ └─md2                            9:2    0 279.4G  0 raid1 /var
└─sda4                             8:4    0 641.9G  0 part  
  └─md3                            9:3    0 641.9G  0 raid1 
    ├─vg0-home (dm-0)            253:0    0   1.4T  0 lvm   /home
    └─vg0-swap (dm-2)            253:2    0    32G  0 lvm   [SWAP]

这是 2010 年之前的 BIOS,没有 EFI 功能。

不相关:在运行的系统上,以下内容给出了与我在 grub-install 上遇到的相同的来自 grub-probe 1.99 的 LVM 错误,尽管一切似乎都正常工作(这似乎在 GRUB 2.02 中已修复)。

# grub-fstest /dev/sda cp '(loop0,msdos1)/grub/grub.cfg' grub.cfg
error: unknown LVM metadata header.

以下答案中的调试方法显示安装到 sd[ab] 的图像的前缀是:

grub-mkimage -d /usr/lib/grub/i386-pc -O i386-pc --output=/boot/grub/core.img '--prefix=(mduuid/<UUID of sdN1>)/grub' biosdisk ext2 part_msdos part_msdos raid mdraid09

我不知道为什么“part_msdos”会重复。没有 gpt 表。md0(启动)使用 RAID 超级块版本 0.9,md1、md2 和 md4 也是如此(这些是旧阵列)。md3 是超级 1.2,但不应参与启动。


更新

感谢迄今为止的建议。经过进一步测试:

  • BIOS 已设置为使用 sda (ata1.00) 启动。使用 重新安装 GRUB 到所有驱动器后dpkg-reconfigure grub-pc,没有任何变化,当新驱动器通过 SATA 连接时,GRUB 仍然在菜单前挂起。无论如何,这不能由 /boot/grub 内容与核心映像不匹配来解释。同样,物理上重新排列驱动器也没有区别。
  • 在 Debian Jessie 中将 GRUB 升级到 2.02 只会造成Welcome to GRUB!无法打印消息 - 相反,它会改变图形模式。在相同条件下它仍然会挂起。
  • 挂起似乎发生在嵌入式配置设置变量之前debug。没有发出有用的调试信息。
  • 从可移动介质启动时,GRUB 会显示一个菜单,其中前缀不使用 UUID,这样就可以在驱动器实际存在的情况下启动系统。但是,驱动器的 TAB 枚举会冻结。正如预期的那样,从硬盘驱动器链式加载 GRUB 会像以前一样挂起。从grub-mkrescue同一系统制作的 USB 驱动器启动也会挂起。
  • 作为一个单独的故障,在实时系统 (Linux 3.2.0-4-amd64) 上,尝试通过内部 SATA 或 USB 将新的 4Kn 驱动器添加到 RAID1 阵列会导致Bad block number requested设备出现故障,随后 md 系统导致驱动器出现故障,BUG: unable to handle kernel paging request并且内核出现错误。(mdadm --remove表示故障元素正忙,并且 md-resync 进程不响应 SIGKILL。我没有尝试echo frozen > /sys/block/mdX/md/sync_action。通过 SATA 测试驱动器dd一切正常。)Linux MD 驱动程序肯定能够将 4Kn 驱动器与旧驱动器同步并且不使用 BIOS?

因此,解决方法可能包括将非 RAID 分区安装为/boot/;使用与设备相关的前缀安装 GRUB;或刷新 BIOS。最明智的做法可能是联系供应商更换驱动器。

换句话说,问题 3 有一个解决方案,但其无效性可能是 GRUB 功能请求的主题;问题 2 找错了方向,所以我修改了它;而问题 1,如果没有偏离主题太远的话,现在还另外涉及为什么该驱动器显然不能用于 Linux RAID。

我很乐意为对此做出合理解释的人颁发赏金,包括有关 RAID 重新同步错误、用于flashrom4Kn 支持的轶事、如何告诉 grub-install 不要使用 UUID 或任何相关的系统管理员提示等。

答案1

我将回答问题的第三部分,关于安装启用调试的 GRUB 的过程。我仍然希望得到有关问题可能出在哪里的明智建议,或者以最少的停机时间和最多的原因信息解决问题的策略。


一些一般要点:GRUB 提供了其他调试方法 -grub-mkrescue将生成一个包含您可能需要内置的所有模块的 .iso,因此就像实时 USB 一样,可用于尝试导航 RAID 阵列并尝试加载 .cfg 文件甚至内核。grub-emu大多数发行版都提供模拟器,但更侧重于菜单的外观。更高级的是标准 GRUB 模块gdb使用串行电缆进行调试

安装启用调试的 GRUB 的步骤

因此,获取调试消息的过程请参阅GRUB 手册第 6 节,但不详细。您可能要考虑的第一件事是通过串行控制台进行调试,并script在之前运行screen以记录调试消息。显然,您需要 root 权限。请注意,此答案中的驱动器布局不一定与问题相匹配,只是一个示例。假设正常(非调试)GRUB 已根据需要安装到其他驱动器:这只是将调试 GRUB 安装到您希望启动的驱动器的过程。(这意味着调试消息可以清楚地显示哪个驱动器正在启动。对于安装到 RAID 分区,前缀在两种情况下可能相同,因此您只需对/dev/sdaas运行相同的命令即可/dev/sdb。)

首先,检查现有 grub 文件的位置,/boot/grub或者更可能是/boot/grub/<platform>。在这种情况下,假设它们在/boot/grub/i386-pc/。我们不会修改已经存在的文件,而是添加启用调试的附加核心映像。如果文件.cfg丢失或已被修改,请使用 重新生成它们grub-mkconfig -o /boot/grub/grub.cfg

检查已安装的模块和前缀

显示哪些模块已编译到核心映像中的快捷方式是grub-install再次运行。这在 GRUB 2.02 中有效:

grub-install -v /dev/sda 2>&1 | grep '\(mkimage\|setup\)'

在没有 RAID 或 lvm 的简单情况下,这可能会显示类似 的列表ext2 part_gpt biosdisk。但是 GRUB 1.99 不使用-v详细,因此请使用--debug。我们将结合这个技巧不实际安装映像,以节省一点时间:

grub-install --debug --grub-setup=/bin/true /dev/sda 2>&1 | grep '\(-mkimage\|-setup\|true\)'

请注意,grub-install可以运行 shell 脚本来代替它调用的程序,因此我们可以执行以下操作:

# create grub-mkimage wrapper
cat > /usr/local/bin/grub-mkimage.sh <<"EOF"
echo Arguments to grub-mkimage: $*
/usr/bin/grub-mkimage $*
EOF
# create a dummy grub-setup
cat > /usr/local/bin/grub-setup.sh <<"EOF"
#!/bin/bash
echo Arguments are: $*
EOF
# run grub-install using the above
chmod u+x /usr/local/bin/grub-*.sh
grub-install --grub-mkimage=/usr/local/bin/grub-mkimage.sh \
  --grub-setup=/usr/local/bin/grub-setup.sh /dev/sda 2>&1 \
  | grep 'Arguments' | tee grub-args.txt

当然,路径可能会根据您的发行版和选择的 shell 而有所不同。

设置调试变量

我们现在创建一个可以debug.cfg使用调试设置调用的文件。(如果核心在此阶段遇到注释,则会产生非致命错误,因此我们不会使用任何注释。)

set pager=1
set debug='init modules disk ata,scsi,linuxefi,efi,badram,drivemap linux,fs,elf,dl,chain serial,usb,usb_keyboard,video'
set

,可以使用空格、;或 的任意组合|来分隔字符串内的模块名称。

我从 GRUB 2.02 源代码中提取了调试工具列表,并按语义对其进行了排序。'all'从解释器中生成了过多的内存信息scripting。对于特定文件系统(如“xfs”和“reiserfs”)以及“net”、“partition”和“loader”(对于我们在菜单之前感兴趣的内容,“loader”太晚了。如果我们可以获取菜单,我们可以在那里设置调试变量。)遗憾的是,“mdraid_linux”源代码中没有调试消息,但disk显示了最重要的操作。

pager如果您没有通过控制台捕获调试消息(例如使用),则需要变量来读取调试消息。script我发现如果pager不包含额外的模块(如sleep或) configfile,则无法正常工作,这会使图像的大小增加一倍以上。无论如何,调试环境变量都会生效。

安装

现在制作您想要调试的变体图像:

grub-mkimage -p '(,msdos3)/boot/grub' -c debug.cfg \
   -O i386-pc -o dcore.img -C auto ext2 part_msdos biosdisk

其中模块列表是来自 grub-install 的要调试的模块列表,以及包含sleep或您需要的任何其他内容。前缀-p应该从 的输出中复制grub-install,因为它显然对 GRUB 横幅之后发生的事情有很大影响。但是,您可能想尝试使用 GRUB 设备代码(如本例所示)而不是标准 UUID。您可以使用lsblk -o NAME,TYPE,FSTYPE,LABEL,SIZE,STATE,UUID或显示 UUID ls -l /dev/disk/by-id/,并在 RAID 驱动器上使用mdadm --detail /dev/sda

现在将刚刚创建的核心安装到正常启动的磁盘上:

cp dcore.img /boot/grub/i386-pc
grub-bios-setup -d /boot/grub/i386-pc -c dcore.img /dev/sda

对于 GRUB 2.0 之前的版本,该命令可能仍按照手册中的方式grub-bios-setup调用。grub-setup

重新启动。Welcome to GRUB!在显示菜单之前,您应该会看到随后几页的调试消息(也可能不显示)。

答案2

我现在回答我自己的问题 1.这是一个 4Kn(“高级格式”)问题吗?

是的。

4Kn 硬盘的支持并不像你想象的那么广泛;例如,它们与 Windows 7 或 GRUB 1 或许多 Intel 芯片组不兼容。就我而言,问题似乎出在主板上的 Intel 82801I Enterprise Southbridge 控制器芯片(ICH9 系列)上。我认为这也是驱动器即使通过 USB 也无法部分完成 md_resync 的原因。上述链接中的分析似乎发现 Linux ata_piix 驱动程序在 Intel ICH10 上为 4Kn 运行良好,尽管缺乏 Intel 的官方支持。我可能对 ICH9 发现了不同之处。我还没有测试驱动器是否可以在 AHCI 或 SAS 模式下工作。

只有主板制造商或其他进行过全面测试的人才有可能知道驱动器兼容性信息。我过早得出结论“这不是硬件不兼容”,因为简单的读写操作有效。这款主板的更新 BIOS 不支持 4Kn 是有原因的:因为主板不能可靠地做到这一点。

没有理由认为等效的 512e 驱动器在这些情况下不能工作。

答案3

要回答你的第二个问题,有一个与 raid1 相关的错误该问题已在 2.02 版中修复。

我希望它会有所帮助,即使我无法判断这个错误是否存在于 2.02~beta1(报告该错误的版本)之前。

编辑:此外,发布此文后我立即想到了一个问题:您的 RAID1 是软件 RAID 还是硬件 RAID?

相关内容