[libvirt] [PATCH v2 06/15] qemu: Defer capability check to command line generation time

Andrea Bolognani abologna at redhat.com
Fri Feb 16 16:28:03 UTC 2018


Validate time is a bit too early to check whether the required
capabilities are available, since the QEMU binary might have
been updated or replaced by the time we are asked to run the
guest.

Move capability checks (back) to qemuBuildControllerDevStr()
and get rid of a lot of redundancy in the process.

Signed-off-by: Andrea Bolognani <abologna at redhat.com>
---
 src/qemu/qemu_command.c | 50 +++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.c  | 80 ++-----------------------------------------------
 2 files changed, 52 insertions(+), 78 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a44a1b2d2..a957132bd 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2595,6 +2595,35 @@ qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def,
     return 0;
 }
 
+static int
+virDomainControllerPCIModelNameToQEMUCaps(int modelName)
+{
+    switch ((virDomainControllerPCIModelName) modelName) {
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE:
+        return QEMU_CAPS_DEVICE_PCI_BRIDGE;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE:
+        return QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420:
+        return QEMU_CAPS_DEVICE_IOH3420;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM:
+        return QEMU_CAPS_DEVICE_X3130_UPSTREAM;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM:
+        return QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB:
+        return QEMU_CAPS_DEVICE_PXB;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE:
+        return QEMU_CAPS_DEVICE_PXB_PCIE;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT:
+        return QEMU_CAPS_DEVICE_PCIE_ROOT_PORT;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE:
+        return QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE;
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE:
+    case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST:
+        break;
+    }
+    return -1;
+}
+
 
 /**
  * qemuBuildControllerDevStr:
@@ -2727,6 +2756,7 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
     case VIR_DOMAIN_CONTROLLER_TYPE_PCI: {
         const virDomainPCIControllerOpts *pciopts = &def->opts.pciopts;
         const char *modelName = virDomainControllerPCIModelNameTypeToString(pciopts->modelName);
+        int cap = virDomainControllerPCIModelNameToQEMUCaps(pciopts->modelName);
 
         /* Skip the implicit PHB for pSeries guests */
         if (def->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT &&
@@ -2742,6 +2772,18 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
                            pciopts->modelName);
             return -1;
         }
+        if (cap < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Unknown QEMU device for '%s' controller"),
+                           modelName);
+            return -1;
+        }
+        if (!virQEMUCapsGet(qemuCaps, cap)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("The '%s' device is not supported by this QEMU binary"),
+                           modelName);
+            return -1;
+        }
 
         switch ((virDomainControllerModelPCI) def->model) {
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
@@ -2770,6 +2812,14 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
                               pciopts->chassis, def->info.alias);
             break;
         case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+            if (pciopts->numaNode != -1 &&
+                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("the spapr-pci-host-bridge controller doesn't "
+                                 "support numa_node in this QEMU binary"));
+                return -1;
+            }
+
             virBufferAsprintf(&buf, "%s,index=%d,id=%s",
                               modelName, pciopts->targetIndex,
                               def->info.alias);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2bc0259ea..2fbae695a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4244,8 +4244,7 @@ qemuDomainDeviceDefValidateControllerSCSI(const virDomainControllerDef *controll
 
 static int
 qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controller,
-                                         const virDomainDef *def,
-                                         virQEMUCapsPtr qemuCaps)
+                                         const virDomainDef *def)
 {
     virDomainControllerModelPCI model = controller->model;
     const virDomainPCIControllerOpts *pciopts;
@@ -4322,13 +4321,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
             return -1;
         }
 
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the pci-bridge controller is not supported "
-                             "in this QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS:
@@ -4346,13 +4338,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
             return -1;
         }
 
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the pxb controller is not supported in this "
-                             "QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
@@ -4364,13 +4349,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
             return -1;
         }
 
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the dmi-to-pci-bridge (i82801b11-bridge) "
-                             "controller is not supported in this QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
@@ -4389,22 +4367,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
             return -1;
         }
 
-        if ((pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420) &&
-            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IOH3420)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the pcie-root-port (ioh3420) controller "
-                             "is not supported in this QEMU binary"));
-            return -1;
-        }
-
-        if ((pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT) &&
-            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCIE_ROOT_PORT)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the pcie-root-port (pcie-root-port) controller "
-                             "is not supported in this QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
@@ -4416,13 +4378,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
             return -1;
         }
 
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_X3130_UPSTREAM)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the pcie-switch-upstream-port (x3130-upstream) "
-                             "controller is not supported in this QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
@@ -4441,14 +4396,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
             return -1;
         }
 
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("The pcie-switch-downstream-port "
-                             "(xio3130-downstream) controller is not "
-                             "supported in this QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS:
@@ -4466,13 +4413,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
              return -1;
         }
 
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PXB_PCIE)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the pxb-pcie controller is not supported "
-                             "in this QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
@@ -4494,21 +4434,6 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *controlle
             return -1;
         }
 
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the spapr-pci-host-bridge controller is not "
-                             "supported in this QEMU binary"));
-            return -1;
-        }
-
-        if (pciopts->numaNode != -1 &&
-            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("the spapr-pci-host-bridge controller doesn't "
-                             "support numa_node in this QEMU binary"));
-            return -1;
-        }
-
         break;
 
     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
@@ -4566,8 +4491,7 @@ qemuDomainDeviceDefValidateController(const virDomainControllerDef *controller,
         break;
 
     case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
-        ret = qemuDomainDeviceDefValidateControllerPCI(controller, def,
-                                                       qemuCaps);
+        ret = qemuDomainDeviceDefValidateControllerPCI(controller, def);
         break;
 
     case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
-- 
2.14.3




More information about the libvir-list mailing list