为什么仍然使用驱动器/分区号?

qui*_*ykd 14 partition boot-loader grub2 uuid disk

很多时候,尤其是在使用引导加载程序时,我会看到使用的数字驱动器和分区号。例如,在我的/boot/grub/grub.cfgI see 中set root='hd0,gpt2',我的 UEFI 引导条目通常引用驱动器/分区编号,并且它似乎出现在几乎所有涉及引导加载程序的上下文中。

现在我们有了 UUID 和 PARTUUID,以这种方式寻址分区似乎非常不稳定(afaik,不能保证驱动器总是以相同的顺序安装,用户可能会移动插入其主板的驱动器的顺序,等等)

因此,我的问题是双重的:

  1. 这个寻址方案是否像我上面概述的那样不稳定?我是否遗漏了标准中的某些内容,这意味着该方案比我预期的要可靠得多,还是因为您的驱动器只是在不同的顺序或将它们插入主板上的不同插槽?

  2. 如果上述问题的答案是肯定的,那么为什么还要继续使用这种寻址方案?对所有内容使用 UUID 或 PARTUUID 会不会更加稳定和一致?

fro*_*utz 20

严格来说,UUID 根本没有寻址

寻址非常非常简单:读取驱动器 X 扇区 Y - 否则。读取内存地址 Z - 否则。寻址简单、快速,没有太多解释空间,而且无处不在。

UUID 未寻址。取而代之的是搜索、查找、有时等待设备出现,以及了解文件系统(?)。并且取决于有多少设备,这可能需要很长时间。一旦找到,回到常规地址。

在 GRUB 中,这被称为search(??) 并且仅当 GRUB 已经长出翅膀时才可用(搜索是一个模块,就像它支持的每个文件系统一样,因此只有在加载核心后才可用)。在 Linux 中,它(例如)被称为findfsfindfs 将在系统中搜索块设备以寻找文件系统或分区

它遍历所有块设备,将它们从待机状态唤醒,读取数据,如果 UUID 不是唯一的(在dd事故或类似情况之后),结果甚至可能仍然是随机的,或者如果 UUID 更改,则您不会得到任何结果 - UUID 也容易出现配置错误。

总的来说,UUID 很棒,当然你应该在任何可用的地方使用它们,尤其是当传统寻址注定会失败时,因为在 Linux 中驱动器顺序是随机的;但要明白,复杂性超出了简单寻址的意义。尤其是在引导加载程序的早期阶段,它可能还不是一种选择。先解决问题,再长翅膀。

对于引导加载程序,可能根本不需要付出努力(并非每个引导加载程序都支持广泛的文件系统,例如 GRUB)。如果hd0由于环境原因(BIOS 提供)保证是“我们启动的磁盘”,那么如果您可以排除随机驱动器顺序问题,则可能无需查看可能庞大的其他分区列表搜索 UUID。

如果您对自己的配置有足够的信心,可以说这hd0,gpt2是您想要的配置,并且必须如此,否则不能如此,那么这样使用它并没有错。有时,简单明了的寻址工作得很好。


(?) 我之前在这里为 LABEL解释过这一点......

标签没有通用标准,都是手工编织的,例如参见util-linux 中超级块格式的实现。如果你明天发明一个新的文件系统,即使它有一个标签,它也不会出现,直到添加支持。

...对于 UUID 来说也是一样的。


(??) 实际上,GRUBsearch有一个--hint选项,而且……现在我还没有检查源代码,甚至在他们的手册中也没有记录,但是这样的选项可以为您提供两全其美的选择:提示应该告诉search首先检查该分区,如果 UUID 按预期匹配,它会以最小的努力识别设备,如果不匹配,它仍将回退到全面搜索以保持工作正常进行.

除此之外,以前发现的 UUID 往往会被缓存,因此它不必一次又一次地遍历所有设备 - 这也很有效,前提是您正在寻找的 UUID 确实存在于某处首先将其放入缓存中。


Her*_*ann 13

在最近的系统中实际上并未使用普通编号方案(“最近”是 Ubuntu 9 及更高版本,其他发行版也可能在那个时代进行了调整)。
您在观察根分区设置为普通编号方案时是正确的。但这只是一个默认或后备设置,通常会被下一个命令覆盖,例如:

search --no-floppy --fs-uuid --set=root 74686973-6973-616e-6578-616d706c650a
Run Code Online (Sandbox Code Playgroud)

这将根据文件系统的 UUID 选择根分区。

在实践中,普通编号方案通常是稳定的(只要没有硬件变化)。我观察到的唯一不可预测的编号实例是具有许多 USB 驱动器的系统,这些驱动器是根据先到先服务模式枚举的,然后被模拟为 IDE 驱动器。这些过程中没有一个本质上是混乱的,因此我假设该特定系统 BIOS 实现存在问题。

注意:本文中的“root 分区”是指要从其启动的分区,它可能与包含“root aka./file system”的分区不同。


kkm*_*kkm 5

也不要忘记标签。它们不像 UUID 那样独特,但提供的信息更多,并使您的 fstab 具有可读性。如果是您的台式机或小公司——换句话说,您正在管理几个到几十个驱动器,您可能更喜欢标签而不是 UUID。

仔细思考@frostschutz对您的问题的出色回答,您可能更喜欢“经典”设备链接寻址的一种情况是 VM 设置,尤其是在租用 VM(缩写为“IaaS”)云中。假设您要自定义Ubunzima 04.18映像。您创建一个带有 2 个磁盘的(一次性)VM:一个是(一次性)系统驱动器,第二个是您安装和自定义的。据推测,如果您想在新磁盘上安装较新的 grub,您还可以挂载它的 UEFI 引导分区。假设您已经为 下的目标分区选择了挂载点/mnt,您想要的挂载表看起来像

/dev/sda1    /
/dev/sda9    /boot/efi
/dev/sdb1    /mnt/root
/dev/sdb9    /mnt/efi
Run Code Online (Sandbox Code Playgroud)

因此,您可以从提供商提供的现有云就绪映像制作 2 个相同的驱动器,将它们连接到新的 VM 并启动它。自然,

  • 所有现代操作系统发行版,我们想象中的Ubunzima 04.18也不例外,都依赖于以 UUID 命名的挂载。
  • 从同一映像推出的所有硬盘驱动器都具有相同的 UUID。UUID 是唯一的,那么会出现什么问题呢?

你已经看到这一切的进展。

这个 frankencontraption 第一次启动时,它选择sda9作为 EFI 启动分区,但 Linux 决定重新挂载sdb1为根 FS:

/dev/sda1    /mnt/root
/dev/sdb1    /
/dev/sda9    /boot/efi
/dev/sdb9    /mnt/efi
Run Code Online (Sandbox Code Playgroud)

而且由于我的推出脚本对此毫无准备,我最终得到了一个无法启动的无用映像,在 frankenbuild 期间没有任何工具在日志中抱怨!

当然,我在日志中打印了安装表。和当然的烂摊子起来是很难发现的,因为安装(8)打印中途随意之间,在该装置被安装在为了坐骑,所以这并不奇怪我没有发现它的时候了。并且想象一下,相同的脚本(但使用来自不同图像的磁盘)以前像 15 岁的 Glenfiddich 一样流畅。猜猜我花了多少小时在日志上拉我的头发¹ 试图找出问题所在?


没有适用于任何情况的硬性规定,从台式 PC 到嵌入路由器的 Linux,再到您的 Android 手机,再到云数据中心。SO 答案应该是客观的,而我的经验或偏好当然不是。因此,在选择不同的分区识别方法时,我宁愿展示逻辑推理的示例:

  • 不要管它,如果你没有理由不这样做。UUID 是大多数现代发行版的默认值。如果要添加第二个驱动器,请尝试并决定。很有可能你甚至不需要知道。如果您的系统仍然启动并且您可以看到新设备并对其进行分区,请将其格式化并将其添加到 fstab(通过 UUID、标签或/dev链接,同样的注意事项适用)。只有当您的系统在插入额外驱动器后拒绝启动时,您才会遇到问题(也许更改 UEFI BIOS 中的启动顺序是最快的出路)。

    实际上,标记哪个 SATA 连接器连接到您自己桌面中的哪个驱动器可能是最快和最简单的解决方案,而改变系统启动方式并从很可能的启动失败中恢复,可以说是最糟糕的时间吞噬者。但是如果你为 50 名程序员管理它,他们认为增加一个额外的驱动器不是一个值得打扰你的问题,至少不要测试你的运气极限,并确保他们的初始启动驱动器都被 grub 视为hd0和系统作为sda

  • 用于管理您自己的驱动器和桌面或三个桌面上的分区的标签,或者一个小环境(房子的客厅里挤满了软件工程师,他们有趣地称这个地方为他们的“启动办公室”)。如果您从某人的机器上拉出物理驱动器,如果您始终如一地使用标签,您就会知道它的来源。

    如果 lsblk(8) 说LABEL=bubba-boot,您就知道它已从名为bubba的机器中拉出;此外,bubba-boot6864c4ea-f9b9-46db-b875-4d7fc2981007更容易在我的舌头上滚动,在我被宠坏的口味中,这简直是一个令人惊叹的东西。确保标签是独一无二的现在转移到你身上,但你得到的回报是标签的意义。

  • /dev-link 基于命名,当指挥一个相对短命、低维护的 VM 营时,这些 VM 是同一映像的产物,并且您不会以每周工资为赌注,他们的所有 UUID 都符合 UU 的承诺。任何健全的VM 服务,无论是您自己的物理服务器上的Vyper-H还是Kugel Cloud或任何东西,都不应调用您的引导驱动器sde,以及第二个也是唯一的另一个sdc²。另一方面,在物理机中,您可以通过创造性地连接 SATA 电缆轻松获得相同的排列。

    我现在离题了,但在这种情况下,我使用所谓的“一致”以太网接口命名采用相同的方法:在 VM 中禁用它。不要误会我的意思,只要您放入 PCI 插槽 4 的 NIC 不会在您不看的时候(或者甚至可能在您看的时候)突然跳到插槽 5没有任何羞耻感)。不幸的是,在“虚拟机大队”环境中,他们实际上是这样做的。在这种情况下,与直觉相反,eth0比一致enp0s4f6. VM 提供商并未承诺始终将其虚拟 NIC 编号 1 放在 PCI 总线 0 上的插槽 4(并且提到的 3 个实体中没有一个是物理上真实的),并且它始终是功能 6。但是您可以很漂亮非常依赖第一个接口在第二个之前,考虑到它们通常具有相同的驱动程序模块,通常来自 virtio 系列(如果第一个 NIC 不总是eth0,同样的注意²仍然适用)。


¹ 形象地说,当然。如果这个生意太久了,我已经没有留下任何东西了。
² 如果他们这样做了,我会认真考虑逃离他们的尖叫声,改变提供商或 VM 管理程序软件。