Skip to content

Netlink announcements not arriving in unprivileged Proxmox VE LXC (device creation works) #17

Description

@BramVandenbossche

Thanks for building this — it is the only project I found that addresses this problem head-on.

I'm running Sunshine in an unprivileged LXC on Proxmox VE 9.2.5 (kernel 7.0.14-6-pve), Debian 13 guest, sway headless on an AMD Cezanne iGPU. Video and audio stream fine. Input does not arrive, and I've narrowed it to the netlink announcement step.

What works

Device creation through the CUSE proxy is solid. With:

ExecStart=/usr/local/bin/vuinputd --major 120 --minor 414795 \
  --container-runtime generic-send-netlink-message-only

and the container binding /dev/vuinput over its own /dev/uinput, Sunshine's three devices appear on the host exactly on cue:

/sys/devices/virtual/input/input*/name
  Mouse passthrough
  Mouse passthrough (absolute)
  Keyboard passthrough

Per the generic-send-netlink-message-only help text I bind-mounted both /dev/input and the host's /run/udev into the container (the latter via /mnt/hostudev, since a direct entry on /run/udev is shadowed by the container's own tmpfs).

I also had to add host udev rules to make them usable from inside: OWNER="101000" (container uid 1000 under the default idmap u 0 100000 65536), and to undo the isolation tagging — ID_SEAT back to seat0 and ID_INPUT_MOUSE / ID_INPUT_KEYBOARD restored from ID_VUINPUT_*. Without that last part libinput skips the devices entirely, since the container reads the same udev database as the host.

What does not work

After those rules, libinput list-devices inside the container finds the devices. But wlroots' libinput backend finds zero, and sway refuses to start without WLR_LIBINPUT_NO_DEVICES=1.

My reading: libudev's lookup path works because it only consults /sys and /run/udev/data, both of which I've made available. wlroots additionally opens a udev monitor, and kernel uevents are network-namespace scoped, so the container never sees them. That is precisely the gap generic-send-netlink-message-only is meant to close — but no announcement seems to reach the container's netns. journalctl -u vuinputd shows nothing at the moment Sunshine creates its devices.

Both libseat backends were tried (builtin with SEATD_VTBOUND=0, and seatd); both give zero devices.

Targeting options break device creation

Neither of these works — both stop Sunshine from creating anything at all, with Unable to create virtual mouse: Permission denied:

--target-container 105
--target-pid <container init pid>

The runtime list in --help has no LXC entry, so I assume --target-container cannot resolve an LXC name and rejects every client. --target-pid is also awkward here in principle, since the PID changes on every container start.

Questions

  1. Is generic-send-netlink-message-only expected to deliver uevents into an LXC network namespace, or does it rely on the runtime having a placement implementation?
  2. Is there a supported option combination for unprivileged LXC? The README mentions LXC as working "in principle", but I couldn't find a matching runtime.
  3. Would you accept a patch adding an LXC runtime, if you can point me at what name resolution and namespace discovery should look like?

Also worth flagging for other LXC users: systemd-udevd cannot run inside an unprivileged container at all — it fails ConditionPathIsReadWrite=/sys — so approaches that rely on a container-local udevd building its own database are not portable there.

Happy to run any diagnostic you want; the setup is disposable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions