如何使 USB 设备可供 QEMU 来宾使用?

如何使 USB 设备可供 QEMU 来宾使用?

我正在尝试让我的笔记本电脑摄像头可由其上的访客系统访问。

在来宾系统未运行的情况下,我在 中打开它virt-manager,转到“显示虚拟硬件详细信息”→“添加硬件”→“USB 主机设备”。这里我选择我的摄像机(001:002 Chicony Electronics Co., Ltd HD User Facing)并单击“完成”。该过程似乎与KVM 文档中描述

这会导致以下节添加到来宾计算机的 XML 配置中。

<hostdev mode="subsystem" type="usb" managed="yes">
  <source>
    <vendor id="0x04f2"/>
    <product id="0xb6dd"/>
  </source>
  <address type="usb" bus="0" port="6"/>
</hostdev>

根据以下内容,这看起来是正确的红帽关于连接和更新设备的手册virsh

但是,我无法使用它来运行来宾,因为qemu权限被拒绝。

Error starting domain: internal error: qemu unexpectedly closed the monitor: 2022-03-13T05:27:57.240470Z qemu-system-x86_64: -device {"driver":"usb-host","hostdevice":"/dev/bus/usb/001/002","id":"hostdev0","bus":"usb.0","port":"6"}: failed to open /dev/bus/usb/001/002: Permission denied

Traceback (most recent call last):
  File "/gnu/store/r9jxh3pv020qa05pza3jiky2vppn68mx-virt-manager-3.2.0/share/virt-manager/virtManager/asyncjob.py", line 65, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
  File "/gnu/store/r9jxh3pv020qa05pza3jiky2vppn68mx-virt-manager-3.2.0/share/virt-manager/virtManager/asyncjob.py", line 101, in tmpcb
    callback(*args, **kwargs)
  File "/gnu/store/r9jxh3pv020qa05pza3jiky2vppn68mx-virt-manager-3.2.0/share/virt-manager/virtManager/object/libvirtobject.py", line 57, in newfn
    ret = fn(self, *args, **kwargs)
  File "/gnu/store/r9jxh3pv020qa05pza3jiky2vppn68mx-virt-manager-3.2.0/share/virt-manager/virtManager/object/domain.py", line 1329, in startup
    self._backend.create()
  File "/gnu/store/7c16ipd35j0fdl6mrjbg3v9zsn8iivi0-python-libvirt-7.9.0/lib/python3.9/site-packages/libvirt.py", line 1353, in create
    raise libvirtError('virDomainCreate() failed')
libvirt.libvirtError: internal error: qemu unexpectedly closed the monitor: 2022-03-13T05:27:57.240470Z qemu-system-x86_64: -device {"driver":"usb-host","hostdevice":"/dev/bus/usb/001/002","id":"hostdev0","bus":"usb.0","port":"6"}: failed to open /dev/bus/usb/001/002: Permission denied

它尝试访问的设备是正确的:

$ lsusb -s 001:002
Bus 001 Device 002: ID 04f2:b6dd Chicony Electronics Co., Ltd HD User Facing

该设备的所有者为root.看来读访问权限还不够qemu

$ LC_ALL=C ls -l /dev/bus/usb/001/002
crw-rw-r-- 1 root root 189, 1 Mar 13 06:15 /dev/bus/usb/001/002

我的猜测是,该设备的所有者root出于良好的安全原因。同样,virt-manager不会提示我qemuroot.如何安全地管理权限以允许访客访问摄像头?


我最初尝试的另一种方法是使用 GNOME Boxes 在相应的访客设置中启用对相机设备的访问。它尝试使用 SPICE USB 重定向,这类似于SPICE 用户手册中描述,但使用qemu-xhci主机适配器而不是ich9-ehci1.但是,当我尝试翻转相机设备的访客设置中的开关时,它只是通知其重定向失败。以下是我的客机配置中的相关部分,看起来没问题:

    <controller type="usb" index="0" model="qemu-xhci" ports="15">
      <alias name="usb"/>
      <address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
    </controller>
    <redirdev bus="usb" type="spicevmc">
      <alias name="redir0"/>
      <address type="usb" bus="0" port="2"/>
    </redirdev>
    <redirdev bus="usb" type="spicevmc">
      <alias name="redir1"/>
      <address type="usb" bus="0" port="3"/>
    </redirdev>
    <redirdev bus="usb" type="spicevmc">
      <alias name="redir2"/>
      <address type="usb" bus="0" port="4"/>
    </redirdev>
    <redirdev bus="usb" type="spicevmc">
      <alias name="redir3"/>
      <address type="usb" bus="0" port="5"/>
    </redirdev>

那么,如何才能让客人可以使用相机呢?

答案1

我发现将设备添加到/dev/bus/usb/组中kvm允许使用 GNOME 框中的 GUI 开关或virt-manager使其可供虚拟机使用。

总线号和设备号可以通过 来识别lsusb。该设备可通过其在 中的总线编号命名的目录中的编号来获取/dev/bus/usb/。例如,

$ lsusb | grep HD
Bus 001 Device 002: ID 04f2:b6dd Chicony Electronics Co., Ltd HD User Facing
$ sudo chgrp kvm /dev/bus/usb/001/002
$ LC_ALL=C ls -l /dev/bus/usb/001/002
crw-rw-r-- 1 root kvm 189, 1 Apr  2 17:26 /dev/bus/usb/001/002

将设备重新连接到主机或重新启动主机后,此修改不会继续存在。

答案2

上一个Debian 机器spice-client-glib-usb-acl-helper来自 SPICE GTK 用于根据需要或按配置将 USB 设备传递到 VM。它通过 PolicyKit 套件验证 ACL(Linux 访问控制列表)。

helper 由用户以用户权限运行的程序调用,但决定对特权资源的访问,因此需要设置 setuid 才能以提升的权限运行。在 Debian 机器上,在安装过程中设置了 setuid:

$ LC_ALL=C ls -l /usr/libexec/spice-client-glib-usb-acl-helper
-rwsr-xr-x 1 root root 18512 Mar  1  2023 /usr/libexec/spice-client-glib-usb-acl-helper

请注意s权限中 setuid 位的 。


然而,在 Guix 系统上,安装被假定是由非特权用户进行的。因此,安装后还需要进行额外的配置。此外,Guix 商店不能包含 setuid 程序出于安全原因。因此,需要在系统配置文件中声明setuid程序。

下面是一个不优雅的例子,说明了如何添加这些内容来使 SPICE USB 直通在 Guix 系统上工作:

(use-modules …
             (gnu system setuid)
             (gnu packages spice))
(use-service-modules …
             virtualization dbus)

(operating-system …
  (services
   (append (list …
                 (service libvirt-service-type)
                 (service virtlog-service-type)
                 (simple-service 'spice-polkit polkit-service-type (list spice-gtk)))))
  (setuid-programs
    (append (list (setuid-program
                    (program (file-append spice-gtk "/libexec/spice-client-glib-usb-acl-helper"))))
            %setuid-programs)))

请注意扩展策略的行,然后是扩展默认 setuid 程序列表的代码片段。

通过这样的配置,可以使用 GNOME Box 中的接口中的开关将 USB 设备传递到客户机。

相关内容