虚拟化外设传输

举报
何其不顾四月天 发表于 2022/01/24 22:36:41 2022/01/24
【摘要】 虚拟化外设传输 在虚拟化云桌面中,关于外设的使用一直有两种基本功能, 设备的透传(passthrough)与重定向(redirection). 透传:设备位于Host,将主机本身拥有的设备直接交给虚拟...

虚拟化外设传输

在虚拟化云桌面中,关于外设的使用一直有两种基本功能, 设备的透传(passthrough)与重定向(redirection).

透传:设备位于Host,将主机本身拥有的设备直接交给虚拟机使用。

重定向:远程虚拟机时,设备位于客户端,通过网络,将设备数据传递给虚拟机(guest).

设备透传(passthrough)

设备透传,主要面向IDV场景。或者说 (Host Device Pass-Through,Direct I/O).

设备透传主要依赖硬件支持,cpu/主板芯片组支持VT-D技术,软件层面/BIOS/操作系统支持IO-MMU。当前主要支持基于PCI总线透传。

当前的主要设备透传,USB设备/网卡透传/显卡透传

主要透传步骤:

#1.BIOS修改 VT-d 使能检测,未开启,则开启
#2.内核启动参数修改: intel_iommu=on
#3.查找设备地址 lspci 根据设备型号获取设备地址 lspci -n -s address 获取设备 iommu group 地址
#4.验证是否支持 iommu (dmesg |grep -i iommu|grep address) 或者 (readlink pci address)
#5.设置 SR_IOV 的 VF 端口数量
#6.解绑设备 echo "address" > /sys/bus/pci/devices/0000\:address/driver/unbind
#7.绑定设备(bind to vfio-pci) (modprobe vfio \ modprobe vfio-pci)
#8.设置启动参数 (qemu -device vfio-pci,host=address,in=net0)(libvirt 设置xml启动参数)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Egg.显卡透传:

#!/bin/bash
#

modprobe vfio
modprobe vfio-pci

dev=0000\:00\:02.0
vendor=`cat /sys/bus/pci/devices/$dev/vendor`
device=`cat /sys/bus/pci/devices/$dev/device`

systemctl restart getty@tty1.service 
#关闭显示窗口,解除进程对显卡的占用
sleep 1
rm -f /etc/apparmor.d/libvirt/libvirt-*
echo "$vendor $device" > /sys/bus/pci/drivers/vfio-pci/new_id
echo "0000:00:02.0" > /sys/bus/pci/devices/0000\:00\:02.0/driver/unbind
echo "0000:00:02.0" > /sys/bus/pci/drivers/vfio-pci/bind
echo "$vendor $device" > /sys/bus/pci/drivers/vfio-pci/remove_id

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

显卡回挂:

#!/bin/bash
#

echo -n "0000:00:02.0" > /sys/bus/pci/devices/0000\:00\:02.0/driver/unbind
echo -n "0000:00:02.0" > /sys/bus/pci/drivers/i915/bind
systemctl restart display-manager #重新启动显示窗口

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

libvirt 设备透传(鼠标为例)

  • API调用
#include <stdio.h>
#include <stdlib.h>
#include <libvirt/libvirt.h>
#include <string.h>

#define MAX_LEN (1024*10)

int main(int argc, char** argv)
{
    int res;
    virConnectPtr conn;
    conn = virConnectOpen("qemu:///system");
    if(conn == NULL){
        printf("failed to open connection to qemu\n");
	return 1;
    }
    printf("success to open connection to qemu\n");
    char* xml = malloc(MAX_LEN);
    memset(xml,0,MAX_LEN);
    FILE* fp = NULL;
    fp = fopen(argv[1],"r");
    if(fp != NULL){
        int len = fread(xml,1,MAX_LEN,fp);
	printf("len = %d\n",len);
    }
    if(fp != NULL){
    	fclose(fp);
    }
    virDomainPtr dom;
    dom = virDomainDefineXML(conn,xml);
    if(!dom){
        printf("domain definition failed\n");
    } 
    char* usbxml = malloc(MAX_LEN);
    memset(usbxml,0,MAX_LEN);
    FILE* usbfp = NULL;
    usbfp = fopen(argv[2],"r");
    if(fp != NULL){
        int len = fread(usbxml,1,MAX_LEN,usbfp);
	printf("len = %d\n",len);
    }
    if(usbfp != NULL){
    	fclose(usbfp);
    }
    res = virDomainAttachDeviceFlags(dom,usbxml,VIR_DOMAIN_AFFECT_CURRENT | VIR_DOMAIN_AFFECT_LIVE);
    printf("virDomainAttachDeviceFlags res = %d\n",res);
    return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • xml文件
<hostdev mode='subsystem' type='usb' managed='yes'>
    <source>
        <vendor id='0x413c'/>
        <product id='0x301a'/>
    </source>
</hostdev>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

设备重定向(redirection)

设备重定向通常在云桌面中使用,大体分为两种端口重定向和设备重定向。通常使用的为端口重定向,在常见的协议的中,例如spice协议。

端口重定向,通常是走总线驱动虚拟化。

设备重定向,设备驱动虚拟化。

端口重定向

以USB端口为例,下述事SPICE协议(端口重定向)的使用方法。

  • libvirt-xml文件
<!- USB2.0>
<controller type='usb' index='0' model='ich9-ehci1'/>
<controller type='usb' index='0' model='ich9-uhci1'>
  <master startport='0'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
  <master startport='2'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
  <master startport='4'/>
</controller>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>

<!- USB3.0>
<controller type='usb' index='0' model='nec-xhci'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • QEMU
#USB2.0
-device ich9-usb-ehci1,id=usb \
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2 \
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4 \
-chardev spicevmc,name=usbredir,id=usbredirchardev1 \
-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \
-chardev spicevmc,name=usbredir,id=usbredirchardev2 \
-device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \
-chardev spicevmc,name=usbredir,id=usbredirchardev3 \
-device usb-redir,chardev=usbredirchardev3,id=usbredirdev3
#USB3.0
-device nec-usb-xhci,id=usb \
-chardev spicevmc,name=usbredir,id=usbredirchardev1 \
-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \
-chardev spicevmc,name=usbredir,id=usbredirchardev2 \
-device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \
-chardev spicevmc,name=usbredir,id=usbredirchardev3 \
-device usb-redir,chardev=usbredirchardev3,id=usbredirdev3

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • remote-viewer
#自动连接
remote-viewer --spice-usbredir-redirect-on-connect="0x03,-1,-1,-1,0|-1,-1,-1,-1,1"
#热拔插时支持USB设备
remote-viewer --spice-usbredir-auto-redirect-filter="0x03,-1,-1,-1,0|-1,-1,-1,-1,1"

  
 
  • 1
  • 2
  • 3
  • 4

设备重定向

常规的重定向方法通常为端口重定向,但是例如一些设备为USB设备,但是不是使用通用USB设备,就需要使用设备重定向,需要针对开发虚拟机内部的虚拟化设备驱动,虚拟设备驱动层,但需要考虑兼容性问题,不具备通用性,成本也相对比较高。

设备重定向在应用层实现,在虚拟机上创建一个虚拟的USB外设驱动,是的应用程序获得数据。

设备重定向做为端口重定向的补充,优势时数据传输效率更高,延时更低。在使用类似于USB摄像头的场景时,就需要使用USB设备重定向或者其他特定的USB设备时,就需要使用设备重定向。

Egg:

设备重定向在实际业务场景中,还有一些其他关键因素需要考虑,设备的黑白名单,设备热拔插,还有设备重定向的需求中数据传输需要怎么做。

以摄像头为例:

#USB设备列表获取
#USB热拔插事件监听(libusb/libusbevent/libudev)
#USB黑白名单过滤
#USB重定向
#--摄像头--
#USB摄像头数据获取(视频流编码<硬编>)
#USB数据传输

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

文章来源: blog.csdn.net,作者:何其不顾四月天,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/u011218356/article/details/122671305

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。