Spice-QXL

QXL消息流程

QXL message flow:

以上绿色线表示为一个图形绘制流程,当GuestOS上的一个user应用需要产生一个渲染操作的时候,

  1. 由Guest APP发送请求给Guest的图形引擎(GDI/X)
  2. 图形引擎将命令传送给qxl驱动
  3. qxl驱动将命令翻译为qxl命令推送到qemu中qxl设备的消息队列里面
  4. libspice从队列里面取数据,将其加入到display Tree中
  5. display Tree包含了命令的集合,执行这些命令会产生显示内容。这棵树也可以优化掉那些会被覆盖掉的命令。这个命令树还用来检测video数据流。
  6. 当一条命令从队列中取出发给客户端是,发送的命令被转换为Spice协议消息,同时这个命令从发送队列和树上移除。
  7. 当一个命令不再使用时,libspice将其放入驱动release ring,qxl驱动释放掉命令资源。client收到图形命令后用其来更新显示。

QXL–>VDI

Spice中的VDI是一个接口规范,此类接口设计的主要目标是在尽量不改变原有代码的情况下,通过动态库的方式来为原有软件提供全新的功能组件。qemu也是通过VDI借口与Spice交互的
VDI
VDI接口规范本身非常简单,它仅为开发人员提供一种标准的开发方式,具体的VDI接口功能则由程序员自己负责。具体的约束总结如下:

  1. 必须包含一个固定的BaseInterface结构体成员。
  2. Back-end与Front-end的交互关系初始化工作由Back-end负责发起。
  3. Back-end负责实现与Back-end内部强相关且Front-end感兴趣的功能接口。
  4. Front-end负责实现与Front-end内部强相关且Back-end感兴趣的功能接口。

QXLInterface是最主要也是最复杂的一个VDI,并且与其他VDI不同的是,Front-end有一个单独的网络处理模型, QXLInterface在Front-end有自己单独的处理线程。Back-end端需要实现Qxl device,同时需要Guest OS的Driver配合工作。另外,Qemu需要Spice为其提供相关的接口来完成一些交互工作。

QXL图形子系统

Spice server通过通道(channel)与client通信,每个通道类型专用于特定类型的数据。每个通道使用一个特定的tcp socket(可以是ssl或非安全的)。
主通道和输入通道受handler函数(在reds.c中实现)控制,显示和光标通道在red worker线程(每个display一个线程)里面处理,音频回放和录音通道有自己的handler(snd_worker.c)。libspice和VDI主机程序(比如qemu)通过为每个功能(qxl,agent,keyboard,mouse等)定义的接口来通信。
red 与其它spice server中的子系统不同,图形子系统是与spice server并行的一个专门线程。这种架构可以使qemu流程与处理和渲染图形命令独立开来,因为后者会占用大量cpu资源。Red server在每个新的qxl接口中初始化一个dispatcher,dispatcher创建一个red worker。red worker处理的命令来自三处:1) 同步的qxl设备命令;2)red server命令;3)异步qxl设备命令。其中1)和2)由red dispatcher通过socket传送,3)由red worker从qxl设备ring中通过接口取出。
Red Worker(red_worker.c)
spice server为每个qxl设备实例运行一个red worker线程。

red worker的作用主要有:
* 处理qxl设备命令;
* 处理从dispatcher收到的消息;
* channel pipe和pipe item;
* 显示和光标通道;
* 图形压缩(使用quic,lz,glz);
* 视频流---识别、编码、创建流;
* 缓存---client共享的pixman缓存、光标、调色板缓存
* Cairo和OpenGL渲染----canvas,surface等 
Red Dispatcher(red_dispatcher.c)
* 每个qxl实例一个dispatcher
* 初始化red worker,创建red worker线程
* 使用socketpair通道调度worker
* qxl设备使用QxlWorker接口,dispatcher实现并attach这些接口,将设备调用翻译成在worker管道中传递的消息。

QXL指令

qxl指令分为异步和同步。

QXL指令代码流程
Spice源码流程

### 解决 Virt-Manager 中 SPICE GL (Spice-Glx) 不支持的问题 #### 问题背景 在使用 Virt-Manager 创建或编辑虚拟机时,如果尝试启用 SPICE GL(也称为 Spice-Glx)作为显示协议却发现其不可用或报错“not supported”,通常是因为系统环境中某些必要组件缺失、配置错误或者硬件不兼容所引起。 --- #### 原因分析与解决方法 ##### 1. 主机硬件是否支持 GPU 虚拟化 SPICE GL 需要主机具备 GPU 虚拟化的功能。如果没有启用相关设置或硬件本身不支持,则会导致无法正常工作。 **解决方法:** 确认 BIOS/UEFI 中启用了以下选项: - 对于 Intel 平台,确保开启了 **Intel VT-d**。 - 对于 AMD 平台,确保开启了 **AMD-Vi (IOMMU)**[^1]。 此外,还需要验证主机显卡驱动是否支持 GPU 虚拟化技术。例如 NVIDIA 用户应安装支持 Virtual GPU 的驱动版本,并检查是否加载了 `nvidia-virtualgpu` 模块。 --- ##### 2. 是否安装了必要的软件包和支持库 为了使 SPICE GL 正常运行,需要一系列额外的支持工具和库文件。这些包括但不限于: - **Mesa 库**: 提供 OpenGL 支持。 - **libvirt 版本**: 确保使用的 libvirt 是较新的稳定版本。 - **QEMU/KVM 插件**: 启用 SPICE 和 GL 扩展的相关模块。 **解决方法:** 更新并安装所需的依赖项。以下是针对不同 Linux 发行版的命令示例: 对于 Ubuntu/Debian: ```bash sudo apt update && sudo apt install -y \ mesa-utils \ qemu-kvm \ libvirt-daemon-system \ libvirt-clients \ spice-server-xpi \ spice-client-gtk \ libegl1-mesa-dev \ libgles2-mesa-dev ``` 对于 CentOS/RHEL: ```bash sudo yum groupinstall "Development Tools" sudo yum install -y \ qemu-kvm \ libvirt \ virt-manager \ spice-server \ mesa-libGL-devel \ mesa-libEGL-devel ``` 同时,还需验证是否存在 `libepoxy` 库以及对应的开发头文件。若不存在,请一并安装。 --- ##### 3. XML 配置中的 `<graphics>` 参数是否正确 Virt-Manager 自动生成的虚拟机 XML 文件可能未能完全覆盖 SPICE GL 的需求参数。因此,手动调整 XML 配置可能是解决问题的关键之一。 **解决方法:** 导出目标虚拟机的 XML 文件并通过文本编辑器修改相关内容。重点在于 `<graphics>` 节点及其子属性,具体如下所示: ```xml <domain type='kvm'> <name>example_vm</name> <devices> <graphics type='spice' port='-1' autoport='yes' listen='0.0.0.0' gl='yes'> <listen type='address' address='0.0.0.0'/> <image compression='off'/> <streaming mode='all'/> <gl enable='yes' rendernode='/dev/dri/renderD128'/> </graphics> <video> <model type='qxl' heads='1' primary='yes'/> </video> </devices> </domain> ``` 在此处需要注意的是: - 将 `type='spice'` 添加至 `<graphics>` 标签中。 - 使用 `rendernode` 属性指明具体的 DRI 设备节点位置[^3]。 完成后重新导入修改后的 XML 文件即可。 --- ##### 4. SELinux/AppArmor 安全策略的影响 SELinux 或 AppArmor 这类强制访问控制系统有时会限制 QEMU-KVM 进程对 GPU 设备的访问权限,进而阻碍 SPICE GL 的启动过程。 **解决方法:** 可以暂时禁用 SELinux 来测试是否与此有关联: ```bash sudo setenforce 0 ``` 如果发现此时能够成功启用 SPICE GL,则表明确实存在安全策略方面的冲突。长期解决方案为自定义 SELinux 策略规则以适应当前环境需求。 同样地,在 AppArmor 下也可以采取类似手段排查问题所在。 --- ##### 5. 显存分配不足或其他性能瓶颈 即便完成了以上所有步骤,仍有可能因为显存容量过低而使得 SPICE GL 失效。这是因为高分辨率图像渲染需要消耗大量显存资源。 **解决方法:** 增加分配给虚拟机视频设备的 RAM 数量。可以通过调整 `<video>` 节点下的 `ram` 和 `vram` 属性实现这一目的。例如: ```xml <video> <model type='qxl' ram='65536' vram='65536'/> </video> ``` 此处单位为 KiB,默认值可能不足以支撑复杂场景下 SPICE GL 的运作。 --- ### 总结 通过逐一排除上述潜在障碍——从硬件支持情况到软件环境准备再到细粒度的 XML 配置优化——大多数情况下都可以顺利激活 Virt-Manager 中 SPICE GL 的功能。然而值得注意的是,鉴于各平台差异较大,实际操作过程中或许还会遇到其他特殊情况,届时可根据具体情况灵活应对。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值