为什么我的 MD RAID 1 上的备份 GPT 分区表已损坏?为什么内核一次只能看到 1 个随机选择的成员磁盘?

为什么我的 MD RAID 1 上的备份 GPT 分区表已损坏?为什么内核一次只能看到 1 个随机选择的成员磁盘?

我有 2 个磁盘,每个磁盘大小 1TB,并且它们都是 MD RAID-1 阵列的成员,如以下命令创建的:

mdadm --create /dev/md0 /dev/sda /dev/sde --level=1 --metadata=1.0

该参数--metadata=1.0指示内核使用位于物理磁盘末尾的特定 MD RAID 标头。

我做出这个决定的原因是因为该阵列中的磁盘必须可由不支持 MD RAID 的 UEFI 启动;因此,从 UEFI 的角度来看,它可以选择任何成员磁盘并从中启动,因为它会在磁盘的开头找到 GPT 分区表,就像任何不属于 RAID 设置的普通磁盘一样。

内核和 initramfs 一起放置在 UEFI 分区中。 UEFI从UEFI系统选择的任何成员磁盘加载内核,而UEFI对RAID一无所知。这已经有效,因为所有成员磁盘都是相同的(感谢它们之上的 RAID 1 镜像)。

一旦支持 MD RAID 的内核加载,它就会读取 RAID 元数据(位于磁盘末尾),并自动将它们组装到逻辑映射器设备文件中/dev/md0。这有点作品。

目前,我有两个问题:

  • 问题一:内核检测到MD RAID阵列的存在,这证明内核正在读取MD RAID头。

    但问题是它只显示1个成员盘,不显示其他成员盘。选择哪个磁盘会在重新启动时随机洗牌,但仅显示 1 个。

    从逻辑上讲,这意味着内核在某种程度上没有读取其他磁盘之一的元数据标头,因此不知道它们的存在。即使,比如说,mdadm --examine /dev/sda表明它确实是 RAID 成员(假设这/dev/sda是这次重新启动时不幸的成员)。

    尝试将不幸的磁盘添加到阵列时,会导致mdadm显示磁盘正忙。

    此外,不幸的磁盘没有得到任何镜像。例如,如果我在重新启动时编辑一些文件并/dev/sde显示,那么如果我再次重新启动以显示另一个文件,那么我将看不到在显示/dev/sda时上次重新启动期间所做的任何更改。/dev/sde这表明没有镜像。

  • 问题2: fdisk /dev/md0备份GPT 表已损坏。对于 GPT,备份表存在于磁盘的末尾。

    我不知道这是什么原因。正在fdisk窥视结尾身体的磁盘/dev/sda/dev/sde?它是如何知道它们的(如果知道的话)?毕竟,我只是给了它一个/dev/md0应该抽象物理成员磁盘的逻辑映射器设备。我想它的/dev/md0大小也会更小,因为它应该减去 MD RAID 放入的元数据身体的磁盘。

问题:到底是怎么回事?如何解决这两个问题呢?


背景:我使用的是 Gentoo Linux 最新的稳定版本,本周进行了全新安装,使用了 systemd 和 systemd-boot(以前称为 Gummiboot)。

答案1

我只是总结我的问题下评论部分的讨论作为未来的参考(感谢弗罗斯特舒茨)。


长话短说:

  • 至于在initramfs中加载RAID:因为我用来dracut构建我的initramfs,所以我必须添加rd.auto=1/etc/kernel/cmdline,以便dracut知道挂载虚拟设备,例如RAID。默认为rd.auto=0(这是设置不起作用的原因)。
  • 至于ESP:使用两个独立的ESP分区,不使用RAID;例如,在不同的物理磁盘上安装/boot和,并且。然后在它们之间实现您自己的 EPS 同步。/boot_backup/dev/sdX1/dev/sdY1

以及其中的链接表明,Lennart Poettering 希望 Systemd 执行检查 ESP 的额外工作,并在 RAID 化时彻底拒绝写入它,即使系统管理员知道他在做什么(例如,没有竞争的操作系统)在 ESP 上,--metadata=1.0使用该选项是为了让 UEFI 系统不会觉得它是 RAID1-ed)。

原因是这样的 RAID1 设置将使操作系统镜像整个 ESP,其他操作系统也可能使用该 ESP。其他操作系统可能会在没有此 MD RAID(特定于 Linux)的情况下写入其 ESP 分区,但会直接写入各个磁盘,这在这些情况下可能会导致冲突。

虽然我发现这样的设置并不适合所有人,但我仍然不明白为什么 Systemd 的职责是让父级系统管理员在知道自己在做什么的情况下禁止他们做他们想做的事情。这个育儿似乎只是一个额外的代码,bootctl应该被删除(或移动到mumctl)。我认为最多bootctl应该只显示一个警告,或者至少允许一个--force选项。原因是,在很多情况下,在 ESP 上使用 RAID1(例如带有 的 MD RAID1 --metadata=1.0)是有益的。

我认为,最好的解决方案是bootctl通过systemd-boot-update.service配置文件,可以选择为那些需要的人更新多个 ESP,而无需 RAID。这样,可以使用备份 ESP,但本地操作系统只会同步 ESP 中自己的条目(而不是整个 ESP)。然而,诗歌也反对这一点,我不明白为什么。


附录

到目前为止我的具体做法:

  • 创建/boot,/boot_primary/boot_secondary.
  • /dev/sdX1然后将和分别安装/dev/sdY到主要和次要设备mount --rbind /boot_primary /boot。添加相同的到/etc/fstab.
  • 为了填充/boot_primary,我跑了bootctl installemerge --config gentoo-kernel是的,我使用分发内核并已安装sys-kernel/installkernel-systemd-boot,因此这 2 个命令将完全填充主 ESP)。
  • 填充/boot_secondary,重新绑定/boot/boot_secondary然后bootctl install --efi-boot-option-description='Linux Boot Manager (Secondary)'重复emerge --config gentoo-kernel

现在我有 2 个独立的 ESP。上述步骤是手动完成的,但仅在系统安装阶段进行一次。

然后,后来,为了更新它们,我扩展了我的 Gentoo 更新系统(这只是一个Makefile),以便在每次更新后盲目地执行 4 个额外步骤:

  1. 重新安装/bootrbind/boot_secondary
  2. bootctl update
  3. emerge --config gentoo-kernel
  4. 恢复/boot/boot_primary.

它不是最快的解决方案(这里的速度并不重要,因为 Gentoo 的更新无论如何都很慢;由于编译、速度有多慢emerge等),但我喜欢它的简单性以及它不会试图对上游工具使用的特定格式。因此,如果上游决定更改其行为或格式,我将不必更改此代码,并且一切都会完美地工作,而无需我不断地赶上上游。即使我安装了另一个恰好共享 ESP 的操作系统,此代码也应该仍然有效。

它也不是最慢的,因为emerge --config gentoo-kernel不重新编译内核或模块,而只是重复安装,包括启动条目(感谢分发内核太棒了)。

/dev/sdX发生故障时,根分区/仍然可以工作(感谢 RAID),并且我仍然能够使用辅助 ESP 顺利启动到系统。不再需要手动摆弄 ESP 恢复工具。

相关内容