外观
USB 与串口直通
给虚拟机接一个 Zigbee/Z-Wave 网关、许可证加密狗,或者一根管理 UPS 用的串口线,不需要 IOMMU 和 vfio 这一整套 PCI 直通的机制。QEMU 自带的 USB/串口直通门槛低得多,做完这篇就能用。
为什么需要它
USB 直通走的是 QEMU 自身的 usb-host 机制,不依赖 IOMMU 分组,配置和排查都比 PCI 直通简单很多。常见场景:Home Assistant 虚拟机需要一个 Zigbee/Z-Wave USB 网关、某些软件的 USB 许可证狗、或者用一根 USB 转串口线管理 UPS。
开始之前
不需要完成开启 IOMMU那一篇——USB 直通和 PCI 直通是两条独立的路径。
带着直通设备不能在线迁移
和 PCI 直通一样,配置了 USB 主机直通的虚拟机绑定在当前宿主机上,不能在线迁移到集群里的其他节点。这是功能限制,不影响数据安全。
USB 直通
1. 找到设备
sh
# 宿主机 shell,先看设备的厂商:产品 ID
lsusb输出类似:
text
Bus 003 Device 004: ID 0451:16a8 Texas Instruments CC2531 ...0451:16a8 就是厂商 ID 和产品 ID。如果有两个型号完全相同的设备,ID 没法区分是哪一个,改看物理端口路径:
sh
# 宿主机 shell
lsusb -t从输出的树状结构里拼出 总线-端口 路径,比如挂在总线 3、根口 1 下面的设备是 3-1;如果设备接在一个 Hub 后面,路径要把经过的每一级端口用点连起来,比如 1-1.3。
2. 加进虚拟机
Web UI:虚拟机 → Hardware → Add → USB Device,二选一:
| 方式 | 什么时候用 |
|---|---|
| Use USB Vendor/Device ID | 只有一个这个型号的设备,随便插哪个 USB 口都行 |
| Use USB Port | 有多个相同型号的设备需要分给不同虚拟机,或者希望固定物理插口 |
对应的配置大致是:
text
usb0: host=0451:16a8或者:
text
usb0: host=3-13. 生效方式
sh
# 宿主机 shell 或 Web UI 里点 Shutdown 再 Start
qm stop <vmid>
qm start <vmid>重启虚拟机(reboot)不够,要完全停止再启动
在客户机内部执行 reboot 不会重新扫描 USB 直通配置,必须在 PVE 侧完全停止(Stop)后再启动(Start)一次,新加的 USB 设备才会生效。
设备在虚拟机启动时不存在也没关系,虚拟机照常开机,等设备接上之后会被直通进去。
串口直通
场景例如:用一根 USB 转串口线连着 UPS,需要虚拟机里的 NUT 之类软件直接读取。
1. 确认设备节点
sh
# 宿主机 shell
ls -l /dev/serial/by-id/优先用 /dev/serial/by-id/ 下的持久化路径,而不是 /dev/ttyUSB0 这种编号——重新插拔或者宿主机重启后,编号可能会变,但 by-id 路径不会变。
2. 加进虚拟机
Web UI:虚拟机 → Hardware → Add → Serial Port,输入设备路径(例如 /dev/serial/by-id/usb-xxx)。虚拟机内部会表现为一个标准串口(Linux 下通常是 /dev/ttyS0,Windows 下是 COMx)。
检查结果
- USB:客户机内
lsusb(Linux)或设备管理器(Windows)能看到对应设备,驱动能正常加载。 - 串口:客户机内对读写这个端口的软件(比如 UPS 监控工具)能正常拿到数据,或者用
stty/终端工具能打开端口不报错。
常见问题
加了 USB 设备重启虚拟机,设备不见了。 用的是客户机内部 reboot,需要在 PVE 侧完全 Stop 再 Start,见上文。
有两个一模一样的 USB 设备,接进了另一台虚拟机。 用了 Vendor/Device ID 方式,两个设备 ID 相同没法区分,改用 USB Port 方式按物理插口分配。
想让同一个 USB 设备在集群里换节点后还能稳定引用。 见资源映射,可以按节点分别配置对应的物理地址。
热插拔后设备没有出现在虚拟机里。 确认设备先在宿主机 lsusb 里能看到;仍不出现的话按上文完全 Stop 再 Start 一次。