292 lines
9.8 KiB
Diff
292 lines
9.8 KiB
Diff
|
From 5237e9b27b8102c6f91015f33bab8e892c5fa82b 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 718533b..67ff000 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;
|
||
|
}
|
||
|
|