我正在尝试让我的笔记本电脑摄像头可由其上的访客系统访问。
在来宾系统未运行的情况下,我在 中打开它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
不会提示我qemu
以root
.如何安全地管理权限以允许访客访问摄像头?
我最初尝试的另一种方法是使用 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 设备传递到客户机。