(is_gpu: bool, plan: &LaunchPlan)
| 1442 | |
| 1443 | #[allow(clippy::result_large_err)] |
| 1444 | fn validate_launch_plan_backend(is_gpu: bool, plan: &LaunchPlan) -> Result<(), Status> { |
| 1445 | // NOTE: this guard exists because the non-GPU QEMU launch path |
| 1446 | // (PCI device transport, VFIO root port wiring) has not landed |
| 1447 | // yet. Until then, even though the resolver will happily promote |
| 1448 | // a plan to QEMU when an extension requires `PciPassthrough` or |
| 1449 | // `ExternalKernelImage`, the launch itself is blocked here so we |
| 1450 | // don't spawn a QEMU instance with no concrete device backing. |
| 1451 | // Remove this guard once the non-GPU QEMU launch path supports |
| 1452 | // emitting `pcie-root-port` + `vfio-pci` for arbitrary device |
| 1453 | // descriptors. |
| 1454 | if plan.backend == VmBackend::Qemu && !is_gpu { |
| 1455 | let offending_feature = plan |
| 1456 | .required_backend_features |
| 1457 | .iter() |
| 1458 | .find(|feature| feature.requires_qemu()) |
| 1459 | .map_or("(explicit QEMU backend requirement)", |feature| { |
| 1460 | feature.as_str() |
| 1461 | }); |
| 1462 | return Err(Status::failed_precondition(format!( |
| 1463 | "vm lifecycle extension required '{offending_feature}', which resolves to the QEMU backend, \ |
| 1464 | but non-GPU QEMU launch is not yet supported (pending PCI device transport)" |
| 1465 | ))); |
| 1466 | } |
| 1467 | if plan.backend != VmBackend::Qemu && is_gpu { |
| 1468 | return Err(Status::failed_precondition( |
| 1469 | "GPU sandbox launch requires the QEMU backend", |
| 1470 | )); |
| 1471 | } |
| 1472 | if plan.required_backends.contains(&VmBackend::Libkrun) |
| 1473 | && plan.required_backends.contains(&VmBackend::Qemu) |
| 1474 | { |
| 1475 | return Err(Status::failed_precondition( |
| 1476 | "VM lifecycle extensions requested conflicting VM backends", |
| 1477 | )); |
| 1478 | } |
| 1479 | if plan.required_backends.contains(&VmBackend::Libkrun) |
| 1480 | && plan.backend != VmBackend::Libkrun |
| 1481 | { |
| 1482 | return Err(Status::failed_precondition( |
| 1483 | "VM lifecycle extension requires the libkrun backend", |
| 1484 | )); |
| 1485 | } |
| 1486 | if plan.required_backends.contains(&VmBackend::Qemu) && plan.backend != VmBackend::Qemu { |
| 1487 | return Err(Status::failed_precondition( |
| 1488 | "VM lifecycle extension requires the QEMU backend", |
| 1489 | )); |
| 1490 | } |
| 1491 | if plan.backend != VmBackend::Qemu |
| 1492 | && let Some(feature) = plan |
| 1493 | .required_backend_features |
| 1494 | .iter() |
| 1495 | .find(|feature| feature.requires_qemu()) |
| 1496 | { |
| 1497 | return Err(Status::failed_precondition(format!( |
| 1498 | "VM backend feature '{}' requires a VM backend with PCI-style launch support", |
| 1499 | feature.as_str() |
| 1500 | ))); |
| 1501 | } |
nothing calls this directly
no test coverage detected