libvirt - 使用内置固件自动选择功能进行UEFI固件配置

https://blueprints.launchpad.net/nova/+spec/libvirt-firmware-auto-selection

Libvirt 引入了其内置的 UEFI 固件自动选择功能,该功能会根据请求的功能自动填充 UEFI 固件文件的 CODE 文件和 VAR 文件的路径。此功能更加复杂,并且能够检测到最近引入的几个新标志,例如 AMD SEV 或无状态固件。

本文档建议用内置功能替换 nova 中现有的逻辑,这样我们就不必维护自己的逻辑,并利用底层 libvirt 中改进的机制。

问题描述

最近的 libvirt 能够根据请求的功能(例如

  • 安全启动

  • amd-sev/amd-sev-es/amd-sev-snp

  • 无状态固件

为使用 UEFI 启动的域选择合适的固件文件。此功能在 libvirt 中称为自动选择,它读取 qemu 包在发行版中提供的固件描述文件中维护的标志。

Nova 在引入安全启动支持时引入了自己的逻辑。由于 nova 显式定义了使用 UEFI 启动的每个实例的固件文件,libvirt 会跳过其自动选择功能并相应地使用指定的 文件。但是 nova 中现有的逻辑仅考虑 secure-boot 标志,因此无法为其他功能选择合适的固件。因此,具有附加功能的实例可能会使用错误的固件文件启动。一个例子是无状态固件,应该使用带有“stateless”标志的固件文件,但当前的 nova 可能不会考虑此标志,并且可能会使用一个 CODE 文件启动实例,

该 CODE 文件关联着非零 VAR 文件。

除了新的功能标志外,最近的 QEMU 包还引入了新型的 ROM 类型固件。Libvirt 可以识别这些固件,但 nova 无法处理这些新型固件,因为用于定义固件路径文件的键不同。

用例

  1. 作为云管理员,我希望 nova 根据用户请求的功能选择合适的固件文件,而无需额外配置。

  2. 作为云用户,我希望我的实例能够使用与请求的功能相对应的固件启动。

提议的变更

我们建议对 libvirt 驱动程序生成 guest XML 的方式进行以下更改,以便 libvirt 根据请求的功能选择固件文件。

  • 在定义域时,停止显式传递 code 文件和 var 文件的路径。

    • 当前 nova 在生成 guest XML 时会填充 loader 元素和 nvram 元素。以下示例描述了具有 secure-boot 的 guest XML 的 os 元素。

      <os>
        <type machine='q35'>hvm</type>
        <loader type='pflash' readonly='yes' secure='yes'>/usr/share/OVMF/OVMF_CODE.secboot.fd</loader>
        <nvram template='/usr/share/OVMF/OVMF_VARS.secboot.fd'/>
        <boot dev='hd'/>
        <smbios mode='sysinfo'/>
      </os>
      
    • 一旦实施了提议的更改,nova 将不再填充这些文件路径,而是为 secure-boot 添加固件功能元素。以下示例描述了具有 secure-boot 的 guest XML 的 os 元素。

      <os firmware='efi'>
        <type machine='q35'>hvm</type>
        <loader secure='yes'/>
        <firmware>
          <feature enabled='yes' name='secure-boot'/>
        </firmware>
        <boot dev='hd'/>
        <smbios mode='sysinfo'/>
      </os>
      
      • 请注意,firmware='efi' 是告诉 libvirt 检测固件文件路径的关键。

      • 为了保持不使用 secure-boot 的 guest 的现有行为,如果未请求 secure-boot 功能,则会在 guest XML 中显式拒绝该功能。

        <os firmware='efi'>
          <type machine='q35'>hvm</type>
          <loader secure='no'/>
          <firmware>
            <feature enabled='no' name='secure-boot'/>
          </firmware>
          <boot dev='hd'/>
          <smbios mode='sysinfo'/>
        </os>
        
    • 但是,libvirt 不需要这些固件功能元素来支持无状态固件(libvirt 读取 loader 元素中的 stateless 属性)和 AMD SEV/SEV-ES(libvirt 读取 launchSecurity 元素)。例如,当请求无状态固件时,guest XML 的 os 元素应如下所示。

      <os firmware='efi'>
        <type machine='q35'>hvm</type>
        <loader secure='no' stateless='yes'/>
        <firmware>
          <feature enabled='no' name='secure-boot'/>
        </firmware>
        <boot dev='hd'/>
        <smbios mode='sysinfo'/>
      </os>
      
  • 在以下操作期间,检查现有 guest XML 中的 loader 元素和 nvram 元素,然后显式传递这些元素并禁用自动检测以生成新的 guest XML,以便在这些操作期间不会重新选择固件文件。

    • 硬重启(和启动)

    • 实时迁移

    注意

    如果实例启动时 domain xml 不存在(例如,如果实例从卷启动并且其主机已重新安装),则有可能 domain xml 不存在。在这种情况下,xml 将从头开始生成,并且在操作之后固件文件路径可能会更改。

备选方案

另一种方法是在 nova 中实现相同的自动选择逻辑,但这需要付出努力才能使实现与 libvirt 保持一致。这会导致对未来代码维护的担忧,而没有带来很大的好处。

数据模型影响

REST API 影响

安全影响

通知影响

其他最终用户影响

在生成 domain XML 的操作之后(例如

  • 启动,当域定义不存在于 hypervisor 上时

  • 重建

  • 搁置

  • 调整大小或冷迁移

  • 疏散

性能影响

其他部署者影响

部署者必须确保固件描述文件(通常位于 /usr/share/qemu/firmware/)已更新,以包含预期功能的标志。

开发人员影响

升级影响

  • 如“最终用户影响”部分所述,当使用新的 libvirt 驱动程序启动时,实例可能会使用不同的(但正确的)固件启动。

  • 升级后,如果固件描述文件都不包含所需的标志(sev 标志和无状态标志),而这些标志之前未经过检查,则实例创建可能会失败。

实现

负责人

主要负责人

kajinamit (irc: tkajinam)

其他贡献者

工作项

  1. 添加对现有 libvirt XML 中使用的固件文件的检测

  2. 更新 libvirt 驱动程序生成 XML 文件的方式,仅在显式提供这些文件时才填充固件文件路径。

  3. 更新实时迁移和硬重启,以便在生成新的 XML 文件时传递当前使用的固件文件。

应根据新的逻辑添加单元测试和功能测试。

依赖项

  • 使用自动选择功能需要 Libvirt >= 5.2.0。这已由最低 libvirt 版本检查强制执行。

  • QEMU 固件及其描述文件已更新,以包含 nova 请求的功能的标志。受支持的发行版安装的固件描述文件大多包含所需的标志,但已知 Ubuntu 24.04 需要更新才能支持 AMD SEV-ES。有关详细信息,请参阅 Bug 2122286

测试

需要扩展或添加相应的单元/功能测试,以涵盖

  • 在实例 XML 生成期间传递的简化 XML 文件,该文件不包含显式固件文件路径

  • 硬重启或实时迁移生成的 XML 文件应包含显式固件文件路径,这些路径与现有域 XML 中的路径相对应。

对于安全启动和无状态固件,可以向 tempest 添加新的场景测试。但是,目前在 CI 中用于 guest OS 的 cirros 不支持 UEFI 启动,我们需要一个不同的(并且可能更重的)guest OS 来支持这些功能。如果确定我们无法在 CI 中使用这些 guest,则可以在本地测试这些功能。

此外,AMD SEV 和 AMD SEV-ES 在 CI 中没有可用的实际固件,因此这些将手动测试。

文档影响

参考资料

历史

修订版

发布名称

描述

2026.1 Gazpacho

已批准