WSLg提供了GWSL的大部分功能。除非需要在WSLg中运行OpenGL应用(issue),否则大部分时候考虑只使用WSLg即可。
0x00 起因
最近在折腾WSL下用QEMU开黑苹果以开发iOS软件,结果QEMU一直起不来,报错如下:
|
|
但是我用musicbox测试了音频,发现音频工作正常,而且老早之前还用QEMU起过kali虚拟机,当时音频也做了额外配置但是忘记了。这回无论如何都不能工作,遂开始分析原因。
0x01 分析
老早之前我通过环境变量修复了这个问题,是如下脚本(已废弃):
|
|
这段代码配合在WSL内再手动起一个pulseaudio的服务,可以暂时解决问题(启动QEMU),只是不能播放音频。这个方案在今晚却失效了,于是不得不开始寻找问题的根源。
通过搜索,查到Github上的一个issue。这大概是反馈QEMU无法初始化pa(直通)的问题,里面提到:QEMU PulseAudio seems to work and initializes only if the pulseaudio server was explicitly started and enabled auth-anonymous in either unix or tcp mode, without enabling auth-anonymous it would fail to utilize it.
。
也就是说,QEMU依然依赖本地的pulseaudio server。于是,我开始检查$PULSE_SERVER
环境变量,却发现它惊人地指向了tcp:10.255.255.254
。这是一个很奇怪的IP,看格式像是一个网关,而且能ping通。$DISPLAY
变量也指向了10.255.255.254:0.0
。根据WSLg的文档,这种配置下GUI是能正常工作的,但是音频应该不能,后者应该要通过一个unix socket连接unix:/mnt/wslg/PulseServer
。
我想起来这应该是由于设置了dnsTunneling=true
时候WSL2会把DNS请求转发到Windows,应该就是/etc/resolv.conf
的设置。不过,也有可能是WSLg把pulseaudio的功能转交给Windows而主动设置的环境变量,因而这也合理。
于是我关闭了dnsTunneling,发现这个变量指向了我的本机IP。于是确认了这个变量随着/etc/resolv.conf
变化。这其实是GWSL的一个自动化功能(如下代码),在WSLg之前能提供无感使用图形界面的体验。然而现在这使得音频无法正常工作。关键是我记得在之前我手动在~/.bashrc
内删除了这两行,理论上应该不会再自动导出这两个变量了。我检查了~/.profile
和/etc/profile
,但是仍然找不到是在哪导出的。
|
|
于是把GWSL打开,看有没有办法让它去清理环境变量。最后在GWSL Distro Tools/More Shells and Options
中找到了Clean GWSL Additions
才完成清理。再次检查两个变量得到:
|
|
此时重启WSL,pulseaudio服务会正常工作(但是默认情况只有non-root用户才有,QEMU因此也得运行在non-root模式下),QEMU能正常启动。
0x02 结论
GWSL自动导出$DISPLAY
和$PULSE_SERVER
环境变量的设置会使得WSLg无法正常工作。对于从GWSL迁移到WSLg的用户,应该考虑清理之前的环境变量。