在 Arch@WSL2 中启用 systemd , GUI 与 GPU加速

7 minute read

Published:

知乎

众所周知, Ubuntu in WSL2 是微软和Ubuntu的亲儿子, 从两边都得到了最好的支持, 开箱即用.

而 Arch in WSL 是纯纯的野孩子, 微软和Arch两边都不管的, 想要在其中启用 systemd , GUI 与 GPU加速, 会碰到许多坑, 这篇文章把坑全给填平.

以下方法在 2024-3 的 Windows11-23H2-22631.3235 中测试通过.

理论上应该在所有支持 WSLg 和 systemd 的 WSL Linux 发行版中都有效.

2024-6-23 Arch 更新 systemd-256 后必须禁用 cgroup-v1.

Prepare 准备

  1. ensure WSL components and Arch packages are all updated.
    确保 WSL 组件和 Arch 包已更新.
     PS> wsl --update
     Checking for updates.
     The most recent version of Windows Subsystem for Linux is already installed.
    
     Arch$ sudo pacman -Syuu
     :: Synchronizing package databases...
     core is up to date
     extra is up to date
     :: Starting full system upgrade...
     there is nothing to do
    
  2. edit /etc/wsl.conf to enable systemd.
    修改 /etc/wsl.conf 以启用 systemd.
     [boot]
     systemd=true
    
  3. create /etc/tmpfiles.d/wslg.conf.
    创建 /etc/tmpfiles.d/wslg.conf1.
     # Type Path           Mode UID  GID  Age Argument
     L+     /tmp/.X11-unix -    -    -    -   /mnt/wslg/.X11-unix
    
  4. create ~/.config/user-tmpfiles.d/wslg.conf.
    创建 ~/.config/user-tmpfiles.d/wslg.conf.
     # Type Path              Mode UID  GID  Age Argument
     L+     %t/wayland-0      -    -    -    -   /mnt/wslg/runtime-dir/wayland-0
     L+     %t/wayland-0.lock -    -    -    -   /mnt/wslg/runtime-dir/wayland-0.lock
     L+     %t/pulse/native   -    -    -    -   /mnt/wslg/runtime-dir/pulse/native
     L+     %t/pulse/pid      -    -    -    -   /mnt/wslg/runtime-dir/pulse/pid
    
  5. execute command below to enable ~/.config/user-tmpfiles.d/wslg.conf.
    执行下面的命令以启用 ~/.config/user-tmpfiles.d/wslg.conf.
     systemctl --user enable systemd-tmpfiles-setup.service systemd-tmpfiles-clean.timer
    
  6. add current user to group video,render
    把当前用户加入用户组 video,render
     sudo usermod --append --groups video,render user1
    
  7. edit %UserProfile%/.wslconfig to disable cgroup-v1 in windows, see 2. New Added in 2024-6-23
    在 Windows 中编辑 %UserProfile%/.wslconfig 以禁用 cgroup-v1, 参见 2. 2024-6-23 新加入
    You must do so from systemd-256.
    Arch 系统更新 systemd-256 及后续版本后, 此步骤必做.
     [wsl2]
     kernelCommandLine = cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1
    
  8. restart Arch@WSL2 in Windows PowerShell.
    在 Windows PowerShell 中 重启 Arch@WSL2.
     wsl.exe --shutdown
    

Install and check 安装并检查

Enter Arch terminal.
进入 Arch 终端.

  1. Mesa(OpenGL,GLX,EGL,GLES)
     $ sudo pacman -S mesa mesa-utils
     $ glxinfo -B | grep render
     direct rendering: Yes
     OpenGL renderer string: D3D12 (Your GPU)
     $ eglinfo -B
     $ glxgears
     $ eglgears_wayland
    
  2. Vulkan
    • vulkan-dzn for using D3D12 over GPU is unavailable, so we can only use vulkan-swrast to run Vulkan over CPU.
    • vulkan-dzn 用于通过 D3D12 调用 GPU, 但 Arch 不包含, 只能用 vulkan-swrast 来使用 CPU.
       $ sudo pacman -S vulkan-swrast vulkan-tools
       $ vulkaninfo
       GPU id : 0 (llvmpipe (LLVM 16.0.6, 256 bits)):
       $ vkgears
       $ vkcube
      
    • You can compile mesa to get libvulkan_dzn.so(vulkan-dzn)
    • 可以重新编译 mesa 得到 libvulkan_dzn.so(vulkan-dzn)
       $ sudo pacman -U vulkan-dzn-24.0.2-2.tar.zst
       $ vulkaninfo
       GPU id : 0 (Microsoft Direct3D12 (Your GPU)):
      
  3. VA-API
    • Currently, vainfo fails on x11 and wayland.
    • 当前, vainfo 不能在 x11 和 wayland 上运行.
       $ sudo pacman -S libva libva-mesa-driver libva-utils
       $ vainfo --display drm
       Trying display: drm
       vainfo: VA-API version: 1.20 (libva 2.20.1)
       vainfo: Driver version: Mesa Gallium driver 24.0.2-arch1.1 for D3D12 (Your GPU)
       vainfo: Supported profile and entrypoints
        VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      
  4. VDPAU
    • Currently, vdpauinfo fails over D3D12.
    • 当前, vdpauinfo 调用 D3D12 驱动失败.
       $ sudo pacman -S libvdpau mesa-vdpau vdpauinfo
       $ VDPAU_DRIVER=d3d12 vdpauinfo
      
    • So use vdpauinfo over VA-API by package libvdpau-va-gl. But VA-API fails on x11, and VDPAU only runs on x11.
    • 所以安装包 libvdpau-va-gl 来使 vdpauinfo 调用 VA-API 驱动. 但 VA-API 不能在 x11 运行, 而 VDPAU 只支持 x11.
     $ sudo pacman -S libvdpau-va-gl
     $ VDPAU_DRIVER=va_gl vdpauinfo
     display: :0   screen: 0
     API version: 1
     Information string: OpenGL/VAAPI backend for VDPAU
    
     Video surface:
    
     name   width height types
     -------------------------------------------
     420     4096  4096  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 NV24 YV24 P010 P016 Y_U_V_444_16
    
  5. OpenCL
    • I cannot determine which driver should be used in WSL2.
    • 不知道在 WSL2 中该用哪个驱动.
       $ sudo pacman -S ocl-icd opencl-rusticl-mesa clinfo
       $ clinfo
      
    • NVidia: opencl-nvidia
    • AMD: rocm-opencl-runtime
    • Intel: intel-compute-runtime
    • Mesa: opencl-rusticl-mesa opencl-clover-mesa

Lib Details 运行库详情

In website https://pkgs.org , you can use filename below (libvulkan_lvp.so) to search package name in your distro.
可以在网站 https://pkgs.org 中, 用下面的文件名(libvulkan_lvp.so)来搜索你的发行版对应的包名.

APIlibdriverdriversinfo utiltest utils
GLXlibGLX*.sod3d12_dri.so/usr/lib/dri/*_dri.soglxinfoglxgears
EGLlibEGL*.sod3d12_dri.so/usr/lib/dri/*_dri.soeglinfoeglgears_wayland, eglgears_x11
GLESlibGLESv2.sod3d12_dri.so/usr/lib/dri/*_dri.soes2_infoes2gears_wayland, es2gears_x11
Vulkanlibvulkan.solibvulkan_lvp.so libvulkan_dzn.so/usr/lib/libvulkan_*.sovulkaninfovkcube-wayland, vkcube
VA-APIlibva.so, libva-*.sod3d12_drv_video.so/usr/lib/dri/*_drv_video.sovainfo 
VDPAUlibvdpau.solibvdpau_d3d12.so libvdpau_va_gl.so/usr/lib/vdpau/libvdpau_*.sovdpauinfo 
OpenCLlibOpenCL.solibRusticlOpenCL.so/usr/lib/lib*OpenCL.soclinfo 

Glitches in GUI 程序花屏

  • Enter WLSg system distro, and restart weston.
  • 进入 WLSg 系统发行版, 重启 weston.
PS> wsl --system

wslg$ ps -A | grep weston
     10 ?        00:00:09 weston
    349 ?        00:00:00 weston-rdprail-

wslg$ kill -9 10

wslg$ ps -A | grep weston
    707 ?        00:00:00 weston
    777 ?        00:00:00 weston-rdprail-

wslg$ exit
logout

Problems 问题

  • cannot open display: :03
  • Error: couldn’t open display :0
  • Error: unable to open display :0
  • XCB failed to connect to the X server due to error:1.
  • EGLUT: failed to initialize native display
  • qt.qpa.xcb: could not connect to display :0
  • Failed to create wl_display (No such file or directory)

Troubleshooting 故障诊断

  1. check environment variables
    检查环境变量
     $ env | grep -E "XDG|DISPLAY|PULSE"
     DISPLAY=:0
     WAYLAND_DISPLAY=wayland-0
     PULSE_SERVER=unix:/mnt/wslg/PulseServer
     XDG_RUNTIME_DIR=/run/user/1000/
    
  2. check dev files
    检查设备文件
     $ ls -l /dev/dxg /dev/dri/card0 /dev/dri/renderD128
     crw-rw---- 1 root video  226,   0 Mar  6 18:49 /dev/dri/card0
     crw-rw-rw- 1 root render 226, 128 Mar  6 18:49 /dev/dri/renderD128
     crw-rw-rw- 1 root root    10, 127 Mar  6 18:49 /dev/dxg
    
    • If you have two or more distros installed in WSL2, the last started distro may recreate the dev files even in the first started distro, and make the owner group mismatch in the first distro4.
    • 如果你在 WSL2 里安装了多个发行版, 后启动的发行版会重新创建这些设备文件, 甚至会影响先启动的发行版, 导致这些设备文件用户组混乱4.
     $ ls -l /dev/dxg /dev/dri/card0 /dev/dri/renderD128
     crw-rw---- 1 root  985 226,   0 Mar  6 18:52 /dev/dri/card0
     crw-rw-rw- 1 root  989 226, 128 Mar  6 18:52 /dev/dri/renderD128
     crw-rw-rw- 1 root root  10, 127 Mar  6 18:52 /dev/dxg
    
     $ cat /etc/group | grep -E "video|render"
     video:x:44:user1
     render:x:110:user1
    
  3. check display sockets
    检查 X11 和 wayland 的 socket 文件
    • 4 files and 1 dir must link to /mnt/wslg/*
    • 下面的4个文件和1个目录必须链接到 /mnt/wslg/*
       $ ls -ld /tmp/.X11-unix $XDG_RUNTIME_DIR/wayland* $XDG_RUNTIME_DIR/pulse/*
       lrwxrwxrwx 1 user1 user1 34 Mar  6 18:49 /run/user/1000//pulse/native -> /mnt/wslg/runtime-dir/pulse/native
       lrwxrwxrwx 1 user1 user1 31 Mar  6 18:49 /run/user/1000//pulse/pid -> /mnt/wslg/runtime-dir/pulse/pid
       lrwxrwxrwx 1 user1 user1 31 Mar  6 18:49 /run/user/1000//wayland-0 -> /mnt/wslg/runtime-dir/wayland-0
       lrwxrwxrwx 1 user1 user1 36 Mar  6 18:49 /run/user/1000//wayland-0.lock -> /mnt/wslg/runtime-dir/wayland-0.lock
       lrwxrwxrwx 1 root      root      19 Mar  6 18:49 /tmp/.X11-unix -> /mnt/wslg/.X11-unix
      
  4. check group permissions
    检查用户组和权限
     $ groups
     video render wheel user1
    

Reasons 原因

  1. /init which is from Microsoft create the 5 links above to /mnt/wslg/* .
    /init(来自微软)创建了上述的5个链接,正确指向 /mnt/wslg/* .
  2. systemd mount and tmpfiles service recreate /tmp and /run/user/1000, and make them empty.
    systemd 的 mount(挂载文件系统) 和 tmpfiles(创建临时目录) 两个服务重新创建了 /tmp/run/user/1000 , 使之清空.
  3. we’d use tmpfiles service to recreate the 5 links after step 2.
    我们就用 tmpfiles 服务在步骤2. 之后重新创建5个链接.
    /etc/tmpfiles.d/wslg.conf, ~/.config/user-tmpfiles.d/wslg.conf
  4. What does Ubuntu do?
    Ubuntu has disabled mounting /tmp and /run/user/1000 as tmpfs, so links created by /init won’t be cleared.
    Ubuntu 是怎么做的?
    Ubuntu 禁用了作为 tmpfs 挂载 /tmp/run/user/1000, 所以/init创建的链接不会被清除.
     Ubuntu$ mount | grep -E "user|tmp"
     none on /tmp/.X11-unix type tmpfs (ro,relatime)
    
     none on /run/user type tmpfs (rw,nosuid,nodev,noexec,noatime,mode=755)
     none on /run/user type tmpfs (rw,relatime)
    
     Arch$ mount | grep -E "user|tmp"
     tmpfs on /tmp type tmpfs (rw,nosuid,nodev,size=8131748k,nr_inodes=1048576)
     none on /tmp/.X11-unix type tmpfs (ro,relatime)
    
     none on /run/user type tmpfs (rw,nosuid,nodev,noexec,noatime,mode=755)
     none on /run/user type tmpfs (rw,relatime)
     tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=1626348k,nr_inodes=406587,mode=700,uid=1000,gid=1000)
     tmpfs on /mnt/wslg/run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=1626348k,nr_inodes=406587,mode=700,uid=1000,gid=1000)
    

References 参考链接