在 Arch Linux 上搞定了 GPU 直通(VFIO)后,很多人的最后一步是配置 Looking Glass 从而在 Linux 宿主机上无缝低延迟玩 Windows 虚拟机游戏。
然而,Looking Glass 极度依赖**共享内存(shm)**和 UNIX Domain Socket(用于 Spice 输入和音频)。由于 Arch Linux 的 libvirt 和 systemd 安全沙盒机制非常激进,90% 的启动失败(例如 Permission denied、Failed to map memory)都和权限或 Socket 路径设错有关。
这里梳理出在 Arch Linux 下配置 Looking Glass 必须要解决的权限和 Socket 设定细节,避免反复折腾。
一、 /dev/shm 共享内存的权限持久化
Looking Glass 客户端(宿主机运行)和 Windows 虚拟机(通过 QEMU ivshmem 驱动)是通过 /dev/shm/looking-glass 这个内存文件进行帧传输的。
每次重启宿主机,/dev/shm 里的内容都会丢失。必须通过 systemd-tmpfiles 在开机时自动创建该文件并分配合适的权限。
1. 确定所需内存大小
根据你的虚拟机分辨率计算所需内存,公式为:宽 * 高 * 4 * 2,然后向上取整到最接近的 2 的幂。
- 1080p:1920 * 1080 * 8 ≈ 16.5 MB → 分配 32MB
- 2K (1440p):2560 * 1440 * 8 ≈ 29.4 MB → 分配 64MB
- 4K:3840 * 2160 * 8 ≈ 66.3 MB → 分配 128MB(或 256MB 以防万一)
2. 配置 systemd-tmpfiles
新建配置文件 /etc/tmpfiles.d/looking-glass.conf:
# 路径 类型 权限 属主 属组 生命周期 额外参数
f /dev/shm/looking-glass 0660 your_user kvm -
- 将
your_user替换为你登录 Arch Linux 的日常用户名。 - 属组指定为
kvm(Arch 下 QEMU 默认运行在此组内)。 - 权限
0660确保了你的日常用户和 QEMU 都有读写权限。
执行以下命令立即使其生效,而无需重启:
sudo systemctl restart systemd-tmpfiles-setup.service
二、 避开 Systemd 的 /tmp 目录陷阱
很多教程会让你把 Spice 的 UNIX Socket 扔到 /tmp/ 目录下(例如 /tmp/spice.sock)。
在 Arch Linux 下,千万不要这样做。
Arch 的 libvirtd 和 qemu 服务由 systemd 托管,默认开启了 PrivateTmp=true。这意味着:
- QEMU 启动后看到的
/tmp是一个被系统隔离的虚拟沙盒目录。 - 即便 QEMU 在它的 "/tmp" 下创建了 socket,你外面运行的 Looking Glass 客户端也根本找不到它,反之亦然。
解决方案:使用独立的运行目录
将 Socket 路径指定在 /var/run/ 或者你的用户运行目录 /run/user/1000/ 下。
最推荐的做法是,在 /etc/tmpfiles.d/looking-glass.conf 中追加一行,创建一个专门存放 socket 的目录:
d /run/looking-glass 0750 your_user kvm -
应用配置后,在虚拟机 XML 中将 Spice Socket 指向该目录。
三、 Libvirt XML 关键配置
在 Arch 上,通过 virsh edit your_vm_name 修改虚拟机配置。
1. 共享内存设备(Shmem)
在 <devices> 标签内加入以下内容(以 64MB 为例):
<shmem name='looking-glass'>
<model type='ivshmem-plain'/>
<size unit='M'>64</size>
</shmem>
注意:现代版本的 Libvirt 不需要写一长串 qemu:commandline 伪装参数,直接使用标准的 <shmem> 标签即可。
2. Spice 输入 Socket
为了让 Looking Glass 捕获鼠标和键盘,必须配置 Spice 并且使用 Socket 监听,而不是 TCP 端口:
<graphics type='spice' autoport='no'>
<listen type='socket' socket='/run/looking-glass/spice.sock'/>
<image compression='off'/>
<gl enable='no'/>
</graphics>
四、 彻底解决权限的“大招”:修改 QEMU 运行用户
如果你在配置完上述步骤后,依然遇到音频(PipeWire/PulseAudio)传不出来、或者 Socket 连接被拒绝的问题,这是因为 Arch 的 libvirt 默认以 nobody:kvm 或 libvirt-qemu:kvm 用户运行虚拟机,而你的音频服务和显示服务运行在 your_user 用户下,跨用户的 IPC 通信被严格限制。
对于个人单人使用的 Arch 桌面系统,最简单、最暴力的优雅解决方案是:直接让 QEMU 以你的日常用户身份运行。
编辑 /etc/libvirt/qemu.conf,找到以下两行并修改(默认是被注释掉的):
user = "your_user"
group = "kvm"
your_user替换为你的用户名。- 保持
group为kvm或你的主用户组。
修改后,重启 libvirtd 服务:
sudo systemctl restart libvirtd
这样做之后,QEMU 运行的虚拟机进程将天然拥有你当前用户的权限,无缝访问 /dev/shm/looking-glass、你的 Pipewire 声音 Socket,以及各类输入设备,彻底告别复杂的 ACL 和权限组配置。
五、 客户端启动与验证
在 Arch 宿主机上,通过 AUR 安装 looking-glass 包:
yay -S looking-glass
启动客户端时,显式指定你配置好的 Socket 路径:
looking-glass-client -f /dev/shm/looking-glass -s /run/looking-glass/spice.sock
如果画面成功显示,说明权限与 Socket 路径已经全部打通。如果遇到无法输入的问题,请检查 looking-glass-client 运行终端的权限,确保其有权限读取 /run/looking-glass/spice.sock。