Cloud Hypervisor 设备模型完全指南:从 Legacy 设备到 Virtio 与 Vhost-user 的设备矩阵解析
【免费下载链接】cloud-hypervisorA Virtual Machine Monitor for modern Cloud workloads. Features include CPU, memory and device hotplug, support for running Windows and Linux guests, device offload with vhost-user and a minimal compact footprint. Written in Rust with a strong focus on security.项目地址: https://gitcode.com/GitHub_Trending/cl/cloud-hypervisor
导读
本文以 docs/device_model.md 为核心骨架,系统梳理 cloud-hypervisor(一个面向现代云工作负载、以 Rust 编写的虚拟机监控器)所支持的完整设备模型,包括 Legacy 设备、virtio 设备、vhost-user 设备与 VFIO 直通四大类别。文章会逐一说明每种设备的启用方式、默认状态、构建期可配置性以及典型使用场景,并结合仓库源码(devices、vmm、virtio-devices)印证设备实现与配置解析细节,帮助你准确回答"某个设备默认开不开、如何开启、底层如何实现"这类问题,并据此规划自己的 VM 启动参数。
设备总览:一张表看懂设备矩阵
cloud-hypervisor 的每种设备都有三个维度的属性:构建期是否可配置(是否能用 Rust feature 编译掉)、默认是否启用、运行期是否可配置(能否通过命令行参数改变行为)。原文档开头的汇总表完整列出如下:
| 设备 | Build configurable | Enabled by default | Runtime configurable |
|---|---|---|---|
| Serial port | |||
| RTC/CMOS | |||
| I/O APIC | |||
| i8042 shutdown/reboot | |||
| ACPI shutdown/reboot | |||
| virtio-blk | |||
| virtio-console | |||
| virtio-iommu | |||
| virtio-net | |||
| virtio-pmem | |||
| virtio-rng | |||
| virtio-vsock | |||
| vhost-user-blk | |||
| vhost-user-fs | |||
| vhost-user-net | |||
| VFIO |
解读这张表可以得到几个关键结论:virtio 类设备全部是"内置(always built-in)+ 按命令行参数动态启用"的模式,这与 cloud-hypervisor 追求最小、紧凑、按需组合的设计目标一致;只有 RTC/CMOS 和 VFIO 允许在构建期裁剪(通过 Rust feature);而"始终启用且无法关闭"的只有 ACPI 设备与 RTC/CMOS。所有设备的具体实现分散在 devices/src(Legacy 设备)与 virtio-devices/src(virtio 后端)中,由 vmm/src/device_manager.rs 统一装配。
Legacy 设备:支撑最小启动与关机重启的基石
Legacy 设备是传统 PC 兼容平台上必不可少的部分。它们大多直接通过端口 I/O(port I/O)或内存映射 I/O 模拟硬件寄存器,实现在 devices/src/legacy 目录下。
Serial port:获取早期启动日志的关键通道
串口通过读写特定的端口 I/O 地址来模拟,是收集虚拟机内操作系统早期启动日志的最有效手段——在内核尚未就绪时,virtio-console 等设备还不可用,串口几乎是唯一的输出通道。
- 在 x86_64 平台,默认串口来自模拟的16550A设备;Linux 客户机可用
console=ttyS0将其作为默认控制台。 - 在 AArch64 平台,默认串口来自模拟的PL011 UART设备(实现见 devices/src/legacy/uart_pl011.rs),对应内核参数为
console=ttyAMA0。
该设备总是被编译进二进制,但默认禁用,只有--serial参数的值不是off时才启用。从 vmm/src/config.rs 的CommonConsoleConfig::parse可以看到串口/控制台共用的输出模式解析逻辑,支持以下取值:
off:禁用(默认状态);pty:输出到一个伪终端;tty:直接使用当前终端 tty;null:丢弃所有输出;file=<path>:写入指定文件(若指定 file 但模式不是 file 会报校验错误);socket=<path>:通过 Unix socket 输出。
对应的SerialConfig与ConsoleConfig解析器分别位于 vmm/src/config.rs 与 vmm/src/config.rs,后者额外支持PciDeviceCommonConfig的选项(如iommu、pci_segment、pci_device_id)。
RTC/CMOS:让 Windows 与 EFI 也能读时间
对于依赖 KVM clock 之外的时钟源的 Windows 或 EFI 环境,RTC/CMOS 模拟是平台可用的前提。该设备默认编译进二进制,但可通过 Rust feature 在构建期去掉;一旦编译进去就始终启用、无法从命令行关闭。x86_64 上对应 CMOS 实现 devices/src/legacy/cmos.rs;在 AArch64 平台则实现了 ARM PrimeCell Real Time Clock(PL031),见 devices/src/legacy/rtc_pl031.rs,同样默认内置且始终启用。
I/O APIC:拆分的 IRQ 芯片实现
cloud-hypervisor 支持所谓的 split IRQ chip(分离式中断控制器)实现:通过实现 IOAPIC,把 IRQ 芯片模拟的一部分从内核态搬到用户态,从而避免中断控制器模拟始终运行在完全特权模式下。相关代码在 devices/src/ioapic.rs。
I/O APIC 总是内置,其启用与否取决于串口是否存在:如果串口被禁用,且没有任何其他设备需要基于引脚的中断(INTx),I/O APIC 也会一并禁用。
i8042:极简的 PS/2 端口
i8042 是一个高度简化的 PS/2 端口(实现见 devices/src/legacy/i8042.rs),只支持一个按键来触发重启或关机(具体行为取决于 ACPI 支持与否)。它总是内置但默认禁用:由于 ACPI 默认开启,重启/关机由专用 ACPI 设备处理;只有 ACPI 被禁用时,i8042 才会启用,为 VM 兜底提供重启/关机能力。
ARM PrimeCell GPIO(PL061):AArch64 的优雅关机按钮
针对 AArch64 客户机,实现了简化的 ARM PrimeCell GPIO(PL061,见 devices/src/legacy/gpio_pl061.rs),只支持 key 3 来触发客户机的优雅关机(graceful shutdown)。
ACPI 设备:默认的关机/重启通道
当 ACPI 开启时,由专用 ACPI 设备处理关机与重启。该设备总是内置且默认启用(因为 ACPI 特性默认开启)。ACPI 相关逻辑见 devices/src/acpi.rs。
Virtio 设备:按需启用的半虚拟化主力
对于下述所有 virtio 设备,cloud-hypervisor仅支持virtio-pci传输层。此外 cloud-hypervisor 支持多 PCI 段(PCI segment),用户可以在设备参数后追加,pci_segment=<PCI_segment_number>或,pci_device_id=<PCI_device_ID>,把设备分配到指定 PCI 段或指定设备槽位,这对大型多段拓扑的组织很有用。这些通用选项定义在PciDeviceCommonConfig(见 vmm/src/config.rs),virtio 后端实现位于 virtio-devices/src(如 block.rs、net.rs、iommu.rs 等)。
virtio-block:引导客户机的块设备
virtio-blk 向客户机暴露一个块设备,通常用于引导客户机操作系统。设备总是内置,通过--disk参数的存在与否决定启用。典型的--disk参数支持path=<镜像路径>,readonly=on|off,direct=on|off,iommu=on|off等子选项,并可附带serial=<序列号>(序列号长度不能超过 virtio-blk 定义的 ID 上限,否则校验会失败,见 vmm/src/config.rs)。底层块格式支持 raw、qcow2、vhd、vhdx、vmdk 等多种格式,实现在 block/src/formats 与 block/src/disk_file.rs。
virtio-console:更快更完整的客户机控制台
virtio-console 是默认启用的客户机控制台。虽然用它做控制台可能会截断一部分早期启动消息,但它能缩短客户机启动时间并提供完整控制台实现。如果需要切换回传统串口,可执行:
--serial tty --console off即串口输出到当前终端、关闭 virtio-console。从源码看,ConsoleConfig与SerialConfig共享同一套输出模式解析(off/pty/tty/null/file/socket),区别仅在于 console 额外支持iommu等 PCI 通用选项。
virtio-iommu:半虚拟化 IOMMU
为改进嵌套客户机(nested guest)支持,cloud-hypervisor 通过 virtio 暴露一个半虚拟化 IOMMU 设备(详见 docs/iommu.md),用于更安全地支持嵌套 virtio 与设备直通。设备总是内置,只要任意 virtio 或 VFIO 设备带上了iommu=on参数,virtio-iommu就会被创建——也就是说它由其他设备的配置隐式触发。
virtio-net:自动创建 TAP 的网络设备
virtio-net 为客户机提供网络连接:cloud-hypervisor 会在宿主机上自动创建 TAP 接口并与之相连(TAP 打开逻辑见 net_util/src/open_tap.rs)。设备总是内置,由--net参数启用。--net支持tap=<已有tap>,mac=<mac>,ip=<ip>,mask=<netmask>,iommu=on|off,vhost_user=on|off等参数。
virtio-pmem:可引导的虚拟持久内存
virtio-pmem 模拟一个虚拟持久内存设备,cloud-hypervisor 可以从该设备引导系统。从 virtio-pmem 引导可以绕过客户机页面缓存(page cache),改善客户机内存占用。设备总是内置,由--pmem参数启用,典型用法:
--pmem file=/path/to/pmem.img,size=1G注意--pmem必须有file且支持size与discard_writes参数(解析见 vmm/src/config.rs)。
virtio-rng:向客户机注入熵
虚拟机不像真实机器那样天然产生熵,而客户机内的负载(如 TLS、随机数生成)需要随机数。virtio-rng 借助宿主机的随机源为客户机提供熵,默认熵源是/dev/urandom。该设备总是内置且始终启用,可用--rng改变熵源(例如--rng source=/dev/random)。
virtio-vsock:高效安全的主客机通信
virtio-vsock 是 VSOCK socket 地址族在 virtio 之上的混合实现,用于更高效、更安全的主客机通信。原文档明确说明该实现复制自 Firecracker 项目(相应实现见 virtio-devices/src/vsock)。设备总是内置,由--vsock参数启用,例如:
--vsock cid=3,socket=/tmp/vsock.sockVhost-user 设备:把 virtio 后端搬出 VMM 进程
vhost-user 设备本质上是运行在 VMM 之外的独立进程中的 virtio 后端,目的是带来更强的灵活性与隔离性。由于后端独立成进程,使用时通常要求 VM 由共享内存支撑(校验逻辑见 vmm/src/config.rs:vhost_user设备必须搭配共享内存,且必须提供socket参数,且不支持速率限制)。
vhost-user-blk:外置的块后端
作为将半虚拟化 I/O 卸载到外部进程的整体工作的一部分,cloud-hypervisor 支持 vhost-user-blk 后端,用户可以把基于 vhost-user 的块设备(例如 SPDK)接入 VMM。启用条件是--disk参数中同时提供vhost_user=true与socket=<socket路径>:
--disk vhost_user=true,socket=/path/to/vhost-blk.sock相关后端接入逻辑见 vhost_user_block 与 virtio-devices/src/vhost_user/blk.rs。
vhost-user-fs:高效的宿主机/客户机文件系统共享
cloud-hypervisor 支持 virtio-fs 共享文件系统,用于在宿主机与客户机之间高效、可靠地共享文件系统。完整用法见 docs/fs.md。设备总是内置,由--fs参数启用,典型形式为:
--fs tag=myfs,socket=/path/to/virtiofsd.sock其中 tag 必须在 cloud-hypervisor 命令行中指定(tag 长度不能超过VIRTIO_FS_TAG_LEN,见 vmm/src/config.rs)。
vhost-user-net:外置的网络后端
同样出于 I/O 卸载目标,支持 vhost-user-net 后端(例如 DPDK 方案),用户可以把基于 vhost-user 的网络设备接入 VMM。启用条件与块设备一致:--net参数提供vhost_user=true与socket:
--net vhost_user=true,socket=/path/to/vhost-net.sock相关后端见 vhost_user_net 与 virtio-devices/src/vhost_user/net.rs。
vhost-user-generic:承载任意 vhost-user 后端的通用设备
vhost-user-generic 是一个通用 vhost-user 设备,主要用途是接入 cloud-hypervisor 原生不支持的 vhost-user 设备;当然,它同样可以用于 cloud-hypervisor 已经支持的设备。一个典型差异场景是:virtio-fs 设备的 tag 可以在 virtiofsd 命令行设置,而内置 virtio-fs 支持要求 tag 必须在 cloud-hypervisor 命令行设置——用通用设备即可规避这一限制。
在协议层面:如果后端协商了VHOST_USER_PROTOCOL_F_CONFIG特性,则所有配置空间访问都由后端处理;否则写入会被忽略、读取返回 0xFF,cloud-hypervisor 会对这种情况发出告警。
该设备总是内置,通过--generic-vhost-user标志启用,详细用法见 docs/generic-vhost-user.md 与 virtio-devices/src/vhost_user/generic_vhost_user.rs。
VFIO:把物理设备直接交给客户机
VFIO(Virtual Function I/O)是内核提供的、把设备直接访问权暴露给用户态的框架。cloud-hypervisor 通过 VFIO 把宿主机物理设备**直接分配(直通)**给客户机,绕开 VMM 的中介模拟。详细用法见 docs/vfio.md。
在构建层面:由于 VFIO 在 cloud-hypervisor 语境下意味着vfio-pci,因此 VFIO 支持在选中pcifeature 时内置;而pcifeature 默认开启,所以VFIO 支持默认也是内置的。当 VFIO 支持编译进来后,用--device参数即可启用直通路径,例如:
--device path=/sys/bus/pci/devices/0000:01:00.0相关实现位于 pci/src/vfio.rs 与 vfio-user 支持,DeviceConfig的解析与校验集中在 vmm/src/config.rs。
设备装配与生命周期:从命令行到客户机可见
在源码层面,所有设备的最终装配都发生在 vmm/src/device_manager.rs 中:make_virtio_block_devices、make_virtio_net_devices、make_virtio_rng_devices、make_virtio_pmem_devices、make_virtio_vsock_devices等函数按配置逐个构建 virtio 设备(见 vmm/src/device_manager.rs),Legacy 设备则由add_serial_device等函数添加(vmm/src/device_manager.rs)。设备构建还支持快照恢复(snapshot/restore)路径:上述函数均接受Option<&Snapshot>参数,迁移恢复时可直接从快照重建设备。
命令行的整体解析入口在 vmm/src/config.rs 的VmConfig,其中--serial、--console、--disk、--net、--pmem、--rng、--vsock、--fs、--device、--generic-vhost-user等参数分别对应上文各类设备的*Config::parse实现,并经过validate阶段做交叉校验(例如 vhost-user 必须配共享内存、磁盘 socket 与 path 不能同时存在、串口 socket 模式必须带 socket 路径等)。
结语
cloud-hypervisor 的设备模型可以概括为三个层次:Legacy 设备保障了与传统固件、Windows/EFI 环境的兼容以及关机重启等基础语义;virtio 设备提供按需启用的半虚拟化 I/O(块、网络、控制台、内存、熵、通信);vhost-user 与 VFIO则分别把 I/O 后端隔离到独立进程、把物理设备直接交付给客户机,兑现"极小、紧凑、安全优先"的设计承诺。理解这张设备矩阵及其默认状态,是正确编写 cloud-hypervisor 启动参数、排障设备缺失问题、以及评估某项工作负载所需设备组合的第一步。
【免费下载链接】cloud-hypervisorA Virtual Machine Monitor for modern Cloud workloads. Features include CPU, memory and device hotplug, support for running Windows and Linux guests, device offload with vhost-user and a minimal compact footprint. Written in Rust with a strong focus on security.项目地址: https://gitcode.com/GitHub_Trending/cl/cloud-hypervisor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考