[PATCH v2 16/17] qemu: Clean up qemuDomainDefaultUSBControllerModel()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Just like qemuDomainDefaultSCSIControllerModel() before that,
split the function into an internal part and a trivial public
wrapper.

This allows us to rewrite the internal logic in the much more
compact and readable

  if (condition)
      return value;
  if (other_condition)
      return other_value;
  return default_value;

style, while still implementing the usual error handling
behavior and avoiding any ambiguity caused by
VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT having value -1.

The conversion is straightforward if messy, with one notable
exception: the piix3-uhci case, which serves as our fallback,
has to be moved from the top of the function to the bottom due
the change from the previous set-and-overwrite approach to the
new return-early approach.

The use of 'else if' is eliminated completely, comments are
updated and improved.

Signed-off-by: Andrea Bolognani <abologna@xxxxxxxxxx>
---
 src/qemu/qemu_domain.c | 143 +++++++++++++++++++++++++++++------------
 1 file changed, 101 insertions(+), 42 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6801a883f4..db09af496b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4157,62 +4157,121 @@ qemuDomainDefaultSCSIControllerModel(virDomainControllerModelSCSI *model,
 }
 
 
-static int
-qemuDomainDefaultUSBControllerModel(virDomainControllerModelUSB *model,
-                                    bool autoAdded,
-                                    const virDomainDef *def,
-                                    virQEMUCaps *qemuCaps,
-                                    unsigned int parseFlags)
+/* Internal. Use qemuDomainDefaultUSBControllerModel() instead */
+static virDomainControllerModelUSB
+qemuDomainDefaultUSBControllerModelInternal(bool autoAdded,
+                                            const virDomainDef *def,
+                                            virQEMUCaps *qemuCaps,
+                                            unsigned int parseFlags)
 {
-    /* Default USB controller is piix3-uhci if available. */
-    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI))
-        *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
+    bool abiUpdate = !!(parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE);
 
     if (ARCH_IS_S390(def->os.arch)) {
         /* No default model on s390x, one has to be provided
          * explicitly by the user */
-        *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE;
-    } else if (ARCH_IS_PPC64(def->os.arch)) {
-        /* To not break migration we need to set default USB controller
-         * for ppc64 to pci-ohci if we cannot change ABI of the VM.
-         * The nec-usb-xhci or qemu-xhci controller is used as default
-         * only for newly defined domains or devices. */
-        if ((parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE) &&
-            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) {
-            *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
-        } else if ((parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE) &&
-                   virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) {
-            *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
-        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI)) {
-            *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
-        } else {
-            /* Explicitly fallback to legacy USB controller for PPC64. */
-            *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
-        }
-    } else if (def->os.arch == VIR_ARCH_AARCH64) {
+        return VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE;
+    }
+
+    if (ARCH_IS_PPC64(def->os.arch)) {
+        /* Newly-defined guests should use USB3 if possible */
+        if (abiUpdate && virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
+            return VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
+        if (abiUpdate && virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
+            return VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+
+        /* To preserve backwards compatibility, existing guests need to
+         * use pci-ohci (USB2) instead */
+        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI))
+            return VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
+
+        /* If neither USB3 nor USB2 can be used, bail */
+        return VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
+    }
+
+    if (def->os.arch == VIR_ARCH_AARCH64) {
+        /* Prefer USB3 */
         if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
-            *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
-        else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
-            *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+            return VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
+        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
+            return VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+
+        /* If USB3 is unavailable, we should probably bail by
+         * returning VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT here
+         * instead of possibly falling back to piix3-uhci (USB1), but
+         * historically we haven't done that and starting now might
+         * cause backwards compatibility issues */
     }
 
     if (ARCH_IS_X86(def->os.arch)) {
         if (qemuDomainIsQ35(def) && autoAdded) {
-            /* Prefer adding a USB3 controller if supported, fall back
-             * to USB2 if there is no USB3 available, and if that's
-             * unavailable don't add anything.
-             */
+            /* Prefer USB3 */
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
-                *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
-            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
-                *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
-            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
-                *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
-            else
-                *model = VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
+                return VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
+                return VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+
+            /* Fall back to USB2 */
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
+                return VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
+
+            /* If no suitable device is available, simply avoid
+             * adding the controller.
+             *
+             * Note that this is only the case for the USB controller
+             * that gets automatically added for new guests, and only
+             * for the q35 machine type */
+            return VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
         }
     }
 
+    /* The default USB controller is piix3-uhci (USB1) if available.
+     * This choice is a fairly poor one, rooted primarily in historical
+     * reasons; thankfully, in most cases we will overwrite it with a
+     * much more reasonable value below */
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI))
+        return VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
+
+    return VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
+}
+
+
+/**
+ * qemuDomainDefaultUSBControllerModel:
+ * @model: return location
+ * @autoAdded: whether this controller is being automatically added
+ * @def: domain definition
+ * @cont: controller definition, or NULL
+ * @qemuCaps: QEMU capabilities, or NULL
+ * @parseFlags: parse flags
+ *
+ * Choose a reasonable model to use for a USB controller where a
+ * specific one hasn't been provided by the user.
+ *
+ * The choice is based on a number of factors, including the guest's
+ * architecture and machine type. @qemuCaps, if provided, might be
+ * taken into consideration too.
+ *
+ * @autoAdded should be true is this is a controller that libvirt is
+ * trying to automatically add on domain creation for the user's
+ * convenience: in that case, the function might decide that the best
+ * course of action is to not add the controller after all. This
+ * decision will be communicated to the caller by setting @model
+ * to VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT.
+ *
+ * Not being able to come up with a value is NOT considered a
+ * failure. It's up to the caller to decide how to handle that
+ * scenario.
+ *
+ * Returns: 0 on success, <0 on failure.
+ */
+static int
+qemuDomainDefaultUSBControllerModel(virDomainControllerModelUSB *model,
+                                    bool autoAdded,
+                                    const virDomainDef *def,
+                                    virQEMUCaps *qemuCaps,
+                                    unsigned int parseFlags)
+{
+    *model = qemuDomainDefaultUSBControllerModelInternal(autoAdded, def, qemuCaps, parseFlags);
     return 0;
 }
 
-- 
2.43.0
_______________________________________________
Devel mailing list -- devel@xxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux