很多时候,尤其是在使用引导加载程序时,我会看到使用的数字驱动器和分区号。例如,在我的/boot/grub/grub.cfg
I see中set root='hd0,gpt2'
,我的 UEFI 引导条目经常引用驱动器/分区号,并且它似乎几乎出现在涉及引导加载程序的任何上下文中。
现在我们有了 UUID 和 PARTUUID,以这种方式寻址分区似乎非常不稳定(据我所知,驱动器不能保证始终以相同的顺序安装,用户可能会移动插入主板的驱动器的顺序等)
因此,我的问题有两个:
这个寻址方案是否像我上面概述的那样不稳定?我是否在标准中遗漏了一些内容,这意味着该方案比我预期的要可靠得多,或者该寻址方案是否会真正使您的系统无法启动(至少在您修复启动条目之前),因为您的驱动器只是在不同的顺序或将它们插入主板上的不同插槽?
如果上述问题的答案是肯定的,那么为什么还要继续使用这种寻址方案呢?对所有事物使用 UUID 或 PARTUUID 不是会更加稳定和一致吗?
答案1
严格来讲,UUID 未寻址根本不。
寻址非常非常简单:读取驱动器 X 扇区 Y - 否则。读取内存地址Z——否则。寻址简单、快速,没有太多解释空间,而且无处不在。
UUID 未寻址。相反,它会搜索、查找,有时会等待设备出现,并且了解文件系统(★)。并且根据设备的数量,可能需要很长时间。一旦找到,就回到常规寻址。
在 GRUB 中,这被称为search
(★★),并且仅当 GRUB 已经长出翅膀时才可用(搜索是一个模块,它支持的每个文件系统都是一个模块,因此仅在加载核心后才可用)。在 Linux 中,它(例如)称为findfs
,findfs 将搜索系统中的块设备以查找文件系统或分区。
它会遍历所有块设备,将它们从待机状态唤醒,读取数据,如果 UUID 不应该是唯一的(在发生事故等之后),结果甚至可能仍然是随机的dd
,或者如果 UUID 更改,则不会得到任何结果 - UUID 也容易出现配置错误。
一般来说,UUID 很棒,当然,如果可用的话,您应该在任何地方使用它们,特别是当传统寻址必然失败时,因为 Linux 中的驱动器顺序是随机的;但要明白,复杂性超出了简单寻址的意义。尤其是在引导加载程序的早期阶段,它可能还不是一个选择。先解决问题,然后再长翅膀。
对于引导加载程序,可能根本不需要付出努力(并非每个引导加载程序都支持广泛的文件系统,例如 GRUB)。如果hd0
由于情况(BIOS 提供)而保证是“我们启动的磁盘”,因此,如果您可以排除随机驱动器顺序问题,则可能不需要查看潜在的大量其他分区列表搜索 UUID。
如果您对自己的配置有足够的信心,可以说这hd0,gpt2
就是您想要的配置,并且必须是这样,否则就不可能是这样,那么这样使用它并没有什么问题。有时,简单明了的寻址就可以了。
(★) 我之前解释过这一点此处的标签...
标签没有通用标准,都是手工编织的,请参见示例util-linux 中超级块格式的实现。如果你明天发明一个新的文件系统,即使它有标签,在添加支持之前它也不会显示。
...对于 UUID 来说也是如此。
(★★) 实际上,GRUBsearch
有一个--hint
选项,而且...现在我还没有检查源代码,甚至没有在他们的手册中记录它,但这样的选项是有意义的,可以为您提供两全其美的效果:提示应该search
告诉首先检查该分区,如果 UUID 按预期匹配,则它通过以下方式识别设备最小的努力,如果不匹配,它仍然会回到全面搜索,以保持事情以某种方式正常运转。
除此之外,以前找到的 UUID 往往会被缓存,因此不必一遍又一遍地遍历所有设备 - 这也很有效,只要您要查找的 UUID 实际上存在于某处即可首先将其放入缓存中。
答案2
简单的编号方案实际上并未在最近的系统中使用(“最近”是 Ubuntu 9 及更高版本,其他发行版也可能在那个时代进行了调整)。
您观察到根分区是使用普通编号方案设置的,这是正确的。但这只是默认或后备设置,通常会被下一个命令覆盖,例如:
search --no-floppy --fs-uuid --set=root 74686973-6973-616e-6578-616d706c650a
这将根据文件系统的 UUID 选择根分区。
实际上,普通编号方案通常是稳定的(只要没有硬件更改)。我观察到的不可预测编号的唯一实例是具有许多 USB 驱动器的系统,这些驱动器根据先到先服务模式进行枚举,然后模拟为 IDE 驱动器。这些过程本质上都不是混乱的,因此我假设该特定系统 BIOS 实现存在问题。
注意:本文中的“根分区”指的是启动分区,它可能与包含“根又名./文件系统”的分区不同。
答案3
也不要忘记标签。它们不像 UUID 那样独特,但信息量更大,并且使您的 fstab 具有可读性。如果是您的台式机,或者是一家小公司,换句话说,您正在管理几个到几十个驱动器,那么您可能更喜欢标签而不是 UUID。
沉思@frostschutz 的很好的答案对于您的问题,您可能更喜欢“经典”设备链接寻址的一种情况是虚拟机设置,尤其是在租用虚拟机(缩写为“IaaS”)云中。假设你想定制一个乌本齐马 04.18图像。您创建一个具有 2 个磁盘的(一次性)VM:一个是(一次性)系统驱动器,第二个是您安装和自定义的驱动器。如果您想在新磁盘上运行较新的 grub,您可能还需要挂载其 UEFI 引导分区。假设您已为 下的目标分区选择了挂载点/mnt
,则您所需的挂载表如下所示
/dev/sda1 /
/dev/sda9 /boot/efi
/dev/sdb1 /mnt/root
/dev/sdb9 /mnt/efi
因此,您可以从提供商提供的现有云就绪映像中制作 2 个相同的驱动器,将它们连接到新的虚拟机并启动它。自然,
- 所有现代操作系统发行版,我们的想象乌本齐马 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
由于我的转出脚本对此毫无准备,所以最终我得到了一个无法启动的无用图像,并且在 Frankenbuild 期间没有任何工具在日志中抱怨!
当然我在日志中打印了安装表。和当然这种混乱很难发现,因为 mount(8) 打印安装的顺序介于随机和设备安装顺序之间,所以我没有立即发现它并不奇怪。想象一下,相同的脚本(但使用不同图像的磁盘)以前可以像 15 年的格兰菲迪一样顺利。猜猜我花了多少个小时把头发放在木头上试图找出问题所在?
从台式电脑到路由器中嵌入的 Linux,再到 Android 手机,再到云数据中心,没有适用于任何情况的硬性规则。 SO 答案应该是客观的,而我的经验或偏好当然不是。因此,在选择不同的分区识别方法时,我宁愿展示逻辑推理的示例:
不要管它如果你没有理由不这样做。 UUID 是大多数现代发行版的默认值。如果需要添加第二个驱动器,请尝试然后决定。您可能根本不需要知道。如果您的系统仍然启动,并且您可以看到新设备并对其进行分区,请将其格式化并将其添加到 fstab(通过 UUID、LABEL 或链接
/dev
,适用相同的注意事项)。只有当您的系统在插入额外的驱动器后拒绝启动时,才会出现问题(也许更改 UEFI BIOS 中的启动顺序是最快的解决方法)。实际上,标记哪个 SATA 连接器连接到您自己的桌面中的哪个驱动器可能是最快、最简单的解决方案,而改变系统启动方式并从很可能的启动失败中恢复可以说是最浪费时间的方法。但是,如果您为 50 名程序员管理它,他们认为添加额外的驱动器不是什么值得困扰您的问题,那么至少不要测试您的运气极限,并确保它们的初始引导驱动器都被 grub 视为
hd0
和系统为sda
.标签管理您自己的桌面或三个桌面或小型环境(房子的客厅里挤满了软件工程师,他们有趣地称这个地方为“初创办公室”)中自己的驱动器和分区。如果您从某人的机器上取出物理驱动器,如果您一致使用标签,您就知道它来自哪里。
如果 lsblk(8) 说
LABEL=bubba-boot
,您就知道它已从名为的机器中拉出布巴;除了,布巴引导在我的舌头上滚动比6864c4ea-f9b9-46db-b875-4d7fc2981007,按照我被宠坏的口味,这简直是令人瞠目结舌。确保标签的独特性现在由您负责,但您得到的回报是标签的意义。/dev
-基于链接当指挥一群生命周期相对较短、维护成本较低的虚拟机(这些虚拟机是同一映像的衍生品)时,您不会用每周的工资打赌它们的所有 UUID 都符合 UU 承诺。任何理智的VM服务,就这样吧维珀-H在您自己的物理服务器上或库格尔云或任何东西,永远不会调用您的引导驱动器sde
,以及第二个也是唯一的另一个sdc
²。另一方面,在物理机中,您可以通过创造性地连接 SATA 电缆轻松实现相同的布置。我现在离题了,但在这种情况下,我采用了所谓的“一致”以太网接口命名相同的路线:在虚拟机中禁用它。不要误会我的意思,只要您放入 PCI 插槽 4 的网卡不会在您不看时(或者甚至在您不看时)突然随意跳到插槽 5,命名就非常一致;网卡没有任何羞耻)。不幸的是,在“虚拟机大队”环境中,它们实际上是这样做的。在这种情况下,与直觉相反的
eth0
是更多的一致比enp0s4f6
。 VM 提供商并没有承诺始终将其虚拟 NIC 编号 1 放在 PCI 总线 0 上的插槽 4 中(并且提到的 3 个实体都不是物理上真实的),并且它将始终是功能 6。但是您可以相当很大程度上依赖于第一个接口在第二个接口之前,考虑到它们通常具有相同的驱动程序模块,通常来自 virtio 系列(如果第一个 NIC 并不总是eth0
,则相同的注释²仍然适用)。
1 当然,这是象征性的。我从事这行太久了,已经没有剩下的了。
² 如果他们这样做了,我会认真考虑逃避他们的尖叫,改变供应商或虚拟机管理程序软件。
答案4
我想,第二个问题(“为什么继续使用这种寻址方案?”)的答案是惯性。是的,完全可以在 GPT 分区磁盘上仅使用 UUID。您可以使用/dev/xxx
UUID代替/etc/fstab
.现在我们有了可发现的分区规范,在许多情况下,您甚至不必再指定 UUID,只需使用分区类型对磁盘进行分区,系统就会自动选择分区。在我的机器上,root=
内核命令行中完全缺少该条目。
说到引导加载程序:GRUB 在现代 UEFI PC 上基本上是多余的,因为它与引导机器关系不大。如今,GRUB 仅充当内核选择程序,对于该任务,有更简单、更好的替代方案可用,例如 systemd-boot。