device hotplug & file handles

Hi, For usb device pass-through (aka -device usb-host) it would be very useful to pass file handles from libvirt to qemu. The workflow would change from ... (1) libvirt enables access to /dev/usb/$bus/$dev (2) libvirt passes $bus + $dev (using hostbus + hostaddr properties) to qemu. (3) qemu opens /dev/usb/$bus/$dev ... to ... (1) libvirt opens /dev/usb/$bus/$dev (2) libvirt passes filehandle to qemu. Question is how can we pass the file descriptor best? My idea would be to simply add an fd property to usb-host: * Coldplug would be "-device usb-host,fd=<nr>" (cmd line). * Hotplug would be "device_add usb-host,fd=<getfd-name>" (monitor). Will that work from libvirt point of view? Or does anyone have an better idea? thanks, Gerd PS: background: https://bugzilla.redhat.com/show_bug.cgi?id=1595525

On Thu, May 07, 2020 at 16:49:14 +0200, Gerd Hoffmann wrote:
Hi,
For usb device pass-through (aka -device usb-host) it would be very useful to pass file handles from libvirt to qemu. The workflow would change from ...
(1) libvirt enables access to /dev/usb/$bus/$dev (2) libvirt passes $bus + $dev (using hostbus + hostaddr properties) to qemu. (3) qemu opens /dev/usb/$bus/$dev
... to ...
(1) libvirt opens /dev/usb/$bus/$dev (2) libvirt passes filehandle to qemu.
Question is how can we pass the file descriptor best? My idea would be to simply add an fd property to usb-host:
* Coldplug would be "-device usb-host,fd=<nr>" (cmd line). * Hotplug would be "device_add usb-host,fd=<getfd-name>" (monitor).
We have prior art for both approaches so it's fine.
Will that work from libvirt point of view?
Sure! Just please make sure that the new approach is detectable somehow. Either via device-list-properties or query-qmp-schema.
Or does anyone have an better idea?
thanks, Gerd
PS: background: https://bugzilla.redhat.com/show_bug.cgi?id=1595525

On 5/7/20 9:49 AM, Gerd Hoffmann wrote:
Hi,
For usb device pass-through (aka -device usb-host) it would be very useful to pass file handles from libvirt to qemu. The workflow would change from ...
(1) libvirt enables access to /dev/usb/$bus/$dev (2) libvirt passes $bus + $dev (using hostbus + hostaddr properties) to qemu. (3) qemu opens /dev/usb/$bus/$dev
... to ...
(1) libvirt opens /dev/usb/$bus/$dev (2) libvirt passes filehandle to qemu.
Question is how can we pass the file descriptor best? My idea would be to simply add an fd property to usb-host:
* Coldplug would be "-device usb-host,fd=<nr>" (cmd line). * Hotplug would be "device_add usb-host,fd=<getfd-name>" (monitor).
Will that work from libvirt point of view? Or does anyone have an better idea?
Qemu already has -add-fd (both a CLI version, and a QMP version when a Unix socket can pass fds), at which point any existing interface that uses qemu_open() will understand the magic syntax /dev/fdset/NNN to refer to the existing fd previously passed in via -add-fd. Libvirt is already able to use this feature for some cases (for example, see src/qemu/qemu_command.c:qemuBuildChrChardevFileStr). So all that remains is making sure -device usb-host uses qemu_open(), and if it didn't already do so, also making sure libvirt can find a way to introspect when usb-host started supporting fdset usage. Or put another way, let's use the generic fd mechanism that qemu already supports, rather than inventing yet another syntax.
thanks, Gerd
PS: background: https://bugzilla.redhat.com/show_bug.cgi?id=1595525
-- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org

On 5/7/20 4:49 PM, Gerd Hoffmann wrote:
Hi,
For usb device pass-through (aka -device usb-host) it would be very useful to pass file handles from libvirt to qemu. The workflow would change from ...
(1) libvirt enables access to /dev/usb/$bus/$dev (2) libvirt passes $bus + $dev (using hostbus + hostaddr properties) to qemu. (3) qemu opens /dev/usb/$bus/$dev
... to ...
(1) libvirt opens /dev/usb/$bus/$dev (2) libvirt passes filehandle to qemu.
Question is how can we pass the file descriptor best? My idea would be to simply add an fd property to usb-host:
* Coldplug would be "-device usb-host,fd=<nr>" (cmd line). * Hotplug would be "device_add usb-host,fd=<getfd-name>" (monitor).
Will that work from libvirt point of view? Or does anyone have an better idea?
thanks, Gerd
PS: background: https://bugzilla.redhat.com/show_bug.cgi?id=1595525
I don't have a better idea, but a little background on why libvirt even invented private /dev in the first place. The reason was that occasionally, when udev ran its rules it would overwrite the security labels on /dev nodes set by libvirt and thus denying access to QEMU. See: https://bugzilla.redhat.com/show_bug.cgi?id=1354251 Now, I think there is the same risk with what you are proposing. This isn't problem for DAC where permissions are checked during open(), but it may be a problem for SELinux where each individual operation with the FD is inspected. Having said that, I am not against this approach, in fact I'm in favour of it. Let's hope that people learned that having udev overwriting seclabels is a bad idea and the bug won't appear again. Michal
participants (4)
-
Eric Blake
-
Gerd Hoffmann
-
Michal Privoznik
-
Peter Krempa