|
|
503330 |
From 96a7f7fa1953707e1eb9f0f638baf213507a5cb2 Mon Sep 17 00:00:00 2001
|
|
|
0a6408 |
From: Cole Robinson <crobinso@redhat.com>
|
|
|
0a6408 |
Date: Tue, 23 Sep 2014 11:35:57 -0400
|
|
|
0a6408 |
Subject: [PATCH] qemu_command: Split qemuBuildCpuArgStr
|
|
|
0a6408 |
|
|
|
0a6408 |
Move the CPU mode/model handling to its own function. This is just
|
|
|
0a6408 |
code movement and re-indentation.
|
|
|
0a6408 |
|
|
|
0a6408 |
(cherry picked from commit e1d872dc77c80d43036f928f83f560f2e9286148)
|
|
|
0a6408 |
---
|
|
|
0a6408 |
src/qemu/qemu_command.c | 226 ++++++++++++++++++++++++++----------------------
|
|
|
0a6408 |
1 file changed, 122 insertions(+), 104 deletions(-)
|
|
|
0a6408 |
|
|
|
0a6408 |
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
|
503330 |
index eb72451..db5ea35 100644
|
|
|
0a6408 |
--- a/src/qemu/qemu_command.c
|
|
|
0a6408 |
+++ b/src/qemu/qemu_command.c
|
|
|
503330 |
@@ -6140,139 +6140,162 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
|
|
|
0a6408 |
return NULL;
|
|
|
0a6408 |
}
|
|
|
0a6408 |
|
|
|
0a6408 |
-
|
|
|
0a6408 |
static int
|
|
|
0a6408 |
-qemuBuildCpuArgStr(virQEMUDriverPtr driver,
|
|
|
0a6408 |
- const virDomainDef *def,
|
|
|
0a6408 |
- const char *emulator,
|
|
|
0a6408 |
- virQEMUCapsPtr qemuCaps,
|
|
|
0a6408 |
- virArch hostarch,
|
|
|
0a6408 |
- char **opt,
|
|
|
0a6408 |
- bool *hasHwVirt,
|
|
|
0a6408 |
- bool migrating)
|
|
|
0a6408 |
+qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
|
|
|
0a6408 |
+ const virDomainDef *def,
|
|
|
0a6408 |
+ virBufferPtr buf,
|
|
|
0a6408 |
+ virQEMUCapsPtr qemuCaps,
|
|
|
0a6408 |
+ bool *hasHwVirt,
|
|
|
0a6408 |
+ bool migrating)
|
|
|
0a6408 |
{
|
|
|
0a6408 |
+ int ret = -1;
|
|
|
0a6408 |
+ size_t i;
|
|
|
0a6408 |
virCPUDefPtr host = NULL;
|
|
|
0a6408 |
virCPUDefPtr guest = NULL;
|
|
|
0a6408 |
virCPUDefPtr cpu = NULL;
|
|
|
0a6408 |
size_t ncpus = 0;
|
|
|
0a6408 |
char **cpus = NULL;
|
|
|
0a6408 |
- const char *default_model;
|
|
|
0a6408 |
virCPUDataPtr data = NULL;
|
|
|
0a6408 |
- bool have_cpu = false;
|
|
|
0a6408 |
char *compare_msg = NULL;
|
|
|
0a6408 |
- int ret = -1;
|
|
|
0a6408 |
- virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
0a6408 |
- size_t i;
|
|
|
0a6408 |
+ virCPUCompareResult cmp;
|
|
|
0a6408 |
+ const char *preferred;
|
|
|
0a6408 |
virCapsPtr caps = NULL;
|
|
|
0a6408 |
|
|
|
0a6408 |
- *hasHwVirt = false;
|
|
|
0a6408 |
-
|
|
|
0a6408 |
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
|
|
|
0a6408 |
goto cleanup;
|
|
|
0a6408 |
|
|
|
0a6408 |
host = caps->host.cpu;
|
|
|
0a6408 |
|
|
|
0a6408 |
- if (def->os.arch == VIR_ARCH_I686)
|
|
|
0a6408 |
- default_model = "qemu32";
|
|
|
0a6408 |
- else
|
|
|
0a6408 |
- default_model = "qemu64";
|
|
|
0a6408 |
+ if (!host ||
|
|
|
0a6408 |
+ !host->model ||
|
|
|
0a6408 |
+ (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
|
|
|
0a6408 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
0a6408 |
+ _("CPU specification not supported by hypervisor"));
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
+ }
|
|
|
0a6408 |
|
|
|
0a6408 |
- if (def->cpu &&
|
|
|
0a6408 |
- (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
|
|
|
0a6408 |
- virCPUCompareResult cmp;
|
|
|
0a6408 |
- const char *preferred;
|
|
|
0a6408 |
+ if (!(cpu = virCPUDefCopy(def->cpu)))
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
+
|
|
|
0a6408 |
+ if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
|
|
|
0a6408 |
+ !migrating &&
|
|
|
0a6408 |
+ cpuUpdate(cpu, host) < 0)
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
|
|
|
0a6408 |
- if (!host ||
|
|
|
0a6408 |
- !host->model ||
|
|
|
0a6408 |
- (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
|
|
|
0a6408 |
+ cmp = cpuGuestData(host, cpu, &data, &compare_msg);
|
|
|
0a6408 |
+ switch (cmp) {
|
|
|
0a6408 |
+ case VIR_CPU_COMPARE_INCOMPATIBLE:
|
|
|
0a6408 |
+ if (compare_msg) {
|
|
|
0a6408 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
0a6408 |
+ _("guest and host CPU are not compatible: %s"),
|
|
|
0a6408 |
+ compare_msg);
|
|
|
0a6408 |
+ } else {
|
|
|
0a6408 |
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
0a6408 |
- _("CPU specification not supported by hypervisor"));
|
|
|
0a6408 |
- goto cleanup;
|
|
|
0a6408 |
+ _("guest CPU is not compatible with host CPU"));
|
|
|
0a6408 |
}
|
|
|
0a6408 |
+ /* fall through */
|
|
|
0a6408 |
+ case VIR_CPU_COMPARE_ERROR:
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
|
|
|
0a6408 |
- if (!(cpu = virCPUDefCopy(def->cpu)))
|
|
|
0a6408 |
+ default:
|
|
|
0a6408 |
+ break;
|
|
|
0a6408 |
+ }
|
|
|
0a6408 |
+
|
|
|
0a6408 |
+ /* Only 'svm' requires --enable-nesting. The nested
|
|
|
0a6408 |
+ * 'vmx' patches now simply hook off the CPU features
|
|
|
0a6408 |
+ */
|
|
|
0a6408 |
+ if (def->os.arch == VIR_ARCH_X86_64 ||
|
|
|
0a6408 |
+ def->os.arch == VIR_ARCH_I686) {
|
|
|
0a6408 |
+ int hasSVM = cpuHasFeature(data, "svm");
|
|
|
0a6408 |
+ if (hasSVM < 0)
|
|
|
0a6408 |
goto cleanup;
|
|
|
0a6408 |
+ *hasHwVirt = hasSVM > 0 ? true : false;
|
|
|
0a6408 |
+ }
|
|
|
0a6408 |
|
|
|
0a6408 |
- if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
|
|
|
0a6408 |
- !migrating &&
|
|
|
0a6408 |
- cpuUpdate(cpu, host) < 0)
|
|
|
0a6408 |
+ if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
|
|
|
0a6408 |
+ const char *mode = virCPUModeTypeToString(cpu->mode);
|
|
|
0a6408 |
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
|
|
|
0a6408 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
0a6408 |
+ _("CPU mode '%s' is not supported by QEMU"
|
|
|
0a6408 |
+ " binary"), mode);
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
+ }
|
|
|
0a6408 |
+ if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
|
|
|
0a6408 |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
0a6408 |
+ _("CPU mode '%s' is only supported with kvm"),
|
|
|
0a6408 |
+ mode);
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
+ }
|
|
|
0a6408 |
+ virBufferAddLit(buf, "host");
|
|
|
0a6408 |
+ } else {
|
|
|
0a6408 |
+ if (VIR_ALLOC(guest) < 0)
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
+ if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
|
|
|
0a6408 |
goto cleanup;
|
|
|
0a6408 |
|
|
|
0a6408 |
- cmp = cpuGuestData(host, cpu, &data, &compare_msg);
|
|
|
0a6408 |
- switch (cmp) {
|
|
|
0a6408 |
- case VIR_CPU_COMPARE_INCOMPATIBLE:
|
|
|
0a6408 |
- if (compare_msg) {
|
|
|
0a6408 |
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
0a6408 |
- _("guest and host CPU are not compatible: %s"),
|
|
|
0a6408 |
- compare_msg);
|
|
|
0a6408 |
- } else {
|
|
|
0a6408 |
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
0a6408 |
- _("guest CPU is not compatible with host CPU"));
|
|
|
0a6408 |
- }
|
|
|
0a6408 |
- /* fall through */
|
|
|
0a6408 |
- case VIR_CPU_COMPARE_ERROR:
|
|
|
0a6408 |
+ guest->arch = host->arch;
|
|
|
0a6408 |
+ if (cpu->match == VIR_CPU_MATCH_MINIMUM)
|
|
|
0a6408 |
+ preferred = host->model;
|
|
|
0a6408 |
+ else
|
|
|
0a6408 |
+ preferred = cpu->model;
|
|
|
0a6408 |
+
|
|
|
0a6408 |
+ guest->type = VIR_CPU_TYPE_GUEST;
|
|
|
0a6408 |
+ guest->fallback = cpu->fallback;
|
|
|
0a6408 |
+ if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
|
|
|
0a6408 |
goto cleanup;
|
|
|
0a6408 |
|
|
|
0a6408 |
- default:
|
|
|
0a6408 |
- break;
|
|
|
0a6408 |
- }
|
|
|
0a6408 |
+ virBufferAdd(buf, guest->model, -1);
|
|
|
0a6408 |
+ if (guest->vendor_id)
|
|
|
0a6408 |
+ virBufferAsprintf(buf, ",vendor=%s", guest->vendor_id);
|
|
|
0a6408 |
+ for (i = 0; i < guest->nfeatures; i++) {
|
|
|
0a6408 |
+ char sign;
|
|
|
0a6408 |
+ if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
|
|
|
0a6408 |
+ sign = '-';
|
|
|
0a6408 |
+ else
|
|
|
0a6408 |
+ sign = '+';
|
|
|
0a6408 |
|
|
|
0a6408 |
- /* Only 'svm' requires --enable-nesting. The nested
|
|
|
0a6408 |
- * 'vmx' patches now simply hook off the CPU features
|
|
|
0a6408 |
- */
|
|
|
0a6408 |
- if (def->os.arch == VIR_ARCH_X86_64 ||
|
|
|
0a6408 |
- def->os.arch == VIR_ARCH_I686) {
|
|
|
0a6408 |
- int hasSVM = cpuHasFeature(data, "svm");
|
|
|
0a6408 |
- if (hasSVM < 0)
|
|
|
0a6408 |
- goto cleanup;
|
|
|
0a6408 |
- *hasHwVirt = hasSVM > 0 ? true : false;
|
|
|
0a6408 |
+ virBufferAsprintf(buf, ",%c%s", sign, guest->features[i].name);
|
|
|
0a6408 |
}
|
|
|
0a6408 |
+ }
|
|
|
0a6408 |
|
|
|
0a6408 |
- if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
|
|
|
0a6408 |
- const char *mode = virCPUModeTypeToString(cpu->mode);
|
|
|
0a6408 |
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
|
|
|
0a6408 |
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
0a6408 |
- _("CPU mode '%s' is not supported by QEMU"
|
|
|
0a6408 |
- " binary"), mode);
|
|
|
0a6408 |
- goto cleanup;
|
|
|
0a6408 |
- }
|
|
|
0a6408 |
- if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
|
|
|
0a6408 |
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
0a6408 |
- _("CPU mode '%s' is only supported with kvm"),
|
|
|
0a6408 |
- mode);
|
|
|
0a6408 |
- goto cleanup;
|
|
|
0a6408 |
- }
|
|
|
0a6408 |
- virBufferAddLit(&buf, "host");
|
|
|
0a6408 |
- } else {
|
|
|
0a6408 |
- if (VIR_ALLOC(guest) < 0)
|
|
|
0a6408 |
- goto cleanup;
|
|
|
0a6408 |
- if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
|
|
|
0a6408 |
- goto cleanup;
|
|
|
0a6408 |
+ ret = 0;
|
|
|
0a6408 |
+cleanup:
|
|
|
0a6408 |
+ virObjectUnref(caps);
|
|
|
0a6408 |
+ VIR_FREE(compare_msg);
|
|
|
0a6408 |
+ cpuDataFree(data);
|
|
|
0a6408 |
+ virCPUDefFree(guest);
|
|
|
0a6408 |
+ virCPUDefFree(cpu);
|
|
|
0a6408 |
+ return ret;
|
|
|
0a6408 |
+}
|
|
|
0a6408 |
|
|
|
0a6408 |
- guest->arch = host->arch;
|
|
|
0a6408 |
- if (cpu->match == VIR_CPU_MATCH_MINIMUM)
|
|
|
0a6408 |
- preferred = host->model;
|
|
|
0a6408 |
- else
|
|
|
0a6408 |
- preferred = cpu->model;
|
|
|
0a6408 |
+static int
|
|
|
0a6408 |
+qemuBuildCpuArgStr(virQEMUDriverPtr driver,
|
|
|
0a6408 |
+ const virDomainDef *def,
|
|
|
0a6408 |
+ const char *emulator,
|
|
|
0a6408 |
+ virQEMUCapsPtr qemuCaps,
|
|
|
0a6408 |
+ virArch hostarch,
|
|
|
0a6408 |
+ char **opt,
|
|
|
0a6408 |
+ bool *hasHwVirt,
|
|
|
0a6408 |
+ bool migrating)
|
|
|
0a6408 |
+{
|
|
|
0a6408 |
+ const char *default_model;
|
|
|
0a6408 |
+ bool have_cpu = false;
|
|
|
0a6408 |
+ int ret = -1;
|
|
|
0a6408 |
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
0a6408 |
+ size_t i;
|
|
|
0a6408 |
|
|
|
0a6408 |
- guest->type = VIR_CPU_TYPE_GUEST;
|
|
|
0a6408 |
- guest->fallback = cpu->fallback;
|
|
|
0a6408 |
- if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
|
|
|
0a6408 |
- goto cleanup;
|
|
|
0a6408 |
+ *hasHwVirt = false;
|
|
|
0a6408 |
|
|
|
0a6408 |
- virBufferAdd(&buf, guest->model, -1);
|
|
|
0a6408 |
- if (guest->vendor_id)
|
|
|
0a6408 |
- virBufferAsprintf(&buf, ",vendor=%s", guest->vendor_id);
|
|
|
0a6408 |
- for (i = 0; i < guest->nfeatures; i++) {
|
|
|
0a6408 |
- char sign;
|
|
|
0a6408 |
- if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
|
|
|
0a6408 |
- sign = '-';
|
|
|
0a6408 |
- else
|
|
|
0a6408 |
- sign = '+';
|
|
|
0a6408 |
+ if (def->os.arch == VIR_ARCH_I686)
|
|
|
0a6408 |
+ default_model = "qemu32";
|
|
|
0a6408 |
+ else
|
|
|
0a6408 |
+ default_model = "qemu64";
|
|
|
0a6408 |
|
|
|
0a6408 |
- virBufferAsprintf(&buf, ",%c%s", sign, guest->features[i].name);
|
|
|
0a6408 |
- }
|
|
|
0a6408 |
- }
|
|
|
0a6408 |
+ if (def->cpu &&
|
|
|
0a6408 |
+ (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
|
|
|
0a6408 |
+ if (qemuBuildCpuModelArgStr(driver, def, &buf, qemuCaps,
|
|
|
0a6408 |
+ hasHwVirt, migrating) < 0)
|
|
|
0a6408 |
+ goto cleanup;
|
|
|
0a6408 |
have_cpu = true;
|
|
|
0a6408 |
} else {
|
|
|
0a6408 |
/*
|
|
|
503330 |
@@ -6398,11 +6421,6 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
|
|
|
0a6408 |
ret = 0;
|
|
|
0a6408 |
|
|
|
0a6408 |
cleanup:
|
|
|
0a6408 |
- VIR_FREE(compare_msg);
|
|
|
0a6408 |
- cpuDataFree(data);
|
|
|
0a6408 |
- virCPUDefFree(guest);
|
|
|
0a6408 |
- virCPUDefFree(cpu);
|
|
|
0a6408 |
- virObjectUnref(caps);
|
|
|
0a6408 |
return ret;
|
|
|
0a6408 |
}
|
|
|
0a6408 |
|