Blob Blame History Raw
From e543e857120b8a1b352bf34fd8a983e95ea70487 Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Tue, 23 Sep 2014 11:35:57 -0400
Subject: [PATCH] qemu_command: Split qemuBuildCpuArgStr

Move the CPU mode/model handling to its own function. This is just
code movement and re-indentation.

(cherry picked from commit e1d872dc77c80d43036f928f83f560f2e9286148)
---
 src/qemu/qemu_command.c | 226 ++++++++++++++++++++++++++----------------------
 1 file changed, 122 insertions(+), 104 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2184caa..96ba081 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6052,139 +6052,162 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
     return NULL;
 }
 
-
 static int
-qemuBuildCpuArgStr(virQEMUDriverPtr driver,
-                   const virDomainDef *def,
-                   const char *emulator,
-                   virQEMUCapsPtr qemuCaps,
-                   virArch hostarch,
-                   char **opt,
-                   bool *hasHwVirt,
-                   bool migrating)
+qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
+                        const virDomainDef *def,
+                        virBufferPtr buf,
+                        virQEMUCapsPtr qemuCaps,
+                        bool *hasHwVirt,
+                        bool migrating)
 {
+    int ret = -1;
+    size_t i;
     virCPUDefPtr host = NULL;
     virCPUDefPtr guest = NULL;
     virCPUDefPtr cpu = NULL;
     size_t ncpus = 0;
     char **cpus = NULL;
-    const char *default_model;
     virCPUDataPtr data = NULL;
-    bool have_cpu = false;
     char *compare_msg = NULL;
-    int ret = -1;
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    size_t i;
+    virCPUCompareResult cmp;
+    const char *preferred;
     virCapsPtr caps = NULL;
 
-    *hasHwVirt = false;
-
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
 
     host = caps->host.cpu;
 
-    if (def->os.arch == VIR_ARCH_I686)
-        default_model = "qemu32";
-    else
-        default_model = "qemu64";
+    if (!host ||
+        !host->model ||
+        (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("CPU specification not supported by hypervisor"));
+        goto cleanup;
+    }
 
-    if (def->cpu &&
-        (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
-        virCPUCompareResult cmp;
-        const char *preferred;
+    if (!(cpu = virCPUDefCopy(def->cpu)))
+        goto cleanup;
+
+    if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
+        !migrating &&
+        cpuUpdate(cpu, host) < 0)
+        goto cleanup;
 
-        if (!host ||
-            !host->model ||
-            (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
+    cmp = cpuGuestData(host, cpu, &data, &compare_msg);
+    switch (cmp) {
+    case VIR_CPU_COMPARE_INCOMPATIBLE:
+        if (compare_msg) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("guest and host CPU are not compatible: %s"),
+                           compare_msg);
+        } else {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("CPU specification not supported by hypervisor"));
-            goto cleanup;
+                           _("guest CPU is not compatible with host CPU"));
         }
+        /* fall through */
+    case VIR_CPU_COMPARE_ERROR:
+        goto cleanup;
 
-        if (!(cpu = virCPUDefCopy(def->cpu)))
+    default:
+        break;
+    }
+
+    /* Only 'svm' requires --enable-nesting. The nested
+     * 'vmx' patches now simply hook off the CPU features
+     */
+    if (def->os.arch == VIR_ARCH_X86_64 ||
+        def->os.arch == VIR_ARCH_I686) {
+        int hasSVM = cpuHasFeature(data, "svm");
+        if (hasSVM < 0)
             goto cleanup;
+        *hasHwVirt = hasSVM > 0 ? true : false;
+    }
 
-        if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
-            !migrating &&
-            cpuUpdate(cpu, host) < 0)
+    if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
+        const char *mode = virCPUModeTypeToString(cpu->mode);
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("CPU mode '%s' is not supported by QEMU"
+                             " binary"), mode);
+            goto cleanup;
+        }
+        if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("CPU mode '%s' is only supported with kvm"),
+                           mode);
+            goto cleanup;
+        }
+        virBufferAddLit(buf, "host");
+    } else {
+        if (VIR_ALLOC(guest) < 0)
+            goto cleanup;
+        if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
             goto cleanup;
 
-        cmp = cpuGuestData(host, cpu, &data, &compare_msg);
-        switch (cmp) {
-        case VIR_CPU_COMPARE_INCOMPATIBLE:
-            if (compare_msg) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("guest and host CPU are not compatible: %s"),
-                               compare_msg);
-            } else {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("guest CPU is not compatible with host CPU"));
-            }
-            /* fall through */
-        case VIR_CPU_COMPARE_ERROR:
+        guest->arch = host->arch;
+        if (cpu->match == VIR_CPU_MATCH_MINIMUM)
+            preferred = host->model;
+        else
+            preferred = cpu->model;
+
+        guest->type = VIR_CPU_TYPE_GUEST;
+        guest->fallback = cpu->fallback;
+        if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
             goto cleanup;
 
-        default:
-            break;
-        }
+        virBufferAdd(buf, guest->model, -1);
+        if (guest->vendor_id)
+            virBufferAsprintf(buf, ",vendor=%s", guest->vendor_id);
+        for (i = 0; i < guest->nfeatures; i++) {
+            char sign;
+            if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
+                sign = '-';
+            else
+                sign = '+';
 
-        /* Only 'svm' requires --enable-nesting. The nested
-         * 'vmx' patches now simply hook off the CPU features
-         */
-        if (def->os.arch == VIR_ARCH_X86_64 ||
-            def->os.arch == VIR_ARCH_I686) {
-            int hasSVM = cpuHasFeature(data, "svm");
-            if (hasSVM < 0)
-                goto cleanup;
-            *hasHwVirt = hasSVM > 0 ? true : false;
+            virBufferAsprintf(buf, ",%c%s", sign, guest->features[i].name);
         }
+    }
 
-        if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
-            const char *mode = virCPUModeTypeToString(cpu->mode);
-            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("CPU mode '%s' is not supported by QEMU"
-                                 " binary"), mode);
-                goto cleanup;
-            }
-            if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("CPU mode '%s' is only supported with kvm"),
-                               mode);
-                goto cleanup;
-            }
-            virBufferAddLit(&buf, "host");
-        } else {
-            if (VIR_ALLOC(guest) < 0)
-                goto cleanup;
-            if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
-                goto cleanup;
+    ret = 0;
+cleanup:
+    virObjectUnref(caps);
+    VIR_FREE(compare_msg);
+    cpuDataFree(data);
+    virCPUDefFree(guest);
+    virCPUDefFree(cpu);
+    return ret;
+}
 
-            guest->arch = host->arch;
-            if (cpu->match == VIR_CPU_MATCH_MINIMUM)
-                preferred = host->model;
-            else
-                preferred = cpu->model;
+static int
+qemuBuildCpuArgStr(virQEMUDriverPtr driver,
+                   const virDomainDef *def,
+                   const char *emulator,
+                   virQEMUCapsPtr qemuCaps,
+                   virArch hostarch,
+                   char **opt,
+                   bool *hasHwVirt,
+                   bool migrating)
+{
+    const char *default_model;
+    bool have_cpu = false;
+    int ret = -1;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    size_t i;
 
-            guest->type = VIR_CPU_TYPE_GUEST;
-            guest->fallback = cpu->fallback;
-            if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
-                goto cleanup;
+    *hasHwVirt = false;
 
-            virBufferAdd(&buf, guest->model, -1);
-            if (guest->vendor_id)
-                virBufferAsprintf(&buf, ",vendor=%s", guest->vendor_id);
-            for (i = 0; i < guest->nfeatures; i++) {
-                char sign;
-                if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
-                    sign = '-';
-                else
-                    sign = '+';
+    if (def->os.arch == VIR_ARCH_I686)
+        default_model = "qemu32";
+    else
+        default_model = "qemu64";
 
-                virBufferAsprintf(&buf, ",%c%s", sign, guest->features[i].name);
-            }
-        }
+    if (def->cpu &&
+        (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
+        if (qemuBuildCpuModelArgStr(driver, def, &buf, qemuCaps,
+                                    hasHwVirt, migrating) < 0)
+            goto cleanup;
         have_cpu = true;
     } else {
         /*
@@ -6309,11 +6332,6 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
     ret = 0;
 
  cleanup:
-    VIR_FREE(compare_msg);
-    cpuDataFree(data);
-    virCPUDefFree(guest);
-    virCPUDefFree(cpu);
-    virObjectUnref(caps);
     return ret;
 }