Repository navigation
Description
Please confirm
- I have searched existing issues to check if an issue already exists for my feature request.
Is your feature request related to a problem? Please describe.
When adding an amd.com/gpu device, or a unix-hotplug device with ownership.inherit=true, the render group ID is taken from the host. This ID is different for all recent Ubuntu LTSs. For example, when running an ubuntu:26.04 container on a 24.04 host, /dev/kfd inside the container is owned by root:clock rather than root:render.
Describe the solution you'd like
If possible I'd like to make ownership work out of the box. On bare metal the devices we care about are managed by udev. For example kfd devices are configured by this line in /lib/udev/rules.d/50-udev-default.rules:
SUBSYSTEM=="kfd", GROUP="render", MODE="0660"
Most LXD containers already run systemd, including systemd-udevd, but it doesn't currently work:
- Kernel uevents don't appear in the container's network namespace
systemd-udev-trigger.servicefails to synthesize uevents because it can't write to/sys/.../uevent(I assume because the container is unprivileged)
However, there's an exception. After adding a unix-hotplug device, LXD forwards uevents related to that device into the container's netns.
My proposal is to:
- Synthesize uevents when adding a
unix-hotplugorgpudevice. Since we can't just write to/sys, I reconstructed the format of kernel uevent packets fromuevent_storein the kernel. Proof-of-concept code is here: lxd-6.8...jonathan-conder:lxd:feature/add-uevent - Synthesize uevents when removing a
unix-hotplugorgpudevice. - Consider extending this to other device types.
- Adjust the existing
unix-hotplugbehaviour. It listens for uevents marked withlibudevand forwards these into the container. It makes sense to listen forlibudevevents, because they have more information we can use for filtering. But I don't think it makes sense to forward them into the container. Instead we should synthesize a kernel-like uevent as above. This brings us closer to what happens on bare metal. - Synthesize uevents when starting (and stopping?) a container. This is the hard part, because
systemd-udevdwon't see the events if it isn't running yet. Either we time it carefully, or find a way to makesystemd-udev-trigger.servicework properly (maybe intercepting system calls or patchingudevadmupstream).
Describe alternatives you've considered
ACLs
Group-based ownership of device nodes is outdated, on bare metal most devices are tagged with uaccess and made available to users with an active logind seat.
LXD could add an acl config option to gpu and unix-hotplug devices, to allow clients to give certain UIDs access instead of certain GIDs. UIDs are easy to manipulate with cloud-init, and for our use case it will always be 1000.
The only reason this isn't my top suggestion is that ACLs on bare metal are also managed by udev. So implementing uevents properly would kill two birds with one stone.
Group ID mapping
LXD could expose a config option for mapping group names to IDs inside the container. This could be a device config option, a container option, or stored in the image metadata. When using CDI or ownership.inherit=true, LXD could look up the group name on the host, then consult the configured table to map the name back to an ID.
The main downside of this is that it requires extra work from either image maintainers or LXD clients. It might be difficult to maintain a comprehensive list, if some groups and udev rules are only distributed as optional packages.
Additional context
Original issue: canonical/workshop#832
Activity