spice新手学习手册

1、基本架构

spice基本编译模块是spice协议,spice服务器和spice客户端。spice的相关组件包含QXL设备和Guest QXL驱动。

1.1、图形命令流

上图所示,当qemu使用libspice库时,基本的spice框架和guest系统到客户端client图像命令数据流。libspice是被其他所有的VDI使用,兼容主机应用,图形指令数据流通过用户应用请求。

libspice拉指令从ring中和添加它们到图形命令树。图像命令树是一个命令的集合,libspice也维护了发送给客户端的命令队列。

1.2、agent命令流

spice agent是在guest系统中一个软件执行模块。spice服务器和客户端是通过agent完成在guest系统中执行的任务,比如设置guest系统的分辨率。上图显示spice客户端和服务器通信使用了VIDPort设备和guest驱动(Virtio-serial Driver)。客户端消息(如配置guest分辨率的消息),服务器消息(如鼠标的模式),和guest消息(如配置的ACK)。通过输入和输出的rings完成驱动与设备之间的通信。

消息适配器决定消息是否给服务器处理还是发送给客户端。

2、Spice Client

扫描二维码关注公众号,回复: 14650206 查看本文章

Spice跨平台(Linux与Windows)客户端是面向最终用户的接口。

2.1、客户端基本结构

2.2、客户端类

下面对Spice客户端的关键类进行一个介绍。为了有一个清楚跨平台结构,Spice定义基本的接口,在平行的目录保持指定平台的实现。在平台类的基本接口中定义了一些低级的服务接口,如定时器和鼠标操作。应用程序的main类客户端,监视器和屏幕。它处理基本的应用函数,如粘贴命令,运行主循环消息,处理事件(连接,断开,报错等),重定向鼠标事件到输入处理函数,选择全屏模式等。

2.2.1、通道

客户端与服务器是通过通道通信的。每个通道类型是专用的,为了传输指定类型的数据。各个通道使用TCP套接字,你可以选择安全的传输(SSL)和不安全的传输。在客户端这边各个通道都有一个专用的线程,这样不同的QoS服务质量各个之间互相不干扰。

RedClient serves作为主通道。它实例化其他通道和控制它们(使用他们的工厂创建通道)

所有通道的父类:

RedPeer:安全的和非安全的通信套接字通信,提供基础架构,比如连接,断开连接,关闭,接收消息,针对迁移的套接字互换。它定义了基本的消息类: InMessages, CompoundInMessage和OutMessage。所有的消息包含类型,大小和数据。

RedChannelBase:继承自RedPeer,提供与服务器建立通道连接的基本函数和与服务器支持通道的能力。

RedChannel :继承自 RedChannelBase,这个类是实例化通道的父类。操作发送消息和调度接收消息。RedChannel线程运行一个关于各种各样的事件源的事件循环(如发送,中止和触发器)。这个通道的套接字增加了事件源为了触发spice消息发送和接收。

可用的通道是:

主通道 -- 通过RedClient实现

显示通道 -- 处理图像命令,图像和视频流

输入通道 -- 键盘和鼠标输入。

鼠标形状通道 -- 指针设备位置、可见性和光标形状。

音频播放通道 -- 从服务器接收的要由客户端播放的音频。

录音通道 -- 在客户端捕获的音频。

ChannelFactory是所有通道工厂的基类。每个通道注册其特定的工厂,以使RedClient能够按通道类型创建通道。

2.2.2、屏幕与窗口

• ScreenLayer -- 屏幕层附加到特定屏幕上,提供矩形区域的操作(设置、清除、更新、无效等)。层按z顺序排列(例如,光标位于显示上方)。

• RedScreen -- 实现屏幕逻辑并控制窗口,使用屏幕层(例如显示器、光标)显示其内容。

• RedDrawable -- 基本位图的平台特定实现。它支持基本的渲染操作(例如,复制、混合、组合)。

• RedWindow_p -- 特定于平台的窗口数据和方法。

• RedWindow-继承RedDrawable和RedWindow_p。基本窗口状态和功能的跨平台实现(例如,显示、隐藏、移动、最小化、设置标题、设置光标等)。

2.2.3、spice服务器

spice服务器是通过libspice实现的,一个虚拟设备接口(VDI)的插件库。VDI提供一个标准方式为了通过软件组件发布虚拟设备接口。启动另外的软件组件为了连接到这些设备。为了更多的信息。服务器一边是通过使用远程spice协议连接到远程客户端,另一边,连接着VDI主机的应用(比如QEMU)。为了远程的显示目标服务器管理一个命令队列和一个管理依赖和隐藏的树。QXL命令被处理是通过spice协议命令发送到客户端。spice总是尝试传递渲染任务给客户端,因此促使它的硬件加速能力。在主机这边的渲染,是通过软件或者GPU,是最终的结果。spice服务器保持guest图像命令组成当前的图像。

2.2.3.1、服务器架构

服务器通过通道方式与客户端通信。各个通道类型是指定的数据类型。各个通道使用一个特定的TCP套接字,同时可以是安全的(使用SSL)或者不安全的。服务器通道和客户端通道是类似的:Main,Input,Display,Cursor,Playback和Record。其中Main和Input在同一个线程中处理函数(实现代码reds.c)。Display和Cursor以每个显示都有一个处理线程。音频playback和record通道有自己的处理者(snd_worker.c)。libspice和VDI主机应用(如QEMU)与定义好的各个功能(如QXL,agent,keyboard,mouse,tablet,playback,record)通过接口通信,详细如下。

上图显示spice server包括下面主要的几个组件:

Red Server(reds.c):服务器本身,监听客户端连接,accept它们并与它们通信。Reds主要职责是:

1、通道
• 拥有和管理通道(包括注册,注销,关闭)。
• 告诉客户端激活的通道,这样客户端创建它们。
• 主通道和输入通道命令处理。
• 连接建立(包括主通道和其它通道)。
• 套接字操作和连接管理。
2、处理SSL和ticketing。
3、VDI接口(如核心功能,迁移,键盘,鼠标,手写板,代理)添加和删除。
4、迁移过程协调
5、处理用户命令(如Qemu监视器命令)
6、与guest系统中agent通信。
7、统计。

图像子系统

不像spice服务器的其他子系统,图形子系统在专用线程上与服务器执行并行运行(如red工作线程)。这种结构实现了QEMU流与传入图形命令的处理和呈现之间的独立性,这会消耗大量CPU资源。上图显示spice服务器图像子系统的架构。Red Server在新的QXL接口上启动调度器(如VDI)。调度器通过那个接口创建Red Worker。命令的三个来源

(1)同步QXL设备的命令;
(2)red服务器命令,(1)和(2)都是调度程序使用套接字传递(如socket pair)
(3)异步QXL设备命令,worker通过使用接口拉取QXL设备的rings中的指令。

Red Worker(red_worker.c)

spice服务器为每个QXL设备实例保存不同的红色Worker线程实例。red_worker职责是

• 处理QXL设备命令(如画,更新,鼠标形状)
• 接收来自调度者的处理消息
• 通道管道和管道本身
• 显示通道和鼠标形状通道
• 图像压缩(使用quic,lz,glzenconding和jpeg)
• 视频流(定义,编码和流创建)
• 缓存(客户端共享pixmap缓存,cursor缓存,paletter缓存)
• 图像删除优化(使用对象树,容器,阴影除了区域和不透明对象)
• cairo和opengl渲染(canvas,surface等)
• Ring操作

Red Dispatcher(red_dispatcher.c)

• 每个QXL设备一个调度器
• 封装来自QXL设备和reds
• 初始化QXL设备实例worker和创建worker工作线程
• 使用socketpair通道调度worker
• QXL设备使用QXLWorker接口,实现和调用red调度器,它将设备调用转换为通过red_worker管道传输的消息,这种方式两部分是隔离的和逻辑上是独立的。
• Reds使用在red_dispathcer.h中定义的函数操作调度器,如调度器初始化,图像压缩改变,视频流状态变化,鼠标模式设置和渲染等。

2.4、spice协议

spice协议是用于客户端与服务器之间的通信的,目的为了传输图像对象,键盘和鼠标事件,鼠标形状信息,音频播放和录音,控制命令。

2.5、qxl设备

spice服务器支持QXL VDI接口。当libspice被qemu使用时,一个特定的QEMU QXL PCI设备用于提高远程显示的性能和增强guest图像系统的图像能力。QXL设备要求guest QXL驱动完整的功能实现。然而,当没有驱动存在的时候,将使用标准VGA。这个模式也能激活显示从虚拟机启动阶段。设备通过使用命令和光标rings、显示和光标事件以及I/O端口的中断,与驱动程序交互。设备主要职责:

• 初始化和映射设备到物理内存,如ROM,RAM和VRAM
• 映射I/O端口和处理管理的读写,包括区域更新,命令和鼠标通知,IRQ更新,模式设置,驱动重置,日志等。
• Rings - 初始化和管理命令和鼠标Rings,获取命令和来自rings的鼠标命令,等待通知,生产资源ring。
• 使用QXL worker接口与red worker通信,通过red调度器实现和接触,从red worker管道读写消息。
• 为了使能与设备的通信注册QXL接口。接口包括PCI信息和。
• 定义支持qxl模式和开启当前模式的通知,包括VGA模式,所有监视器镜像显示一个单设备(vga clients)
•在VGA模式下处理显示初始化,更新,缩放和刷新

2.6、qxl guest驱动

特定平台的guest驱动是为了与QXL驱动启用和通信。窗口驱动分为一个显示驱动

2.7、spice Agent

spice agent 是一个为了增强用户体验和执行面向guest任务的可选组件。比如,当使用客户端鼠标模式,agent指定guest的鼠标位置和状态。

3、特点

3.1、图像命令

spice支持传输和处理2D图像指令(3D支持即将到来),而不是在许多其他远程桌面解决方案中使用的帧缓冲区更新。QXL设备命令是通用的,与平台无关,因此Windows和X驱动程序都使用它们。

3.2、硬件访问加速

基本的spice客户端渲染使用Cairo,它是跨平台的,不依赖设备的库。Cairo为二维绘图提供矢量图形图元。硬件加速是一种额外的渲染模式,在这种模式下,渲染是由客户端GPU而不是软件使用客户端CPU在硬件上执行的。硬件加速在Linux中使用OpenGL(实验),在Windows中使用GDI。硬件加速优势包括:

• 高性能渲染 - 使用OpenGL,Spice客户端能够比以前更快地渲染。当硬件执行诸如拉伸(视频流使用)之类的繁重软件操作时,其速度要比软件快得多。因此,Spice实现了更流畅的用户体验。
• 减少客户端CPU使用量-客户端享受更多的CPU时间,可以用于音频等其他任务。

与Cairo是一个独立的软件库不同,OpenGL是一个依赖于驱动程序和硬件实现的硬件库。因此,Spice可能会遭受不正确的渲染、严重的CPU使用,或者在最坏的情况下客户端或主机崩溃。此外,尽管OpenGL是一种全球标准,但硬件和驱动程序的实现在供应商之间发生了巨大变化。因此,在不同的GPU上,Spice可能会显示不同的渲染输出,并且可能会检测到不同的性能。此外,有些设备根本不支持OpenGL。

服务器还使用OpenGL进行硬件加速,与Linux客户端共享相同的代码。

3.3、图像压缩

Spice提供了几种图像压缩算法,可以在服务器启动时选择,也可以在运行时动态选择。Quic是Spice专有的图像压缩实用程序,它基于SFALIC算法

根据图像调整的算法是另一种选择。Quic和LZ都是局部算法,即它们独立地编码每个图像。GlobalLZ(GLZ)是Spice的另一个专利,它将LZ与基于历史的全局字典一起使用。GLZ利用图像之间的重复模式来减少流量并节省带宽,这在WAN环境中至关重要。Spice还提供了一种自动模式,用于根据图像进行压缩选择,其中LZ/GLZ和Quic之间的选择是基于图像财产的启发性选择。从概念上讲,LZ/GLZ可以更好地压缩人工图像,而Quic可以更好地对真实图像进行压缩。

3.4、视频压缩

Spice对发送到客户端的图像使用无损压缩,而不是有损压缩,以避免重要显示对象的中断。然而,由于(1)视频流可能是带宽的主要消耗者,因为每个视频帧都是一个独立的图像,并且

(2)它们的内容基本上不具有批判性,因此Spice对这些流采用有损视频压缩:Spice服务器通过识别高速率更新的区域来试探性地识别视频区域。这些区域更新将作为使用易丢失运动JPEG算法(M-JPEG)编码的视频流发送给客户端。这种机制节省了大量流量,提高了Spice的性能,特别是在WAN中。然而,在某些情况下,启发式行为可能导致低质量图像(例如,当将更新的文本区域识别为视频流时)。视频流可在服务器启动时选择,并可在运行时动态更改。

3.5、缓存

Spice实现了客户端图像缓存,以避免到客户端的冗余传输。缓存适用于发送到客户端的任何类型的图像数据,包括位图、调色板和光标。每个图像都来自驱动程序,具有唯一的id和缓存提示。不相同的图像具有不同的id,而相同的图像共享相同的id。缓存提示建议服务器缓存图像。Pixmap缓存在所有显示器之间共享。缓存是按连接定义的,并在服务器和客户端之间进行同步,即,在每个时刻,服务器都确切地知道客户端缓存中有哪些图像。此外,服务器是决定是否应该从缓存中添加或删除项目的服务器。客户端缓存大小由客户端设置,并通过显示通道初始化消息传输到服务器。服务器监视当前的缓存容量,当它缺少空间时,它会删除最近最少使用的缓存项,直到有足够的可用缓存空间。服务器发送带有这些项的无效命令,客户端删除这些项。

3.6、鼠标模式

Spice支持两种鼠标模式,服务器和客户端。模式可以动态改变,并在客户端和服务器之间协商。

• 服务器鼠标 - 使用QEMU ps/2鼠标仿真在来宾机中启用鼠标。当用户在Spice客户端窗口内单击时,客户端鼠标被捕获并设置为不可见。客户端将鼠标移动作为增量坐标发送给服务器。因此,每次移动后,客户端鼠标都会返回到窗口中心。在这种模式下,服务器控制显示器上的鼠标位置,因此客户端和访客之间始终保持同步。然而,在WAN或加载的服务器上可能会有问题,因为鼠标光标可能会有一些延迟或无响应。
• 客户端鼠标 - 客户端鼠标被用作有效的定点设备。它不会被捕获,访客光标设置为不可见。客户端将鼠标移动作为绝对坐标发送给服务器。来宾代理缩放来宾虚拟桌面的坐标并注入适当的光标位置。对于单个监视器,如果VDI主机应用程序注册了绝对指向设备(例如QEMU中的USB平板电脑),即使没有代理,也可以使用客户端鼠标。在这种情况下。Spice服务器缩放坐标。客户端模式适用于WAN或加载的服务器,因为光标具有平滑的移动和响应能力。然而,光标可能会暂时失去同步(位置和形状)。客户端鼠标光标根据访客鼠标光标进行更新。

3.7、多监视器

Spice支持任意数量的监视器,仅受来宾、客户端和服务器限制的限制。启动VM时设置监视器的数量及其RAM大小。Spice支持根据客户端机器设置自动配置来宾监视器分辨率和显示设置。这是通过向来宾代理发出的客户端命令来实现的。

3.8、双通道音频和音视频同步

Spice支持音频播放和录制。使用OPUS算法压缩播放。视频和音频之间的唇同步是通过在QXL设备中对视频帧进行时间戳并将其注入客户端来实现的,与独立的音频同步。

3.9、硬件鼠标

QXL设备支持光标硬件加速。将光标与显示器分离使得能够对光标进行优先级排序以获得更好的响应性。此外,它还减少了网络流量。

3.10、活动迁移

如果对被连接的客户端在服务器之间VM迁移是无缝的。完成连接的状态,包括打开通道和鼠标,是保存在源,存储在目标。

3.11、WAN优化

服务器通过发送一个ping消息来确定延迟和带宽。如果他们超过了阈值,服务器将会告诉guest减少guest端的,当前仅支持windows,减少位深和禁用动画和壁纸,和新增使用无损的jpeg和zlib-glz压缩图像。如果一个图像要求

3.12、拷贝和粘贴

当guest的agent运行时,支持再宿主机和guest之间拷贝和粘贴文本和图片。

猜你喜欢

转载自blog.csdn.net/cai742925624/article/details/129702424