创建快照时出错:不支持操作:不支持具有基于 pflash 的固件的 VM 的内部快照

Joh*_*hau 14 arch-linux snapshot virt-manager libvirt

我正在使用 Arch Linux,无论是主机还是访客。对于 UEFI 启动,我已安装edk2-ovmf并让访客使用固件/usr/share/edk2-ovmf/x64/OVMF_CODE.fd。我想创建虚拟机的快照,但收到错误:

Error creating snapshot: Operation not supported: internal snapshots of a VM with pflash based firmware are not supported

Traceback (most recent call last):
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 65, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/details/snapshots.py", line 237, in _do_create_snapshot
    self.vm.create_snapshot(xml)
  File "/usr/share/virt-manager/virtManager/object/domain.py", line 1124, in create_snapshot
    self._backend.snapshotCreateXML(xml, flags)
  File "/usr/lib/python3.9/site-packages/libvirt.py", line 3059, in snapshotCreateXML
    raise libvirtError('virDomainSnapshotCreateXML() failed')
libvirt.libvirtError: Operation not supported: internal snapshots of a VM with pflash based firmware are not supported
Run Code Online (Sandbox Code Playgroud)

看来我选择的固件(需要使用安装 Arch 所需的 UEFI 启动)不支持快照?

有没有办法可以使用当前设置创建快照?

tuk*_*kan 14

即使到了 2022 年,内部快照也没有修复。唯一的解决方案是使用外部快照。有关更多详细信息,请访问KVM:创建和恢复 libvirt 外部快照。外部快照示例的所有功劳都归于Fabien Lee

\n

简单来宾域的外部快照

\n

创建外部快照

\n

如果您的来宾域是一个简单的 VM,其中所有的<disk>都是 type="file",则创建已启动 VM\xe2\x80\x99s 状态(不包括 RAM)的外部快照如下所示。对于本示例,假设硬盘驱动器位于hda,CD-ROM 位于hdb

\n
# name of domain, snapshot, and target disk device\nthedomain="mysimpledomain"\nsnapshotname="simple-test"\ntargetdisk="hda"\n\n# look at \'<disk>\' types, should be just \'file\' types\nvirsh dumpxml $thedomain | grep \'<disk\' -A5\n\n# show block level devices and qcow2 paths (hda,hdb,..etc)\nvirsh domblklist $thedomain\n\n# create snapshot in default pool location\n# file name is $thedomain.$snapshotname\nvirsh snapshot-create-as $thedomain --name $snapshotname --disk-only\n\n# list snapshot\nvirsh snapshot-list $thedomain\n
Run Code Online (Sandbox Code Playgroud)\n

恢复外部快照

\n

要查看底层机制并准备用于恢复快照的变量,请执行以下命令。

\n
# notice path to hda has now changed to snapshot file\nvirsh domblklist $thedomain\n\n# <source> has changed to snapshot file\nvirsh dumpxml $thedomain | grep \'<disk\' -A5\n\n# pull default pool path from xml \npooldir=$(virsh pool-dumpxml default | grep -Po "(?<=path\\>)[^<]+")\necho "default pool dir: $pooldir"\n\n# should see two files starting with $thedomain\n# the one named $thedomain.$snapshotname is the snapshot\ncd $pooldir\nls -latr $thedomain*\n\n# snapshot points to backing file, which is original disk\nsudo qemu-img info $thedomain.$snapshotname -U --backing-chain\n\n# capture original backing file name so we can revert\nbackingfile=$(qemu-img info $thedomain.$snapshotname -U | grep -Po \'backing file:\\s\\K(.*)\')\necho "backing file: $backingfile"\n
Run Code Online (Sandbox Code Playgroud)\n

为了进行恢复,我们需要将域 xml 修改回原始 qcow2 文件,删除快照元数据,最后删除快照文件。

\n
# stop VM\nvirsh destroy $thedomain\n\n# edit hda path back to original qcow2 disk\nvirt-xml $thedomain --edit target=$targetdisk --disk path=$backingfile --update\n\n# validate that we are now pointing back at original qcow2 disk\nvirsh domblklist $thedomain\n\n# delete snapshot metadata\nvirsh snapshot-delete --metadata $thedomain $snapshotname\n\n# delete snapshot qcow2 file\nsudo rm $pooldir/$thedomain.$snapshotname\n\n# start guest domain\nvirsh start $thedomain\n
Run Code Online (Sandbox Code Playgroud)\n

来宾域现在应该处于原始状态。有关外部快照的更多详细信息,请访问上面的链接。

\n

为什么内部快照被禁用?

\n

为什么内部快照已被禁用,您可以阅读下文。我在搜索此主题时发现的最佳答案之一

\n
\n

2017 年 9 月 4 日星期一上午 08:30:23 -0700,ovirt@xxxxxxxxxxxxxxxxx\n写道:

\n
\n

操作系统:Fedora 26 + Virt-Manager v1.42\nvm:Win 10 UEFI + Q35

\n

创建快照时出错:不支持操作:\n不支持具有基于 pflash 的固件的 VM 的内部快照。

\n

有解决办法吗?

\n
\n

您好,遗憾的是没有,并且可能需要一些时间才能支持 UEFI 来宾的快照。

\n

问题是内部快照已经过时,并且缺少外部快照所具有的许多\n功能。它们基本上仅适用于只有一张磁盘的来宾,其中包括来宾状态的所有内容都存储在一个文件中。

\n

为了修复此问题并为具有 UEFI 的来宾获取快照\nvirt-manager 必须切换到使用外部快照,\n已经存在一个 BUG 3。但是,目前无法完成\n因为 libvirt 仍然缺少一些针对外部快照的强制功能,\n例如,您无法恢复到\n外部快照,这导致它们无法使用。libvirt 实现这个4也有一个 BUG 。

\n

帕维尔

\n

3 https://bugzilla.redhat.com/show_bug.cgi?id=1403951 4 \n https://bugzilla.redhat.com/show_bug.cgi?id=1402581

\n
\n

原因如下

\n
\n

回复:[libvirt] [PATCH v2] qemu:快照:使用 pflash 固件禁止内部快照\n

\n
From: Laszlo Ersek <lersek redhat com>\nTo: Peter Krempa <pkrempa redhat com>\nCc: libvir-list redhat com\nSubject: Re: [libvirt] [PATCH v2] qemu: snapshot: Forbid internal snapshots with pflash firmware\nDate: Thu, 23 Mar 2017 17:49:56 +0100\n
Run Code Online (Sandbox Code Playgroud)\n

2017 年 3 月 23 日 15:07,Peter Krempa 写道:

\n
\n

2017 年 3 月 23 日星期四 11:03:02 +0100,Laszlo Ersek 写道:

\n
\n

2017 年 3 月 23 日 10:54,Peter Krempa 写道:

\n
\n

2017 年 3 月 23 日星期四 10:48:01 +0100,Laszlo Ersek 写道:

\n
\n

2017 年 3 月 23 日 10:29,Peter Krempa 写道:

\n
\n

如果变量存储 () 文件是原始 qemu 则无法执行快照,因此快照将不完整。QEMU 不会拒绝此类快照。

\n

另外允许使用 qcow2 变量存储支持文件将解决此问题,但随后它将有资格成为内存转储的目标。

\n

无论采用哪种存储格式,脱机内部快照都会不完整,因为在这种情况下 libvirt 不处理 pflash 文件。

\n

禁止这样的快照,这样我们就可以避免出现问题。

\n
\n
\n
\n
\n

[...]

\n
\n
\n

@@ -13873,8 +13873,14 @@ qemuDomainSnapshotPrepare(virConnectPtr conn,\ngoto cleanup;\n}

\n\n\n
\n
\n

我对此进行了更多思考,我认为虽然存在上述问题,但我们仍然可以让快照 + OVMF 的用户成功使用它。禁止它会给他们带来回归,因为尽管存在上述问题,他们\n并没有观察到任何不好的事情:

\n

原因如下:

\n
    \n
  1. 内部快照是 virt-manager 中的默认值
  2. \n
  3. 来宾通常不会经常重写 varstore,通常仅在安装时\n
  4. \n
  5. 除了启动项之外,操作系统通常不会修改任何内容
  6. \n
  7. 在线VM的快照在内存映像中携带varstore
  8. \n
  9. 如果启动项失败,操作系统非常擅长恢复启动项
  10. \n
\n

由于上述事实,我认为有些用户合理\n认为使用 pflash 加载程序的快照可以按预期工作。这主要是由于数据非常静态,并且操作系统不存储任何重要的内容,并且能够自我修复一些问题。

\n

我认为我们不应该禁止这样做,以避免可用性下降。我们可以添加说明快照不安全的文档。此外,我们还需要添加对外部快照的支持,目前外部快照存在类似的问题,尽管可以修复。

\n
\n

需要在看似有效但本质上不安全的操作与确保安全的明确错误消息之间进行权衡。

\n

UEFI 变量存储的用途比您提到的更多且不同,例如(按重要性大致降序排列):

\n
    \n
  • 某些 UEFI 变量(经过身份验证的变量)具有安全影响。这涵盖了用于安全启动的标准化密钥(平台密钥、密钥交换密钥、白名单证书和签名 (DB) 以及黑名单证书和签名 (DBX))。

    \n
  • \n
  • 据我所知,它还包括 shim / MokManager 使用的一些类似的安全相关变量(其中“MOK”是 Machine\nOwner Key 的缩写);也就是说,shim 从标准化安全启动接口将 EFI 二进制文件的验证委托给非易失性变量。

    \n
  • \n
  • UEFI 变量可以充当 Linux“pstore”(持久存储)文件系统的后端。Pstore 又可用于在崩溃时保存\ndmesg 的最后部分。这些消息可以在新启动时重新读取。\n

    \n
  • \n
  • 固件在每次启动时在内部使用(读/写)多个变量。这些可能并不重要。一个示例是\n有助于减少一系列引导过程中 UEFI 内存映射碎片的变量。

    \n
  • \n
  • OVMF 根据 bootindex 属性(或更直接地根据“bootorder”\nfw_cfg 文件)在每次启动时操作 UEFI 启动选项。尽管不可否认,这可能是风险最小的 varstore 内容类别。

    \n
  • \n
\n

虽然我自己已经成功地使用了 OVMF 来宾的内部快照(仅限离线),但我并没有意识到 varstore 从未真正被快照过,但对于默默地执行本质上有损的操作,我感到非常不舒服,尤其是当varstore 很可能会产生安全影响。

\n

用户不会阅读文档(他们永远不会这样做),而且我\n也不会提交有关晦涩的安全启动\n错误行为的未来错误报告。

\n

这最终取决于 libvirt 开发人员,但在我看来,如果我们继续允许这种不安全的操作,那么最低限度将是:

\n
    \n
  • 在 virt-manager 中,弹出一个额外的确认对话框,并明确指示该操作将是有损的并且可能会对安全\n产生影响,

    \n
  • \n
  • 在 virsh 中,拒绝操作并显示类似的错误消息,除非指定了“--force”或类似的内容。

    \n
  • \n
  • 而且,由于还有其他(独立的)libvirt 客户端应用程序,这可能需要在 libvirt API 级别上设置一个新标志,以便 libvirt 本身可以拒绝不安全的快照请求,而不管提交该请求的客户端应用程序是什么。

    \n
  • \n
\n

我同意可用性回归并不好,并且可能\n生成错误报告;然而,如果它们与安全改进直接冲突,那么安全改进就会胜过可用性回归。我想我们可以允许用户忽略安全性,但\n需要当场通知他们,并且他们必须选择加入。

\n

我希望我们能够继续进行这个补丁;但是,最终还是取决于你。

\n

谢谢!拉斯洛

\n
\n