Introduction

WSL 2 provides VM-based Linux experience with GUI support (wslg), whereas preverving the feel of using Windows: You can ls /mnt/c or even execute a Windows application with explorer.exe .

Tools that enhance WSL 2

See WSL Utilities, It provides various tools including wslview to open a file/URL using default application on Windows, wslpath to convert a WSL path to Linux one, and vice versa.

.{ba,z}shrc snippet

export BROWSER=wslview
alias open=wslview
alias pbcopy=clip.exe
alias pbpaste='powershell.exe Get-Clipboard'
alias clear='powershell.exe Clear-Host'

Pitfalls

Though WSL 2 make Linux users happy, it has several pitfalls.

PMTUD not working

If you are accessing a remote endpoint whose MTU is lower than yours, then :(

You can either set your MTU in WSL manually like ip link set eth0 mtu 1400 or setup MSS clamp on your router.

https://janovesk.com/wsl/2022/02/15/wsl2-and-mtu.html

Port forwarding limits

Windows will not forward some ports from WSL.

https://github.com/microsoft/WSL/issues/5306

PS$ netsh int ipv4 show excludedportrange protocol=tcp                                                            

Protocol tcp Port Exclusion Ranges

Start Port    End Port
----------    --------
      1032        1131
      1132        1231
      1435        1534
      1569        1668
      7681        7780
      9596        9695
     50000       50059     *
     59100       59100     *

* - Administered port exclusions.

To work around it, you have to

  • Either manually set up port forwarding by PowerShell

netsh interface portproxy

  • Or make WSL2 runs in bridge mode by editing ~/.wslconfig on host
[wsl2]
networkingMode=bridged
vmSwitch=Bridging  # the interface you'd like to use, you should configure it in Hyper-V

If you’re running something in LAN, such as nmb (NetBIOS) or avahi-daemon (mDNS), you have to change the hostname in /etc/wsl.conf to avoid hostname collision with Windows

[network]
hostname=WSL

IPv6 not available

Workaround: switch WSL to bridge mode and

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0

Unable to mount another VHDX on WSL boot

I make my /home under WSL a BTRFS partition to make use of BTRFS transparent compression.

However you can’t mount a VHDX on WSL boot with /etc/fstab

You have to write an ugly wrapper script like

#!/bin/bash -x

/mnt/c/Windows/system32/wsl.exe --mount --bare --vhd 'C:\path\to\projects.vhdx'
/usr/bin/sudo /usr/bin/mount -o compress=zstd:15,autodefrag,discard /dev/sdd /home

Then make it run at WSL boot by setting /etc/wsl.conf in WSL:

[boot]
systemd=true  # If your distribution supports systemd
command=/path/to/the/script/above

WSL 2 doesn’t run in background

If you close the last terminal / IDE owning WSL processes, the WSL would stop in a minute by default.

You can adjust it by setting in ~/.wslconfig on host

[wsl2]
vmIdleTimeout=86400  # a large value in seconds

Unable to load kernel modules

Microsoft ships its own kernel and build everything inside the kernel without the need of kernel modules.

Linux WSL 5.15.79.1-microsoft-standard-WSL2 #1 SMP Wed Nov 23 01:01:46 UTC 2022 x86_64 GNU/Linux

It’s good that you can run any distribution without caring about where the kernel modules.

But it becomes a disaster when the Microsoft kernel doesn’t contains the kernel features you want (like BBR TCP algorithm) or you’d like to add a custom kernel module.

Thereotically you could load a custom kernel by modifying ~/.wslconfig, but I’ve not tried it.

Core dumps not available

WSL stores core dumps in /mnt/wslg/dumps but it prevents core dump by default, you need to

ulimit -c unlimited # enable coredump first
python crash.py # run the application that causes crash
gdb `which python` /mnt/wslg/dumps/core.python # then gdb

CUDA not available

>>> import torch
>>> torch.cuda.is_available()
True

If it was False, you may need to fix your WSL CUDA library

$ ls /usr/lib/wsl/lib
-r-xr-xr-x 1 root root 147K Dec 22 17:29 libcuda.so
-r-xr-xr-x 1 root root 147K Dec 22 17:29 libcuda.so.1
-r-xr-xr-x 1 root root 147K Dec 22 17:29 libcuda.so.1.1

See https://github.com/microsoft/WSL/issues/5663

GUI application doesn’t start up

Error: can’t open display

Try ln -s /mnt/wslg/.X11-unix /tmp/.X11-unix

See https://github.com/microsoft/wslg/issues/844

Unable to run Windows applications

WSL interop may not work as some distros are setting binfmt on their own.

Try add :WSLInterop:M::MZ::/init:PF into /usr/lib/binfmt.d/WSLInterop.conf and sudo systemctl restart systemd-binfmt

See https://github.com/microsoft/WSL/issues/8843

Unable to start the same service under different WSL distros

These distros are running under the same network namespace, you have to run these services under different ports.

https://superuser.com/questions/1719393/how-does-wsl-wsl2-wslg-work-without-systemd

Slow access to Windows files

Especially you’re accessing bunch of small files. plan9 via Hyper-V socket is fast, but it’s not as fast as native ext4 or BTRFS.

Sharing file or directory from a WSL distro to another

mount --bind /path/you/would/share /mnt/wsl/directory

Though / is isolated in different running distros, /mnt/c, /mnt/wsl and /mnt/wslg are shared between all WSL 2 distros.