Don't try to run qemu with pci passthrough, when pcifront fails to start
The problem you're addressing (if any)
After pcifront fails to initialize in guest stubdom doing passthrough, eg. because of memory allocation failure like:
[2025-05-25 19:05:04] pcifront pci-0: Installing PCI frontend
[2025-05-25 19:05:04] xen:swiotlb_xen: Warning: only able to allocate 4 MB for software IO TLB
[2025-05-25 19:05:04] xen:swiotlb_xen: Lowering to 2MB
[2025-05-25 19:05:04] xen:swiotlb_xen: Lowering to 2MB
[2025-05-25 19:05:04] xen:swiotlb_xen: Lowering to 2MB
[2025-05-25 19:05:04] xen:swiotlb_xen: Failed to get contiguous memory for DMA from Xen!
[2025-05-25 19:05:04] You either: don't have the permissions, do not have enough free memory under 4GB, or the hypervisor memory is too fragmented! (rc:-12)
[2025-05-25 19:05:04] pcifront pci-0: Could not setup SWIOTLB!
[2025-05-25 19:05:04] pcifront pci-0: 12 Error setting up PCI Frontend
[2025-05-25 19:05:04] Invalid max_queues (4), will use default max: 1.
[2025-05-25 19:05:04] tun: Universal TUN/TAP device driver, 1.6
...
[2025-05-25 19:05:04] pcifront pci-0: backend going away!
... qemu is started and instructed to passthrough a first PCI device, retries several times, and after spitting a few errors in libxl-driver.log the user is notified of the problem:
2025-05-25 17:05:05.350+0000: libxl: libxl_qmp.c:1837:qmp_ev_parse_error_messages: Domain 24:Could not open '/sys/bus/pci/devices/0000:00:00.3/config': No such file or directory
2025-05-25 17:05:05.351+0000: libxl: libxl_pci.c:1275:pci_add_qmp_device_add_cb: Domain 24:Retrying PCI add 1
...
2025-05-25 17:05:14.950+0000: libxl: libxl_qmp.c:1837:qmp_ev_parse_error_messages: Domain 24:Could not open '/sys/bus/pci/devices/0000:00:00.3/config': No such file or directory
2025-05-25 17:05:14.950+0000: libxl: libxl_pci.c:1275:pci_add_qmp_device_add_cb: Domain 24:Retrying PCI add 10
2025-05-25 17:05:15.276+0000: libxl: libxl_pci.c:1864:device_pci_add_done: Domain 24:libxl__device_pci_add failed for PCI device 0:7:0.3 (rc -9)
2025-05-25 17:05:15.277+0000: libxl: libxl_pci.c:1864:device_pci_add_done: Domain 24:libxl__device_pci_add failed for PCI device 0:7:0.4 (rc -9)
2025-05-25 17:05:15.277+0000: libxl: libxl_create.c:2000:domcreate_attach_devices: Domain 24:unable to add pci devices
...
2025-05-25 17:05:35.432+0000: libxl: libxl_device.c:1507:libxl__wait_for_backend: Backend /local/domain/0/backend/pci/25/0 not ready
2025-05-25 17:05:35.534+0000: libxl: libxl_exec.c:120:libxl_report_child_exitstatus: killed fork (dying as expected) [138540] unexpectedly exited status zero
Here:
- the user has to wait to get a feedback for ~30sec according to log timestamps
- following the thread of events then, from a downstream error, is not completely trivial
The solution you'd like
Before attempting to launch qemu, check that pci frontend is indeed available. If not, fail early reporting this problem rather than letting the user see a downstream one.
The value to a user and who that user might be
Get more pertinent info faster.
Completion criteria checklist
That's ... complicated. QEMU is started by libxl (from our point of view, it's a single "domain create" call covering all of the above interaction. To make things worse(?), libxl handles PCI via hotplug - QEMU is started first without PCI devices and only then they gets added via QMP. BTW, the timeout you observe is due to retrying this hotplug. Upstream libxl uses hotplug also for attaching PCI devices to the stubdomain itself, which makes latter attachment to QEMU racy. Upstream workaround for that is retrying the QMP command. Our libxl is patched to boot stubdomain with PCI devs already attached, avoiding one racy point (but also breaking real PCI hotplug - which is why the patch as is isn't upstreamable), so technically we don't need that retry mechanism.