在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-3。3. 编辑虚拟机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端口。