简单来宾域的外部快照

简单来宾域的外部快照

我正在使用 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

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

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

答案1

即使到了 2022 年,内部快照也没有修复。唯一的解决方案是使用外部快照。欲了解更多详情,请访问KVM:创建和恢复 libvirt 外部快照。外部快照示例的所有学分都转到法比安·李

简单来宾域的外部快照

创建外部快照

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

# name of domain, snapshot, and target disk device
thedomain="mysimpledomain"
snapshotname="simple-test"
targetdisk="hda"

# look at '<disk>' types, should be just 'file' types
virsh dumpxml $thedomain | grep '<disk' -A5

# show block level devices and qcow2 paths (hda,hdb,..etc)
virsh domblklist $thedomain

# create snapshot in default pool location
# file name is $thedomain.$snapshotname
virsh snapshot-create-as $thedomain --name $snapshotname --disk-only

# list snapshot
virsh snapshot-list $thedomain

恢复外部快照

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

# notice path to hda has now changed to snapshot file
virsh domblklist $thedomain

# <source> has changed to snapshot file
virsh dumpxml $thedomain | grep '<disk' -A5

# pull default pool path from xml 
pooldir=$(virsh pool-dumpxml default | grep -Po "(?<=path\>)[^<]+")
echo "default pool dir: $pooldir"

# should see two files starting with $thedomain
# the one named $thedomain.$snapshotname is the snapshot
cd $pooldir
ls -latr $thedomain*

# snapshot points to backing file, which is original disk
sudo qemu-img info $thedomain.$snapshotname -U --backing-chain

# capture original backing file name so we can revert
backingfile=$(qemu-img info $thedomain.$snapshotname -U | grep -Po 'backing file:\s\K(.*)')
echo "backing file: $backingfile"

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

# stop VM
virsh destroy $thedomain

# edit hda path back to original qcow2 disk
virt-xml $thedomain --edit target=$targetdisk --disk path=$backingfile --update

# validate that we are now pointing back at original qcow2 disk
virsh domblklist $thedomain

# delete snapshot metadata
virsh snapshot-delete --metadata $thedomain $snapshotname

# delete snapshot qcow2 file
sudo rm $pooldir/$thedomain.$snapshotname

# start guest domain
virsh start $thedomain

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

为什么内部快照被禁用?

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

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

操作系统:Fedora 26 + Virt-Manager v1.42 虚拟机:Win 10 UEFI + Q35

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

有解决办法吗?

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

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

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

帕维尔

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

原因是这里:

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

From: Laszlo Ersek <lersek redhat com>
To: Peter Krempa <pkrempa redhat com>
Cc: libvir-list redhat com
Subject: Re: [libvirt] [PATCH v2] qemu: snapshot: Forbid internal snapshots with pflash firmware
Date: Thu, 23 Mar 2017 17:49:56 +0100

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

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

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

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

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

如果变量 store () 文件是原始的,qemu 无法对其进行快照,因此快照将不完整。 QEMU 不会拒绝此类快照。

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

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

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

[...]

@@ -13873,8 +13873,14 @@ qemuDomainSnapshotPrepare(virConnectPtr conn, 转到清理; }

  • /* 内部快照不适用于具有 OVMF 加载程序的虚拟机,因为 qemu 可以
  • * not snapshot the variable store */
    
  • /* 内部快照 + 基于 pflash 的加载器存在以下问题:
  • * - if the variable store is raw, the snapshot is incomplete
    
  • * - alowing a qcow2 image as the varstore would make it eligible to receive
    
  • *   the vmstate dump, which would make it huge
    
  • * - offline snapshot would not snapshot the varstore at all
    
  • *
    
  • * Avoid the issues by forbidding this completely.
    
  • */
    

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

原因如下:

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

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

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

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

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

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

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

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

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

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

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

用户不会阅读文档(他们永远不会这样做),而且我宁愿不提交有关模糊安全启动不当行为的未来错误报告。

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

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

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

  • 而且,由于还有其他(独立的)libvirt 客户端应用程序,这可能需要在 libvirt API 级别上有一个新标志,以便 libvirt 本身可以拒绝不安全的快照请求,无论提交它的客户端应用程序如何。

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

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

谢谢!拉斯洛

相关内容