1. 引言
随着云计算技术和虚拟化技术的不断发展,桌面云作为云计算的典型应用之一,可以通过瘦客户端或者其他任何与网络相连的设备来跨平台访问应用程序以及整个客户桌面,具有易于管理、安全性高、应用环保及成本低等特点,被广泛应用在桌面集中管理、信息安全、远程办公等各种应用场景中。桌面云因其具有“桌面统一、资源共享”的特点,能为高校教学和办公提供高效灵活的环境。该技术的应用为师生提供了个性化的桌面服务,使机房和实验室的教学安排更加灵活,促进了虚拟化实验资源的共享,极大地提高了IT资源管理的水平和效率 [1] [2] [3]。
但与传统物理PC机桌面相比,桌面云对USB设备的支持尚不成熟。桌面云在使用中暴露出高速USB设备读取性能受限方面的问题。USB外接设备凭借数据传输速率快、携带便利、即插即用等显著优势,已经成为当前使用最广泛的计算机外设 [4] [5]。因此,在桌面云实际应用中,如果不能有效解决USB重定向通道传输性能的问题,终端用户也就不会热衷于桌面虚拟化技术。目前,在桌面云环境下实现对USB设备的支持,一般来说有两种方式,一种是基于USB总线的虚拟化重定向,又称为USB端口重定向,通过替换USB总线驱动实现,比如文献 [6] [7] 提到的方法;第二种是USB设备驱动的重定向,又称为设备重定向,即替换掉USB设备驱动。与USB端口重定向相比,USB设备重定向技术的整个工作流程中少了很多的代理环节,所以在整个数据传输过程,无论是数据的传输效率,还是网络延时都会比USB端口重定向技术更优,也更适合数据流量较大,同时对延时也比较敏感的外设 [8]。本文所研究的基于SPICE协议的USB重定向正是基于后者实现。虽然基于SPICE协议的桌面虚拟化技术发展十分迅速,国内外各大公司的产品也相继问世,但是,桌面云在USB识别方面还是存在着一些问题 [9],如识别速度偏慢等。由于虚拟化环境下虚拟机的客户系统访问主机的USB设备的I/O性能存在问题,文献 [10] 选择QEMU [11] 作为开发的基础,对直接硬件访问进行尝试,通过改进QEMU的体系结构,借助USB设备访问接口库,实现了虚拟机中客户系统直接访问真实USB接口设备,来提高虚拟机I/O性能。文献 [5] 为了解决USB重定向过程中高速USB设备读取性能受限等问题,提出了USB映射与网络映射相结合的融合方法,对特定类型、高速的USB设备进行自动识别并采用响应机制,提升了USB设备的读写性能和网络效率。但是,此方案的缺点在于需要改变USB设备的使用习惯。USB设备重定向实质就是通过网络将位于终端机上的物理USB设备和位于虚拟桌面服务器端的虚拟USB设备之间建立连接,并将对于USB设备的URB请求及应答进行重定向 [12]。文献 [12] 中指出通常以SPICE协议为基础的USB重定向技术大多都是运用了USBRedir和LibUSB等技术,依靠SPICE的服务端和客户端的Spice-GTK [13] 来实现。这些原生的实现方式,并没有对USB重定向数据传输性能问题做优化处理,在极端情况下,会影响用户使用体验,甚至造成无法正常使用的情况。
因此,为了让用户在使用桌面云时,能够获得接近传统物理PC机使用USB存储设备的体验,本文针对USB重定向识别过程数据传输的性能,结合实际应用场景,以SPICE协议为基础,通过优化USB重定向识别过程整体性能,来有效提高USB存储设备重定向识别速度,进而提高用户使用桌面云的整体体验。
2. SPICE架构
桌面云运用虚拟化技术,把计算资源进行池化,并通过网络为多形态的用户终端提供资源池中的应用程序或者传统PC桌面 [4]。桌面虚拟化技术的核心是虚拟桌面传输协议,在保证和改善用户交互体验质量时发挥着重要作用 [14]。SPICE [15] 是一个开源的虚拟桌面协议,提供了动态自适应、高性能的虚拟桌面服务,实现了远端主机和设备(键盘、鼠标等)的接入。SPICE主要由SPICE协议 [16]、SPICE服务端、SPICE客户端以及SPICE相关的QXL设备组成,在虚拟机内部还有QXL驱动。如图1所示,SPICE使用QEMU作为虚拟化层,QEMU作为中间件与KVM和SPICE进行交互。虚拟机运行于QEMU进程里,SPICE服务端作为一个基于libspice写的静态库被QEMU编译进去。SPICE协议通过各种不同的通道实现客户端和服务端之间的通信,利用不同的通道传输不同类型的数据,每一种通道用来专门负责一种类型的数据传输与通信,每个通道中的内容都可以通过相应的图形命令数据流或代理命令数据流传输 [17]。SPICE服务端以动态连接库的形式与KVM虚拟机整合,通过SPICE协议与客户端进行通信。SPICE协议架构如图1所示。
![](//html.hanspub.org/file/10-1541793x9_hanspub.png)
Figure 1. Structure of SPICE protocol
图1. SPICE协议架构
SPICE协议定义了以下几种通道,每个通道针对一个远端设备,通道支持SPICE自定义:
1) 主连接通道(main):主要的SPICE会话通道;
2) 显示通道(display):处理图形命令,接收远程显示更新;
3) 输入通道(inputs):发送鼠标和键盘事件;
4) 光标通道(cursor):接收指针形状和位置;
5) 播放通道(playback):从服务器接收音频流;
6) 录音通道(record):在客户端捕获音频;
7) USB通道:将USB设备重定向到Guest操作系统中。
3. 基于SPICE协议的USB重定向识别原理和性能分析
基于SPICE协议的USB重定向是将客户端本地的USB设备映射到QEMU虚拟机中的过程,这样虚拟机在USB驱动程序的配合下,就可以像访问本地USB设备一样,访问客户端的USB设备。本地客户端将USB外设通过网络方式,映射到服务端的虚拟化层;服务端虚拟机管理程序QEMU通过创建虚拟的USB重定向字符设备,供虚拟机中的驱动层来访问。
当客户端本地的SPICE客户端连接到服务端QEMU虚拟机时,其会同spice-server建立通道连接,如果客户端有USB设备需重定向,则会同服务端spice-server建立USBRedir通道来收发数据,服务端QEMU会模拟出Redirect字符设备,同spice-server通道关联,这样从通道接收到的数据就会提交给Redirect字符设备,然后由控制器提交到虚拟缓冲区供虚拟机读取;如果Redirect字符设备有数据需要发送,则写入到对应的spice-server通道,由USBRedir通道来负责将数据发送到客户端。基于SPICE协议的USB设备重定向架构图如图2所示。
![](//html.hanspub.org/file/10-1541793x10_hanspub.png)
Figure 2. USB redirection architecture based on SPICE protocol
图2. 基于SPICE协议的USB重定向架构图
从图2可以看出:
1) 客户端USB设备同内核态的控制器进行交互,二者之间通过端点endpoint建立逻辑上对应的管道pipe来通信;
2) 内核态经过USB核心处理负责进行驱动的配置和读取操作,向上提供了接口给USB Fs;
3) 用户态则通过LibUSB的API来配置和读写操作;
4) Spice-Gtk则直接调用LibUSB相关接口来初始化和注册对应的事件处理函数,然后通过USBRedir模块来读取数据,并经过协议封装后,通过SPICE的vmc通道发送给服务端;
5) 服务端spice-server同spice-vmc模块进行耦合,从spice-server接收到的数据,通过qemu-char字符设备接口写入到虚拟的字符设备Redirect中,然后经过USBRedir部分的协议解析后,提交到虚拟缓冲区,供USB控制器处理;
6) USB控制器获取的数据则写入到Redirect字符设备中,然后经过USBRedir协议的处理后,调用spice-vmc的接口,最终通过spice-server的通道发送给客户端。
在传统PC上使用USB时,USB设备直接连接PC USB控制器,识别速度快,用户体验好,USB设备的数据传输不会造成其它影响,而对于基于SPICE协议的桌面虚拟化应用来说,USB设备是通过客户端和主机的网络重定向到虚拟机中的,由于各种延迟的存在导致USB识别速度普遍偏慢,极大的影响用户使用体验。本文从USB重定向识别过程出发,分析基于SPICE协议的USB重定向识别原理和传输数据的性能,进而提出相应的优化方案。
3.1. 基于SPICE协议的USB重定向识别原理
USB识别过程也就是重定向开始的过程,当客户端检测到有USB设备插上或者有USB已经存在,且该USB设备允许重定向,则首先会通过LibUSB的接口打开该设备,获取到设备句柄,然后调用USBRedir提供的usbredirhost_set_device接口来走重定向逻辑,此时,USB重定向已经开始。
usbredirhost_set_device会根据设备句柄获取到设备结构,然后会调用LibUSB的接口来获取设备描述符和配置描述符,再调用LibUSB的libusb_set_auto_detach_kernel_driver或libusb_detach_kernel_driver接口将其从内核态detach,最后调用libusb_claim_interface对设备进行宣告,至此,/dev/下对应的设备会消失,彻底由LibUSB来接管。
接下来会对USBRedir进行适当的配置,包括端点信息、最大包长等。
最后会复位设备,获取设备的速率模式,再将设备的接口描述符有关信息、端点有关信息写入到队列,SPICE中的USB重定向通道会负责对该队列中的数据发送到服务端。
至此,服务端的虚拟机中设备管理器中已经可以看到相应的USB设备了。
后续过程,磁盘控制器会进行磁盘的读写,才能看到对应的USB磁盘。
3.2. 基于SPICE协议的USB重定向识别过程数据传输性能分析
对于USB设备,根据其设备类型的不同,主要有SCSI/HID/UVC等几种协议。SCSI协议主要用于USB存储设备(U盘、USB硬盘、USB读卡器等),HID作为人机接口设备采用的协议(键盘、鼠标等),UVC主要用于USB视频设备(Camera、DV等)。
在虚拟机中通过Bus Hound USB抓包工具分析确实有大量的数据会通过Data In发送到主机,为了确定其数据内容和采用的协议,这里通过Wireshark来抓包,并且对USB协议进行分析,可以知道,大量的数据传输是主机需要通过SCSI command命令来读取U盘对应的Flash扇区导致,即主机需要知道U盘的扇区相关的信息,才能显示该磁盘。可以参考文档《SCSI Commands Reference Manual.pdf》。
通过Wireshark抓包,对request请求报文(如图3所示)和respond响应报文(如图4所示)的协议分析可以验证,此过程确实采用SCSI的CDB Read命令来读取了LUN上的大量的设备块信息,且数据量较大。
为了方便对整个数据传输过程中的理解,这里给出了客户端USB大容量存储设备数据流图,如图5所示:
![](//html.hanspub.org/file/10-1541793x13_hanspub.png)
Figure 5. USB mass storage data flow
图5. USB大容量存储设备数据流图
3.2.1. 协议层面分析
从抓包分析我们知道,USB重定向U盘识别过程进行了大量扇区数据的读取操作,通过抓包可以看出其协议封装,对USB Mass Storage的读写是按如下协议进行的:
![](//html.hanspub.org/file/10-1541793x14_hanspub.png)
Figure 6. USB Mass Storage protocol package
图6. USB大容量存储协议封装
从图6中可以看出,首先是磁盘SCSI系统层读取,然后经过USB Mass Storage层的封装,再经过USB URB的封装,这三层为常规USB设备读取过程协议。
通过对SPICE重定向通道得到其协议封装,这里通过图示来画出网络数据包的协议封装:
![](//html.hanspub.org/file/10-1541793x15_hanspub.png)
Figure 7. USB redirection channel protocol package
图7. USB重定向通道协议封装
从图7中可以看出,USB数据是封装到USBRedir协议中进行传输的。经过USBRedir层的封装后,就可以经过SPICE封装通过SPICE通道发送,SPICE协议是承载于TCP层之上的。
由此可知,在经过QEMU模拟的控制器后,先将磁盘读写和USBMS以及USB URB解析后转换成USBRedir协议,才经过SPICE协议进行发送。
3.2.2. 虚拟机内部磁盘读取分析
在虚拟机内部,通过微软提供的Diskmon磁盘读写监控工具,监控USB识别中的磁盘扇区读写,可以看出每次IO读取的数据量大小。
对比Windows7和Windows10发现,Windows10每次IO读取的数据量最大可达1 M字节大小;而Windows7每次IO读取的数据量在4 K字节大小。
因此,磁盘读写IO是影响U盘识别速度的一大原因。
3.2.3. 虚拟机内部抓包分析
在虚拟机内部,通过Wireshark携带的USBPcap工具来抓取USB端口的数据可以知道,进行了大量的数据读取操作。
对比Windows7和Windows10,发现,Windows10每次读取的数据包长度为64 K;而Windows7每次读取的数据包长度为4 K。
根据协议封装,Windows10在IO层面将DISK.SYS驱动的1次IO请求,由USBSTOR.SYS驱动拆分为16次对USB总线的请求,16次USB总线请求的响应则由DISK.SYS驱动合并成了1次IO数据响应;而Windows7则没有进行IO的合并过程,DISK.SYS驱动1次IO请求就是4 K,USBSTOR.SYS驱动也是按4 K请求的。
3.2.4. 从USB控制器角度分析
由于采用USB2.0和USB3.0的控制器对IO数据长度和USB数据包的长度没有影响。因此说明,控制器层面不会进行数据包的合并操作。
目前推断,这块应该是USB3.0控制器的特性。通过跟踪QEMU相关代码,确认Windows7采用3.0控制器,内部数据包长度也是4 K。但是Windows7采用3.0控制器,识别时间要接近于Windows10。但是随着U盘容量越大,Windows7采用3.0的控制器,也没有Windows10的效果,说明Windows10对磁盘IO进行过优化。
根据以上的分析可以知道,影响USB重定向识别速度的因素,主要包括磁盘读写IO和USB控制器等。此外,如果在网络堵塞情况下,识别过程传输的大量未经压缩的数据也是导致识别速度偏慢的原因之一。
4. 基于SPICE协议的USB重定向识别优化
针对第3节分析出的影响当前USB重定向识别速度的各种因素,本节中将分别对这些问题提出解决方案。
从USB识别原理出发,通过分析调试并进行实际试验发现从以下3个方面进行优化对识别速度会有比较大的提升,分别为:
1) 虚拟机使用的USB控制器从传统的2.0控制器换成高速的3.0控制器;
2) 对重定向网络中传输的数据进行压缩,降低网络传输过程中带来的延迟,尤其在网络质量差时,效果比较好;
3) 虚拟机内部通过编写磁盘过滤驱动对USB读写的块大小进行优化。
4.1. 采用3.0控制器
对于采用3.0控制器在不限速条件下,识别时间明显要短很多,因此,如果采用3.0的控制器,在该条件下,对USB识别速度有较大提升。
xHCI (eXtensible Host Controller Interface),是流行的USB3.0的接口标准,它在速度、节能、虚拟化等方面都比USB2.0的控制器中有了较大的提高。xHCI支持所有种类速度的USB设备(USB 3.0 SuperSpeed, USB 2.0 Low-, Full-, and High-speed, USB 1.1 Low- and Full-speed)。
Libvirt启动xHCI配置如图8所示:
![](//html.hanspub.org/file/10-1541793x16_hanspub.png)
Figure 8. Libvirt starts the xHCI configuration
图8. Libvirt启动xHCI配置
4.2. 数据压缩
由于主机会向USB设备读取大量的数据,为此,通过修改SPICE相关代码对数据进行压缩,以减少传输量,这里采用LZ4压缩算法来实现。LZ4是一种无损压缩算法,最新版本的LZ4压缩速度为每核心500 MB/s以上,它拥有速度极快的解码器,同时CPU占用较低,总的来说,LZ4压缩算法压缩效率较高 [18]。
![](//html.hanspub.org/file/10-1541793x17_hanspub.png)
Figure 9. Compression algorithm comparison diagram
图9. 压缩算法对比图
对于文件传输这样的场景,不能容忍差错的出现,只能采用无损压缩算法,而从图9压缩算法的对比中,可以看出:LZ4算法速度极快,提供很高的压缩和解压速度,其压缩比也最高,但其是以占用内存为代价的。目前较新版本的SPICE采用的LZ4压缩算法,经过测试,其压缩后,网络带宽会有所减少,平均情况下,可达50%的带宽减少。如果在带宽受限条件下,对识别速率有一定的提升作用。
针对USB文件传输,采用下述流程进行有选择性的数据处理流程:
1) 监控USB Redirect模块数据传输接口,捕获Bulk类型数据;
2) 尝试采用LZ4 default的压缩接口对源数据进行压缩;
3) 压缩失败或者压缩后数据大于源数据空间,直接把源数据放进传输队列;
4) 压缩成功数据,修改传输数据头为LZ4的压缩类型,同时把压缩后数据放进传输队列;
5) 服务端处理USB数据,发现数据为LZ4的压缩类型,则进行LZ4解压,还原数据。
详细流程如图10所示:
![](//html.hanspub.org/file/10-1541793x18_hanspub.png)
Figure 10. Data compression process flow chart
图10. 数据压缩处理流程图
4.3. IO优化
通过编写磁盘过滤驱动对USB存储设备读IO进行合并来优化USB存储设备识别过程中的读写速度。优化的核心点主要包含2个方面:1) 在添加设备例程中识别当前设备是否是USB设备,防止优化对非USB存储设备造成影响;2) 在读写例程中,识别出读数据操作,对小块数据读写进行预读和缓存。下面分别对上述两个方面进行说明。
4.3.1. 识别USB设备优化
识别USB设备优化的具体过程如下:判断当前设备的总线是否是USB总线,如果是则表示是USB设备,则创建过滤设备,否则直接跳过。
具体流程如图11所示。
4.3.2. 读数据优化
读数据优化的详细过程如下:判断当前发起的功能码是否为读操作,如果是读操作则判断当前读取的数据块是否为小块(小于32扇区的块),如果数据块为小块,则进行预读缓存处理(预读128个扇区),否则直接进行下发处理;判断当前发起的功能码是否为写操作,如果是写操作则判断写入的数据是否跟我们缓存的数据有重叠,如果有重叠则需进行更新并下发处理,否则直接下发处理。
具体流程如图12所示。
![](//html.hanspub.org/file/10-1541793x19_hanspub.png)
Figure 11. USB identification filter flow chart
图11. USB识别过滤流程图
![](//html.hanspub.org/file/10-1541793x20_hanspub.png)
Figure 12. USB read data optimization flow chart
图12. USB读数据优化流程图
5. 实验结果与分析
本实验通过收集实际数据来验证我们采取的优化方案能否达到预期效果,收集的数据为优化前后USB存储设备在进行重定向过程中Windows7系统正常识别出USB存储设备的时间,实验分别测试了2种不同网络场景下的实验数据,即网络不限速(内网环境)与限速30 K/s (外网环境)。
5.1. 测试实验环境设置
1) 一台安装有Fedora系统的Linux客户端,其硬件为Intel(R) Celeron(R) CPU 1037U @ 1.80 GHz,双核4 G DDR内存,系统安装VDI客户端软件;
2) 3种容量的USB存储设备:一块普通1 T移动硬盘(3.0接口),一个普通2.0接口16 G U盘,一个3.0接口32 G U盘,磁盘格式均为NTFS;
3) 一台安装有VDI服务端软件的服务器,其硬件为Intel(R) Core(TM) i5-6400 CPU @ 2.70 GHz,四核16G DDR内存;
4) 在服务器上建立Windows7 64位系统的KVM虚拟机;
5) 配置好客户端和服务端的网络,保证千兆网络连通;
6) 网络设置,不限速:usb_transfer_limit speed_send = 0,speed_recv = 0;限速:usb_transfer_limit speed_send = 30 K/s,speed_recv = 30 K/s。
5.2. 实验过程
1) 采用现有方案收集实验数据
步骤一:KVM虚拟机USB控制器设置为2.0;
步骤二:对不同的USB存储设备,在不限速与限速2种网络环境下进行重定向并收集重定向识别时间数据。
2) 采用优化方案收集实验数据
步骤一:KVM虚拟机USB控制器设置为3.0,网络传输的数据启用压缩,虚拟机内安装我们的磁盘过滤驱动;
步骤二:对不同的USB存储设备,在不限速与限速2种网络环境下进行重定向并收集重定向识别时间数据。
5.3. 实验数据与分析
![](Images/Table_Tmp.jpg)
Table 1. Performance comparison before and after speed optimization for USB redirection recognition (no speed limit)
表1. USB重定向识别速度优化前后性能对比(不限速)
![](Images/Table_Tmp.jpg)
Table 2. Performance comparison before and after speed optimization for USB redirection recognition (speed limit)
表2. USB重定向识别速度优化前后性能对比(限速)
从表1实验数据分析可知,在网络不限速的条件下,不同的USB存储设备在虚拟机采用WINDOWS 7 64位系统时,重定向识别的时间在优化后有了较大的降幅,性能提升效果明显;由表2实验数据可以看出,由于网络环境受到限制,USB存储设备重定向识别的速度整体偏慢,但是通过优化也获得了一定程度的提升。
从实验数据分析可知,通过方案的优化整体上能有效缩短USB设备识别时间,提升了用户使用体验,达到了预期效果。
6. 结束语
SPICE协议作为开源的桌面传输协议,在桌面虚拟化解决方案中应用较为广泛,有着较好的市场前景。本文针对桌面云技术中,基于SPICE协议的USB重定向数据传输性能受限的问题,提出了优化USB重定向识别速度的解决方案,对USB重定向识别过程的传输数据,从网络协议层面、虚拟机内部磁盘读取和抓包、USB控制器等方面进行分析,找准了USB重定向识别速度慢的原因。本文所述方案分别从USB控制器、数据压缩、磁盘读写IO三个方面来进行优化,最终,有效减少了USB存储设备识别的等待时间,提升了桌面云系统的可用性和用户体验。
基金项目
本项目受云南省教育厅科学研究基金项目(2018JS035)资助。