fix(core): add libvirt patch for USB startupPolicy in containers#2432
fix(core): add libvirt patch for USB startupPolicy in containers#2432yaroslavborbat wants to merge 3 commits into
Conversation
8724900 to
bf557f9
Compare
fd65c11 to
56064f3
Compare
Signed-off-by: Yaroslav Borbat <yaroslav.borbat@flant.com>
95243aa to
66fe545
Compare
Signed-off-by: Yaroslav Borbat <yaroslav.borbat@flant.com>
e1b3a01 to
c772e3c
Compare
| + "device node '%s' is not accessible, skipping", | ||
| + found_bus, found_devno, | ||
| + virUSBDeviceGetPath(usb)); | ||
| + g_clear_pointer(&usb, virUSBDeviceFree); |
There was a problem hiding this comment.
usb is wrapped with g_autoptr, no need to cleanup explicitly. It will be cleaned automatically when usb goes out of scope, e.g. on return.
There was a problem hiding this comment.
g_autoptr only frees usb when it goes out of scope, i.e. at function exit. Here we need an explicit cleanup because this branch uses continue.
Without g_clear_pointer(&usb, virUSBDeviceFree), the loop would continue and the next assignment to usb would overwrite the current object, leaking it.
| + if (found) | ||
| + break; | ||
| + continue; |
There was a problem hiding this comment.
Is it possible to continue? We found device in sysfs, but device is not usable. It seems an unrecoverable error, so cleanup is needed:
| + if (found) | |
| + break; | |
| + continue; | |
| + goto cleanup; |
There was a problem hiding this comment.
goto cleanup is not appropriate here because a missing device node in /dev/bus/usb is not treated as a fatal search error in this code path. We did find a matching entry in sysfs, but this extra check verifies that the device is actually usable from the current mount namespace. If the node is missing, that means the device must be ignored, not that the search itself failed.
virUSBDeviceSearch() is used in two modes:
- by
vendor/product, where it returns a list and there may be multiple matches; - by
bus/devno, where at most one match is expected.
That is why the control flow differs:
continueis needed forvendor/productsearch, so we skip the inaccessible device and keep looking for other usable matches;if (found) break;is needed forbus/devnosearch: once the matchingsysfsentry was found but proved unusable, there is nothing else to search for, so we stop and return an empty result.
Using goto cleanup here would turn this case into an error return instead of an empty result. That would break the mandatory = false semantics in the callers: they should observe this case as "device not found/usable", not as an internal error.
Signed-off-by: Yaroslav Borbat <yaroslav.borbat@flant.com>
Description
Add a libvirt patch (
005-usb-startup-policy-in-containers.patch) that fixesstartupPolicy='optional'for USB hostdev in containerized environments.The patch adds a
virFileExistscheck on the device node path invirUSBDeviceSearchafter sysfs discovery. If the/dev/bus/usb/node is missing, the device is skipped so that callers see an empty result and handle the absence gracefully.deckhouse/3p-kubevirt#124
https://github.com/containerd/containerd/blob/c8802b6e7b81b21ffc134a9c1028f472f87dc262/pkg/oci/mounts.go#L58
Why do we need it, and what problem does it solve?
In containers, sysfs (
/sys/bus/usb/devices/) is mounted from the host kernel and exposes all USB devices regardless of mount namespace isolation. This causes libvirt'svirUSBDeviceSearchto report a device as available even when the corresponding/dev/bus/usb/node is not present in the container's mount namespace.As a result,
startupPolicy='optional'does not remove the missing USB hostdev from the domain XML during incoming migration, and QEMU fails to start with:This breaks VM live migration when USB devices are attached via hotplug and the target node does not yet have the device node mounted into the virt-launcher pod.
What is the expected result?
startupPolicy='optional'.Checklist
Changelog entries