11个版本
0.2.9 | 2023年1月20日 |
---|---|
0.2.6 | 2021年9月8日 |
0.2.5 | 2021年1月6日 |
0.2.4 | 2020年12月15日 |
0.1.2 | 2020年9月22日 |
#164 在 操作系统
每月下载量44次
100KB
2K SLoC
bootupd: 引导加载程序的分布式独立更新
如今,许多Linux系统以不一致和临时的方式处理引导加载程序数据的更新。例如,在Fedora和Debian上,包管理器更新将更新/boot/efi
中的UEFI二进制文件,但不会更新BIOS MBR数据。
事务性/“镜像”更新系统,如OSTree,以及双分区系统,如Container Linux更新系统,则更为一致:它们通常涵盖内核/用户空间,但不包括与引导加载程序相关的内容。
原因很简单:以“A/B”的方式执行引导加载程序更新需要在管理内核和根文件系统之外,完全独立的非平凡逻辑。如今,例如,OSTree选择了不更新/boot/efi
(也不更新BIOS MBR)。
本项目目标是成为一个跨分布、不依赖于特定OS更新系统的工具,以管理以下内容的更新:
/boot/efi
- x86 BIOS MBR
- 其他架构的引导加载程序
本项目起源于这个Fedora CoreOS GitHub问题。
范围限制在其他方面;例如,bootupd不会管理与内核相关的内容,如内核参数;这是为像grubby
和ostree
这样的工具准备的。
状态
目前处于开发中,尚未准备好用于生产更新,但欢迎对设计提供早期反馈!
与其他项目的关系
dbxtool
dbxtool 管理安全启动数据库的更新 - bootupd
可能需要在dbxtool.service
启动之前执行任何对shimx64.efi
二进制文件的更新。但除此之外,它们是独立的。
fwupd
bootupd可以与fwupd进行比较,fwupd是一个现有的项目,用于更新硬件设备的固件 - 这些设备目前不是由apt/zypper/yum/rpm-ostree update
管理的。
fwupd 目前作为一个 UEFI 二进制文件,因此 bootupd 可能会负责更新 fwupd
,但今天 fwupd 自己处理这一过程。因此,bootupd 可能只会处理 GRUB 和 shim。请参阅 这个问题 的讨论。
systemd bootctl
systemd bootctl 可以更新自身;如果检测到使用 systemd-boot,该项目可能会仅作为代理。
其他目标
一个想法是,bootupd 可以帮助支持 冗余可启动磁盘。由于各种原因,尝试使用 RAID1 整个磁盘并不实际;ESP 必须特别处理。bootupd
可以学习如何从主分区同步多个 EFI 系统分区。
关于原因和集成的更多细节
对于基于 rpm-ostree 的系统,一个显著问题是 rpm -q shim-x64
是误导性的,因为它实际上并未在原地更新。
特别是 这个提交 清晰地说明了问题 - RPM 的数据进入 /usr
(OSTree 的一部分),因此它不会触及 /boot/efi
。但这个提交并没有改变 RPM 数据库的工作方式(并且更普遍地说,rpm-ostree 在今天改变 RPM 数据库的工作方式在技术上可能很复杂)。
我们最终想要的是 rpm -q shim-x64
返回 "未安装",因为它是通过 RPM 或 ostree 管理的。取而代之的是,人们将纯粹使用 bootupctl
来管理它。然而,它可能仍然被 构建 为 RPM,但不是以这种方式安装。RPM 版本号将用于与有效负载相关的 bootupd 版本,最终我们会教 rpm-ostree compose tree
如何单独下载引导加载程序并将它们传递给 bootupctl 后端
。
问题和答案
- 为什么 bootupd 不是 ostree 的一部分?
ostree 的一个主要宣传特性是更新确实是事务性的。甚至有一个 测试案例 来验证在操作系统更新期间强制断电。简单来说,在基于 ostree 的系统中,不需要有一个 "请勿关闭计算机电源" 的屏幕。这反过来帮助管理员自信地启用自动更新。
对于引导加载程序(即 bootupd 的领域)做这件事是一个 完全 不同的难题。有一些关于我们如何使引导加载程序使用 A/B 类型的方案(或者至少更健壮)的想法,也许未来 bootupd 将使用其中的一些。
因此,这些更新具有不同级别的风险。实际上,引导加载程序落后是可以接受的;我们不需要每次都更新。
但出于保守起见,目前例如在 Fedora CoreOS 中,bootupd 默认是禁用的。另一方面,如果你的操作系统更新机制不是事务性的,那么你可能希望默认启用 bootupd。
- 为什么 bootupd 是一个守护进程?
实际上并不是。这个名字的意图是 "bootloader-upDater" 而不是 "bootloader-updater-Daemon";"d" 后缀的选择在回顾起来可能太容易引起混淆了。
在技术层面上,确实有一个由套接字激活的系统d服务,它将启动一个 bootupd.service
。然而——该服务会 非常快地 自动退出。没有长时间运行的内容,所以它实际上不是一个守护进程。
这种设计的理由是
- 使用系统d服务提供了一个健壮的自然“锁定”机制。
- 使用系统d服务确保关键日志元数据始终一致地进入系统d日志,而不是例如短暂的客户端SSH连接。
- 系统d服务可以轻松地应用沙箱,尽管bootupd显然具有特权,我们仍然可以利用其中的一些。
- 最终,我们可能需要一个非CLI API(无论是DBus、Cap'n Proto、varlink还是其他什么),拥有一个套接字(没有定义的稳定API)是为这个目的做准备工作。
依赖项
~13–25MB
~374K SLoC