在KVM中将USB设备绑定到虚拟机,device地址会变化的时候也可以使用该办法

1. 检查主机上的USB设备。在主机上运行`lsusb`命令,查看连接的USB设备及其总线地址,例如:
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub 
Bus 001 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

 2. 找到要绑定的USB设备对应的bus和device地址。例如Logitech鼠标接收器的地址为1-33. 编辑虚拟机XML配置文件,添加USB设备和filter。使用virsh edit 虚拟机名称 或直接编辑/etc/libvirt/qemu/虚拟机名称.xml文件。在<devices>节添加:

 

<hostdev mode='subsystem' type='usb'>
  <source>
    <vendor id='0x046d'/>   <!-- 测得的vendor id --> 
    <product id='0xc52b'/> <!-- 测得的product id -->
  </source>
  <address type='usb' bus='1' device='3'/>  <!-- bus和device地址 --> 
</hostdev>
以及一个USB filter:
xml 
<filterref filter='usb-1-3'/>
<filter id='usb-1-3' usbFormFactor='other'> 
  <vendor id='0x046d'/>
  <product id='0xc52b'/>  
</filter>

4. 重启虚拟机,USB设备将自动绑定并在虚拟机中 recognizable。

5. (可选)将USB设备永久绑定到虚拟机。编辑/etc/udev/rules.d/10-libvirt-usb.rules文件,添加:

SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c52b", MODE="0660", GROUP="kvm", SYMLINK+="usb1_3" 
重启主机,USB设备将被默认分配给KVM用户组并永久绑定到虚拟机中。

ID会变化的话如何绑定呢

USB设备的bus和device地址会在重新插拔时发生变化,此时硬编码在XML配置文件中的地址将失效。为解决此问题,我们可以采用USB设备的vendor id和 product id来唯一标识设备,而不是依靠bus和device地址。步骤如下:

1. 同样先使用lsusb命令查找到USB设备的vendor id和product id,例如:
Bus 001 Device 016: ID 0bda:0158 Realtek Semiconductor Corp. Mass Storage Device
该设备的vendor id为0bda,product id为0158。

2. 编辑虚拟机的XML配置文件,添加带有vendor/product id的USB设备:

<hostdev mode='subsystem' type='usb'>
  <source>
    <vendor id='0x0bda'/>  
    <product id='0x0158'/>  
  </source>
</hostdev> 

3. 同时添加USB filter,使该USB设备永久绑定到虚拟机:
xml

<filterref filter='usb-0bda-0158'/>
<filter id='usb-0bda-0158' usbFormFactor='other'>
<vendor id='0x0bda'/>
<product id='0x0158'/>
</filter>

 

4. (可选)在udev规则中添加该USB设备的规则,将其永久分配给KVM libvirt用户组:

SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="0158", MODE="0660", GROUP="kvm", SYMLINK+="usb0bda0158"

 


5. 重启虚拟机和主机(如果添加了udev规则),USB设备将被自动分配并绑定到虚拟机中。此方法不依赖USB设备的bus和device地址,所以即使地址在重新插拔时发生变化,USB设备也会被持续绑定到指定的虚拟机中。libvirt通过扫描USB设备的厂商ID和产品ID来识别和匹配设备。

对于这种同一设备有多个实例的情况,且设备ID(vendor id和product id)相同,将不同设备实例绑定到不同虚拟机,可以采取以下方法:

1. 通过USB端口号或外部端口来区分不同设备。每一个物理USB端口都对应一个bus地址,我们可以在libvirt XML配置文件中指定不同的`<address type='usb' bus='xxx' port='yyy'/>`来绑定设备。例如,添加:
xml

<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x0bda'/>
<product id='0x0158'/>
</source>
<address type='usb' bus='1' port='1'/>
</hostdev>
<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x0bda'/>
<product id='0x0158'/>
</source>
<address type='usb' bus='1' port='3'/>
</hostdev>

这会将两个同型号USB设备分别绑定到bus 1,port 1和bus 1,port 3的地址上。

2. 通过udev规则为不同端口的设备创建不同的链接,在libvirt中通过链接名绑定设备。在`/etc/udev/rules.d/` 目录下添加两个规则,内容如下:

SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="0158", ATTRS{busnum}=="1", ATTRS{portnum}=="1", SYMLINK+="usb_port1"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="0158", ATTRS{busnum}=="1", ATTRS{portnum}=="3", SYMLINK+="usb_port3"

然后在libvirt XML中使用链接名绑定设备:
xml

<hostdev mode='subsystem' type='usb' managed='no'>
<source>
<devpath link="/path/to/usb_port1"/>
</source>
</hostdev>
<hostdev mode='subsystem' type='usb' managed='no'>
<source>
<devpath link="/path/to/usb_port3"/>
</source>
</hostdev>

这两个方法都可以利用USB端口区分同型号设备,实现将不同设备实例绑定到不同虚拟机的目的。如果您对上述内容还有不理解的地方,欢迎在回复中提出。我们将提供进一步的说明和案例帮助理解。作为重要的外部设备接口,USB设备配置一直是我们教程的重点内容。通过适当管理USB设备,可以实现将部分或全部USB设备 "划分" 给不同虚拟环境使用,这在某些用例下十分必要。希望本片内容能对您有所启发,达到管理USB设备实例的目的。

 

USB端口的编号是由USB主控制器根据其物理布局决定的。我们可以通过几个方式来确定特定USB设备所连接的端口号:1. 查看dmesg日志。当USB设备插拔时,dmesg日志会输出对应设备的连接信息,其中包括端口号。例如:

[ 598.873394] usb 1-1: new high-speed USB device number 5 using xhci_hcd
[ 598.996773] usb 1-1: New USB device found, idVendor=0bda, idProduct=0158
[ 598.996779] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 598.996784] usb 1-1: Product: USB Storage
[ 598.996789] usb 1-1: Manufacturer: Realtek
[ 598.996794] usb 1-1: SerialNumber: 0123456789AB

这里`usb 1-1`表示该USB设备连接到主控制器1,端口1。

2. 查看`lsusb -t`输出。`lsusb -t`会显示USB设备树状结构,同一hub下的不同端口对应同一层次的不同设备。例如:

/: Bus 02.Port 1: Dev 1, class="root_hub", Driver=xhci_hcd/4p, 5000M
|__ Port 1: Dev 2, If 0, class="Mass" Storage, Driver=usb-storage, 5000M
/: Bus 01.Port 1: Dev 1, class="root_hub", Driver=xhci_hcd/4p, 480M
|__ Port 1: Dev 2, If 0, class="Mass" Storage, Driver=usb-storage, 5000M
|__ Port 3: Dev 3, If 0, class="Mass" Storage, Driver=usb-storage, 5000M

这里Bus 01下有两个Mass Storage设备,分别在Port 1和Port 3,所以可以区分开来。

3. 物理检查USB端口。如果主机的USB端口有清晰的物理编号标注,我们也可以通过直接检查来确定设备对应的USB端口号。

4. 试验法确定。如果无法通过上述方法明确区分,我们也可以通过 unplug/replug 不同 USB 端口来辨识设备变化,以此确定端口号。

通过以上几种方式,大多数情况下可以准确获取USB设备所处端口的编号。如果您的主机UEFI设置开启了"XHCI手动调度"选项,端口编号可能会更加混乱,这需要您在启动时进入UEFI手动设置USB端口。

 

posted @ 2023-06-16 17:22  Suixin随心  阅读(515)  评论(3编辑  收藏  举报