### Description
This PR updates the `opengl` interface to bind mount the `/us…r/lib/wsl` directory from the host (wsl2) to the same path inside the snap.
<details>
<summary>Why this is needed</summary>
#### ld - wsl paths
In wsl2 there is an additional ld config file at `/etc/ld.so.conf.d/ld.wsl.conf` containing `/usr/lib/wsl/lib`. This config is also present inside the snap.
```
$ ls /etc/ld.so.conf.d/
fakeroot-x86_64-linux-gnu.conf libc.conf zz_i386-biarch-compat.conf
ld.wsl.conf x86_64-linux-gnu.conf zz_x32-biarch-compat.conf
$
$ cat /etc/ld.so.conf.d/ld.wsl.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [automount]
# ldconfig = false
/usr/lib/wsl/lib
```
#### Intel GPU - `clinfo`
Some configurations and libraries specify absolute paths to the wsl equivalent libraries. For example the [Intel Compute Runtime](https://github.com/intel/compute-runtime/blob/44e2e35b5afd48e3c6c99bd6eec3b371c6b50293/shared/source/dll/linux/options_linux.inl#L19) specifically points to `/usr/lib/wsl/lib/libdxcore.so`.
#### NVIDIA GPU - `nvidia-smi`
If `libnvidia-ml.so` is staged in the snap, that will be found by `ld` before it looks in `/usr/lib/wsl/lib`. The staged `libnvidia-ml.so` depends on `libcuda.so.1`, while the one from wsl depends on `libdxcore.so`.
Staged:
```
file=libcuda.so.1 [0]; dynamically loaded by /snap/clinfo-jpm/5/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1 [0]
```
WSL:
```
file=libdxcore.so [0]; dynamically loaded by /usr/lib/wsl/lib/libnvidia-ml.so.1 [0]
```
A user should not stage `libnvidia-ml.so`, or the LD_LIBRARY_PATH should be adjusted to ensure `/usr/lib/wsl/lib` takes precedence over `/snap/<SNAP_INSTANCE_NAME>/<SNAP_REVISION>/usr/lib/x86_64-linux-gnu`.
<details>
<summary>strace extracts</summary>
Snap on native Ubuntu:
```
openat(AT_FDCWD, "/var/lib/snapd/lib/gl/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\274\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=2283608, ...}) = 0
mmap(NULL, 16271784, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ce55aa00000
mmap(0x7ce55aa1b000, 1556480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7ce55aa1b000
mmap(0x7ce55ab97000, 413696, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x197000) = 0x7ce55ab97000
mmap(0x7ce55abfc000, 208896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1fb000) = 0x7ce55abfc000
mmap(0x7ce55ac2f000, 13982120, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ce55ac2f000
close(3)
```
[nsmi-strace-ubuntu-nostaged.txt](https://github.com/user-attachments/files/26081366/nsmi-strace-ubuntu-nostaged.txt)
Snap on WSL:
```
openat(AT_FDCWD, "/var/lib/snapd/lib/gl/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/var/lib/snapd/lib/gl32/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/snap/clinfo-jpm/x1/usr/lib/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/snap/clinfo-jpm/x1/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=20035, ...}) = 0
mmap(NULL, 20035, PROT_READ, MAP_PRIVATE, 3, 0) = 0x77c544a3c000
close(3) = 0
openat(AT_FDCWD, "/usr/lib/wsl/lib/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2409\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0555, st_size=266528, ...}) = 0
mmap(NULL, 4400080, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_DENYWRITE, -1, 0) = 0x77c5441cd000
mmap(0x77c544200000, 2302928, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x77c544200000
munmap(0x77c5441cd000, 208896) = 0
munmap(0x77c544433000, 1885136) = 0
mprotect(0x77c54422d000, 2093056, PROT_NONE) = 0
mmap(0x77c54442c000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2c000) = 0x77c54442c000
close(3)
```
[nsmi-strace-wsl-nostagednv.txt](https://github.com/user-attachments/files/26081372/nsmi-strace-wsl-nostagednv.txt)
Snap on WSL with nvidia-utils staged:
```
openat(AT_FDCWD, "/var/lib/snapd/lib/gl/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/var/lib/snapd/lib/gl32/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/snap/clinfo-jpm/5/lib/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/snap/clinfo-jpm/5/usr/lib/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/snap/clinfo-jpm/5/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\274\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=2296056, ...}) = 0
mmap(NULL, 16295144, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7d3b52800000
mprotect(0x7d3b5281b000, 1982464, PROT_NONE) = 0
mmap(0x7d3b5281b000, 1564672, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7d3b5281b000
mmap(0x7d3b52999000, 413696, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x199000) = 0x7d3b52999000
mmap(0x7d3b529ff000, 208896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1fe000) = 0x7d3b529ff000
mmap(0x7d3b52a32000, 13993192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7d3b52a32000
close(3) = 0
...
[pid 1941] write(1, "NVIDIA-SMI has failed because it"..., 145) = 145
[pid 1941] exit_group(9) = ?
[pid 1954] <... poll resumed> <unfinished ...>) = ?
[pid 1954] +++ exited with 9 +++
+++ exited with 9 +++
error: exit status 9
```
[nsmi-strace-wsl-stagednv.txt](https://github.com/user-attachments/files/26081382/nsmi-strace-wsl-stagednv.txt)
</details>
<details>
<summary>Difference in order of LD_LIBRARY_PATH</summary>
This experiment uses a snap with `nvidia-utils` and therefore `libnvidia-ml.so` staged in the snap.
Default LD_LIBRARY_PATH
```
$ sudo snap run --shell clinfo-jpm
# echo $LD_LIBRARY_PATH
/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/snap/clinfo-jpm/5/lib:/snap/clinfo-jpm/5/usr/lib:/snap/clinfo-jpm/5/usr/lib/x86_64-linux-gnu
```
Add wsl path as prefix
```
# export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
# nvidia-smi
Tue Mar 17 17:52:48 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 590.48.01 Driver Version: 581.80 CUDA Version: 13.0 |
+-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce GTX 1080 Ti On | 00000000:01:00.0 Off | N/A |
| 0% 30C P8 11W / 250W | 7573MiB / 11264MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 32 G /Xwayland N/A |
| 0 N/A N/A 700 C /llama-server N/A |
+-----------------------------------------------------------------------------------------+
```
Reset LD_LIBRARY_PATH
```
# export LD_LIBRARY_PATH=/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/snap/clinfo-jpm/5/lib:/snap/clinfo-jpm/5/usr/lib:/snap/clinfo-jpm/5/usr/lib/x86_64-linux-gnu
# nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
```
Add wsl path to end
```
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/wsl/lib
# nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
```
</details>
</details>
### Related
* PF-6354
* https://github.com/jpm-canonical/clinfo-snap/blob/main/snap/snapcraft.yaml#L6
* https://github.com/canonical/gemma3-snap/pull/71
### Test procedure
Install a build of snapd from this branch, then follow the following test procedures.
<details>
<summary>Manually verify bind mount</summary>
#### WSL
Install any snap that has the `opengl` plug. `clinfo-jpm` from the edge channel can be used.
Shell into the snap, then verify the bind mount exists, and that there are libraries exposed:
```
jpmeijers@olga:~$ snap run --shell clinfo-jpm
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
jpmeijers@olga:/home/jpmeijers$ ls /usr/lib/wsl
drivers lib wait-for-cloud-init wsl-setup
jpmeijers@olga:/home/jpmeijers$ ls /usr/lib/wsl/lib/
libcuda.so libdxcore.so libnvidia-gpucomp.so libnvoptix.so.1
libcuda.so.1 libnvcuvid.so libnvidia-gpucomp.so.580.105.07 libnvoptix_loader.so.1
libcuda.so.1.1 libnvcuvid.so.1 libnvidia-ml.so.1 libnvwgf2umx.so
libcudadebugger.so.1 libnvdxdlkernels.so libnvidia-ngx.so.1 nvidia-ngx-updater
libd3d12.so libnvidia-encode.so libnvidia-opticalflow.so nvidia-smi
libd3d12core.so libnvidia-encode.so.1 libnvidia-opticalflow.so.1
```
#### Multipass VM
In Multipass VM:
```
sudo mkdir -p /usr/lib/wsl/lib
echo "Hi there" | sudo tee /usr/lib/wsl/lib/test.txt
sudo snap install --dangerous <snapd-from-this-branch>
sudo snap install clinfo-jpm --edge
snap run --shell clinfo-jpm
```
In snap shell, make sure file is readable:
```
$ cat /usr/lib/wsl/lib/test.txt
Hi there
```
</details>
<details>
<summary>Test `clinfo` and `nvidia-smi`</summary>
Using `clinfo-jpm` from `edge`, along with `snapd` from this branch.
```
jpmeijers@olga:~$ snap list snapd
Name Version Rev Tracking Publisher Notes
snapd 2.74.1+g325.046bcae-dirty x1 latest/stable - snapd
jpmeijers@olga:~$ sudo snap refresh clinfo-jpm --edge --amend
clinfo-jpm (edge) 3.0.23.01.25+snap.1957829 from JPM refreshed
```
If you have an Intel GPU, make sure `clinfo` prints details on your GPU:
```
jpmeijers@olga:~$ clinfo-jpm
Number of platforms 1
Platform Name Intel(R) OpenCL Graphics
Platform Vendor Intel(R) Corporation
Platform Version OpenCL 3.0
...
Number of devices 1
Device Name Intel(R) Graphics [0x56a2]
Device Vendor Intel(R) Corporation
...
```
If you have an NVIDIA GPU, make sure `nvidia-smi` can detect it:
```
jpmeijers@olga:~$ clinfo-jpm.nvidia-smi
Fri Mar 20 11:50:38 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 590.48.01 Driver Version: 581.80 CUDA Version: 13.0 |
+-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce GTX 1080 Ti On | 00000000:01:00.0 Off | N/A |
| 0% 40C P8 12W / 250W | 157MiB / 11264MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 58 G /Xwayland N/A |
| 0 N/A N/A 778 C /llama-server N/A |
+-----------------------------------------------------------------------------------------+
```
</details>
<details>
<summary>Using an inference snap</summary>
Install gemma3 from [PR](https://github.com/canonical/gemma3-snap/pull/84):
```
sudo snap install gemma3 --channel latest/edge/pr-84
```
By default gemma3 will use a CPU engine in WSL, as it does not detect any PCI GPUs. Manually switch to the appropriate engine depending on if you have an Intel or NVIDIA GPU.
#### Intel GPU
```
sudo gemma3 use-engine intel-gpu
sudo snap restart gemma3.server
```
This will run OpenVINO Model Server, serving a 7B model.
Check the snap logs to verify the server starts up without an error.
Chat with the model:
```
gemma3 chat
```
#### NVIDIA GPU
```
sudo gemma3 use-engine nvidia-gpu-amd64
sudo snap restart gemma3.server
```
This will run llama.cpp serving a 7B model.
Check the snap logs to verify the server starts up without an error.
Chat with the model:
```
gemma3 chat
```
</details>