Broken wayland socket passthrough to container

I filed this as a bug report, xwayland-satellite breaks wayland socket in incus container · Issue #1635 · lxc/incus · GitHub , and the response was confident this was a configuration issue rather than an incus bug. I would appreciate any help in correcting my container configuration.

NOTE: this issue is specific to using xwayland-satellite v0.5. My configuration has had no issues in the past with any other applications using the wayland socket passed in this way. I posted this because, in addition to the (probable) xwayland-satellite bug, I thought something might be wrong with incus too.

I tried to run xwayland-satellite in an incus container (LXD) that has a pass-through set up for the wayland display socket.
Not only does xwayland-satellite fail to run (the message “Connected to Xwayland on {}” doesn’t show up yet), no other wayland applications can run afterward until I restart the container.

xwayland-satellite works as expected when running on the host Sway compositor (with xwayland disable config). And Sway running on the host seems to be unaffected by all this.

In this same container setup, I can run other wayland graphical applications (e.g. foot), and other wayland compositors running nested (e.g. cage, gamescope) with Xwayland support, without issue.

Environment setup

  1. Install incus Incus - ArchWiki How to install Incus - Incus documentation
  2. check /etc/subuid and /etc/subgid, and if needed run echo "root:1000000:1000000000" | sudo tee -a /etc/subuid /etc/subgid
  3. If you haven’t already, run sudo incus admin init
  4. Set up container:
sudo incus profile create wayland <<EOF
config:
  environment.QT_QPA_PLATFORM: wayland
  environment.WAYLAND_DISPLAY: wayland-1
  environment.XDG_RUNTIME_DIR: /run/user/1000
  environment.XDG_SESSION_TYPE: wayland
description: Wayland GUI profile
devices:
  WaylandSocket:
    bind: container
    connect: unix:/run/user/1000/wayland-1
    gid: "1000"
    listen: unix:/run/user/1000/wayland-1
    security.gid: "1000"
    security.uid: "1000"
    type: proxy
    uid: "1000"
  mygpu:
    type: gpu
EOF

echo "D! /run/user/1000 1700 1000 1000 10d" > wayland-incus.conf
sudo incus launch images:archlinux/current/amd64 test
sudo incus file push -p wayland-incus.conf test/etc/tmpfiles.d/wayland-incus.conf
sudo incus stop test
sudo incus profile add test wayland
sudo incus alias add login 'exec @ARGS@ --user 1000 --group 1000 --env HOME=/home/tester/ -- /bin/bash --login'
sudo incus start test
sudo incus exec test -- bash
### in container
pacman -S --noconfirm xorg-xwayland xwayland-satellite foot cage mesa-utils ttf-dejavu
useradd -m tester
exit

Testing

  1. (on host) sudo incus login test
  2. (in container) First, verify wayland graphical apps work with foot
  3. Verify xwayland works in cage:
    cage -- glxinfo -B
    cage -- glxgears
    
  4. Try xwayland-satellite:
    xwayland-satellite & export DISPLAY=:0
    glxinfo -B
    glxgears
    kill %1
    
  5. Notice foot no longer works

System Info

  • Archlinux, linux-zen-6.13.1.zen1-1
  • Compositor: Sway 1.10.1
  • incus 6.9-1
  • xwayland-satellite 0.5-3

it’s very weird that you mount /run/user/1000/wayland-1 in container, because you are using arch which XDG_RUNTIME_DIR is managed by systemd. every time you login, systemd creates XDG_RUNTIME_DIR for you and destroy it when you logout. it’s even weird that you can run foot after login, I don’t think host wayland socket still exists in container XDG_RUNTIME_DIR.

your container doesn’t have a desktop environment, so where DISPLAY=:0 comes from? how is possible you can test xwayland in container? I think you need to mount host DISPLAY.

your profile looks very like the one in my tutorial. so i will correct it in here, the right way to use gpu in container should be:

devices:
  mygpu:
    type: gpu
    gputype: physical
    pci: '0000:00:02.0'
    mode: '0770'
    gid: '44'

gid should match container video’s group id. pci is gpu pic id.

I’ve never knew xwayland-satellite before. but i think it rely on xwayland, so it may only need DISPLAY.

config: 
  environment.DISPLAY: :0
description: x11
devices:
  x11:
    bind: container
    connect: unix:@/tmp/.X11-unix/X0
    listen: unix:/tmp/.X11-unix/X0
    security.gid: '1000'
    security.uid: '1000'
    gid: '1000'
    uid: '1000'
    type: proxy

Look at this topic. I usualy mount wayland socket in /mnt/ and link it to the $XDG_RUNTIME_DIR path using one line in $HOME/.profile file.

xwayland-satellite is only running in the container, not on the host. There is no X11 socket to pass to the container. I have xwayland disable set for Sway on the host. Also, some wayland compositors (e.g. Niri, which I also use) do not support xwayland.

Xwayland-satellite is a solution to compositors that do not integrate support for xwayland. It serves as a compatibility layer to run an xwayland rootless server as a wayland client. See GitHub - Supreeeme/xwayland-satellite: Xwayland outside your Wayland for more info.

As for where to put the sockets in the container, I picked /run/user/1000 to mirror the path on the host, assuming that is where most applications will look to find them. XDG_RUNTIME_DIR is also set there in the container – so unless I change XDG_RUNTIME_DIR, that is where they need to end up. As shown in the setup section of my post, I use a tmpfiles.d config to make sure /run/user/1000 exists. It does not get created by default on boot or login of the container. This has worked just fine in the past.

As I said in my post, many other wayland and X11 apps work just fine with this config – though I suppose it would be good to try your config out, just to see if anything changes.

I believe this is directly related to the xwayland-satellite bug I reported. Xwayland-satellite is doing something weird – and I filed an issue with them to correct it. The reason I posted this discussion, is because I thought it could be more than just a problem with xwayland-satellite, considering how the socket in the container is broken even after xwayland-satellite exits – but the host socket remains unaffected.

I found the issue. This isn’t an incus bug or config problem. Xwayland-satellite is overwriting the socket at /run/user/1000/wayland-1. That’s why it is broken afterward. Why it doesn’t, like when running on the host, correctly make a new wayland-2 socket and instead overwrites the existing one, is the next question.

Trying a disk mount + symbolic link helped me find the issue, since it made it easier to see it was getting overwritten.

1 Like