LWN:不用VM也能使用QEMU存储功能!

关注了就能看到更多这么棒的文章哦~

Accessing QEMU storage features without a VM

October 25, 2022
This article was contributed by Stefan Hajnoczi
KVM Forum
DeepL assisted translation
https://lwn.net/Articles/911281/

QEMU 模拟器,包含了许多存储相关的功能,支持了如 qcow2 等许多 disk-image 文件格式、快照、增量备份、存储迁移等,这些功能都是可供虚拟机使用的。然而,这种在 QEMU 内部提供的软件定义的存储功能(software-defined storage functionality)在 QEMU 之外就没那么容易用上了。Kevin Wolf 和 Stefano Garzarella 在 2022 年 KVM 论坛上介绍了新的 qemu-store-daemon 程序和 libblkio 库,可以让 QEMU 的存储功能可以在不运行虚拟机(VM)的情况下使用。

d298c01e89c7e2f2fa0a94acf3e4dcbd.png

[Kevin Wolf & Stefano Garzarella] 。

就如同 Linux 内核一样,QEMU 有一个支持了磁盘 I/O 的 block layer,它会代表虚拟机来执行任务,完成磁盘 I/O,并且可以在做这些工作时支持带宽控制。虚拟机所看到的虚拟磁盘背后其实都是磁盘镜像文件。一般是文件,或者是块设备,但它们也可以是网络存储。虚拟机中可以使用许多种磁盘镜像文件格式,QEMU 能支持这些格式,其中它本身支持的 qcow2 格式是最广泛使用的格式之一。QEMU 的 block 层还包括一些长期运行的后台操作,被称为 blockjobs,用于迁移、做 mirror、以及合并磁盘镜像。

The QEMU process model

Wolf 首先介绍了 QEMU 的进程模型,每个虚拟机都是一个独立的 QEMU 进程,有自己独立的 block layer,可以在下图中看到。一个名为 QEMU Monitor Protocoal(QMP)的类似 JSON-RPC 的管理界面中提供了大量的命令,可以用来在 QEMU 进程运行时对磁盘镜像进行各种操作。QMP command 可以支持存储迁移、增量备份,等等。这里有一个问题,必须要有 QEMU 进程正在运行才可以,于是虚拟机关闭时就难以继续使用 QMP 命令了。

9380276e5df33997dc904c55c474a61e.png

[QEMU 进程模型]

每个 QEMU 进程对应一个虚拟机,这就带来了另一个限制,那就是磁盘镜像在虚拟机之间只能以只读方式来共享,从而避免多个 QEMU 进程不经商量就更新了共享的磁盘镜像,从而导致数据损坏。当几个虚拟机从相同的一个模板 "备份文件"创建出来时,这个问题就会有影响。只要有两个或更多的虚拟机正在共享这些文件,那么这些备份文件就必须确保不可以被修改。

由于这些原因,QEMU 中的磁盘镜像功能直到现在还只能限于 active VM 以及一些特定的工具(qemu-img 和 qemu-nbd)来使用。

qemu-store-daemon

新增的 qemu-store-daemon 程序使得磁盘镜像功能不再受“一个 QEMU 进程对应一个虚拟机”的限制。qemu-store-daemon 作为一个独立的进程运行,完全不需要任何虚拟机,并提供了以前只在 QEMU 中可用的 QMP 命令来对磁盘镜像文件进行操作。

Wolf 介绍了两种方式来更好地理解 qemu-store-daemon。它可以被看作是一个高级的 qemu-nbd,支持 QMP monitor commands 以及更多的 export 类型。或者它也可以被看作是没有运行虚拟机能力的 QEMU。它对应的命令行和可用的 QMP 命令都与 QEMU 非常相似。

下面的 qemu-store-daemon 命令会对 raw image 文件 test.raw 来提供一个 Network Block Device (NBD) 类型的 export,这样就可以通过网络来读取磁盘镜像了:

$ qemu-storage-daemon \
  --nbd-server addr.type=inet,addr.host=0,addr.port=10809 \
  --blockdev file,filename=test.raw,node-name=disk \
  --export nbd,id=exp0,node-name=disk

他也介绍了几个使用 qemu-storeage-daemon 的案例。把存储设备以及实际运行的虚拟机实例区分开是很合理的做法,两者可以分别管理了。用来对 storage 进行管理的工具,不应该访问 VM 的 QMP 接口,并且 VM 管理工具也不应该访问 qemu-storage-daemon 的 QMP 接口。而且,把存储分离出来之后,就可以对 QEMU VM 和 qemu-storage-daemon 施加更严格的沙盒保护(sandboxing),这样哪怕其中一个程序被攻破了,也不太会影响系统中的其他部分。

dabced58ef2456b5eb56fd2ba3b7a077.png

[qemu-storage-daemon model]

让 qemu-storage-daemon 称为系统中的唯一一个访问磁盘镜像文件的进程,就可以支持以前的访问模型所无法支持的一些新的使用场景了。如上图所示,QEMU 进程可以连接到 qemu-storage-daemon,这样,VM 通过 daemon 访问磁盘镜像,而不是直接用 QEMU 进程来访问。这样就可以实现对多个 VM 公用的文件进行修改了,因为实际上只有 qemu-storage-daemon 这一个进程会对这个共享的文件拥有写操作。

在虚拟机关闭时就没有办法再执行某些磁盘镜像操作的情况下,现在就可以启动 qemu-store-daemon 来应对这种情况。在虚拟机运行时会通过 qemu-store-daemon 来访问磁盘镜像,这样运行中的虚拟机和 qemu-store-daemon 内的动作就不会有冲突。在虚拟机关闭时,qemu-store-daemon 仍然可以为那些需要操作磁盘镜像的请求提供服务。这使得长期运行的操作(如对后台文件进行 commit 操作)在虚拟机关闭时也不会受到损害,这很有用,因为 commit 操作可能由云提供商来执行,而虚拟机关闭则由最终用户自己决定。如果虚拟机在提交操作完成之前被再次启动的话,它仍然可以通过 qemu-storage-daemon 来访问这个磁盘,commit 操作也在继续进行。

这个“一个 VM 对应一个 QEMU 进程”的模型在使用 polling 方式来提升性能的时候也有局限性。在有许多 QEMU 进程的机器上,每个进程都执行自己的 polling,都会消耗 CPU 时间。qemu-store-daemon 可以将 I/O 处理合并到一个进程中,代表多个虚拟机进行轮询,从而为运行中虚拟机省下了更多的 CPU。

在 QEMU 的用户空间 NVMe PCI 驱动被用来榨取设备的最大性能时,就会出现另一个使用场景。NVMe 设备只能由一个进程访问,所以通常只有一个运行中的虚拟机可以打开这个设备。如果不用 QEMU,而是用 qemu-store-daemon 来运行用户空间的 NVMe PCI 驱动,那么就可以有多个虚拟机能同时连接到这个设备了,一个 NVMe 设备就可以被分割成更小粒度的虚拟设备给虚拟机使用。

也许最有趣的使用场景是,qemu-storage-daemon 使 QEMU 的存储功能可以用于 QEMU 之外的其他应用程序了。备份程序、取证工具(forensics tools)以及其他的程序都可以使用 qemu-store-daemon 来访问磁盘镜像,对它们进行操作,并采集快照了。qemu-store-daemon 最初是在 QEMU 5.0.0 中发布的,基于 Debian 的发行版中是在 qemu-system-common 包里,基于 Fedora 的发行版则是在 qemu-img 包中。

采集快照、在运行时添加/删除 export、为增量备份管理 dirty bitmap 等命令都可以通过使用 QMP 协议的 Unix domain socket 来下达。QMP 是一个控制通道,不适合用来实际访问磁盘镜像或 dirty bitmap 的内容。而 qemu-store-daemon 则通过其 export type 提供了几种连接到磁盘镜像的方法。

Block exports types

Network Block Device(NBD)协议在 Linux 中有着悠久的历史,是通过网络来访问 block 设备的一种相当简单的方式。鉴于 QEMU 已经包含了一个 NBD 服务程序和 qemu-nbd 工具,qemu-store-daemon 就可以通过 NBD 导出磁盘镜像了。程序可以直接连接上去,此外还有一个 Linux 内核驱动可以用来将 NBD 所 export 的数据作为 block 设备 attach 上去。

在 qemu-store-daemon 中也有一个 Linux Filesystem in Userspace(FUSE)的 export type。qemu-storage-daemon 处理 qcow2 文件格式的细节看起来更像是处理一个 raw 文件,fdisk、dd 和其他程序都知道如何访问。目前实现的是同步方式的操作(synchronous),因此性能不如其他 export type 好。Wolf 提到,FUSE export type 提供了一种简单的方法,可以将磁盘镜像作为 raw 文件来呈现给那些只能访问普通文件的程序。

vhost-user-blk 这种 export type 是 QEMU 支持的一个 Unix domain socket 协议。与 NBD 不同,它不是通过网络来生效的,而是利用了共享内存,所以 qemu-storage-daemon 可以从磁盘读写 guest 的 RAM。这使得 vhost-user-blk 自然成为了连接 QEMU 虚拟机和 qemu-store-daemon 的一个选项,因为它是最高效的 export type。其他应用程序也可以通过本文后面介绍的新的 libblkio 库来使用这种 export type。

vDPA Device in Userspace(VDUSE)这种 export type 处理了内核中相对较新的 vDPA 驱动框架所发出的 I/O 请求。当 virtio_vdpa 内核模块被加载时,这个 export 看起来就是一个 virtio_blk 设备,可以跟其他 Linux 块设备一样使用。或者,在 host 上加载 vhost_vddpa kernel module 时,这个 export 就显示为一个 Linux vhost 设备,可以作为 virtio-blk 设备被添加到 QEMU 虚拟机中。因此,VDUSE 导出类型实现了两种功能,既向 host 又向 VM 提供了存储访问。请注意,这里的功能与其他的 export type 有一些重叠,需要 VDUSE 的人都会知道他们需要使用这些功能,而其他人可能会坚持使用那些更传统的 export type。

libblkio

为了能高效地访问磁盘镜像,qemu-store-daemon 提供了 server 进程,而 libblkio 库提供了一个客户端 API。由于需要实现 vhost-user-blk 和其他访问 qemu-store-daemon export 协议,所以如果有这么一个库提供这个功能,就很方便了,可以省去应用程序的重复工作。

libblkio 1.0 版本提供了 Linux io_uring 用在文件 I/O 上的功能,主要使用了 NVMe io_uring cmd 来做 NVMe 基准测试,使用了 virtio-blk(vhost-user 和 vhost-vdpa)来连接到 qemu-store-daemon 并访问 vdpa-blk 设备。这样选择下来的驱动使得这个函数库既可用于连接 qemu-storage-daemon,也可用于直接访问文件或 NVMe 设备。

关于 libblkio 的全面概述将留待 KVM 论坛的另一场演讲;希望了解更多信息的人可以观看 YouTube 视频和相关幻灯片。然而,最主要的信息是,希望使用 qemu-storage-daemon 的应用程序都可以使用 libblkio 来通过 vhost-user-blk 进行连接。这个函数库的软件包还没有像 qemu-store-daemon 那样被广泛使用,但随着时间的推移,一定会改善的。

Conclusion

QEMU 的进程模型使得某些组合很难实现,但 qemu-store-daemon 则为存储功能提供了一个专门的进程,从而增强了传统的 QEMU 进程模型,大大减少了这些问题。此外,qemu-storage-daemon 将 QEMU 的一系列存储功能暴露给所有希望使用这些功能的程序,哪怕它们并不使用虚拟机。 libblkio 则提供了 qemu-storage-daemon 的客户端功能,可以让某个程序连接到这些存储。跟 qemu-storage-daemon 一样,libblkio 也是会被 QEMU 使用的,但设计时确保也可用在于与 QEMU 无关的其他程序中。

qemu-storage-daemon 和 libblkio 除了用于 QEMU 之外,还可以用在哪些地方呢?这还有待观察,但从 QEMU 中提取功能并使其可用于外部使用,就为这方面的的未来的无限可能性打开了大门。

如果想了解更多信息,可以在 YouTube 上观看演讲的视频以及幻灯片。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值