提交 3bc6dda6 编写于 作者: C Cole Robinson

qemu_command: Split qemuBuildCpuArgStr

Move the CPU mode/model handling to its own function. This is just
code movement and re-indentation.
上级 9cf6dd00
...@@ -6140,139 +6140,162 @@ qemuBuildClockArgStr(virDomainClockDefPtr def) ...@@ -6140,139 +6140,162 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
return NULL; return NULL;
} }
static int static int
qemuBuildCpuArgStr(virQEMUDriverPtr driver, qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
const virDomainDef *def, const virDomainDef *def,
const char *emulator, virBufferPtr buf,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,
virArch hostarch, bool *hasHwVirt,
char **opt, bool migrating)
bool *hasHwVirt,
bool migrating)
{ {
int ret = -1;
size_t i;
virCPUDefPtr host = NULL; virCPUDefPtr host = NULL;
virCPUDefPtr guest = NULL; virCPUDefPtr guest = NULL;
virCPUDefPtr cpu = NULL; virCPUDefPtr cpu = NULL;
size_t ncpus = 0; size_t ncpus = 0;
char **cpus = NULL; char **cpus = NULL;
const char *default_model;
virCPUDataPtr data = NULL; virCPUDataPtr data = NULL;
bool have_cpu = false;
char *compare_msg = NULL; char *compare_msg = NULL;
int ret = -1; virCPUCompareResult cmp;
virBuffer buf = VIR_BUFFER_INITIALIZER; const char *preferred;
size_t i;
virCapsPtr caps = NULL; virCapsPtr caps = NULL;
*hasHwVirt = false;
if (!(caps = virQEMUDriverGetCapabilities(driver, false))) if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
goto cleanup; goto cleanup;
host = caps->host.cpu; host = caps->host.cpu;
if (def->os.arch == VIR_ARCH_I686) if (!host ||
default_model = "qemu32"; !host->model ||
else (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
default_model = "qemu64"; virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("CPU specification not supported by hypervisor"));
goto cleanup;
}
if (def->cpu && if (!(cpu = virCPUDefCopy(def->cpu)))
(def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) { goto cleanup;
virCPUCompareResult cmp;
const char *preferred; if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
!migrating &&
cpuUpdate(cpu, host) < 0)
goto cleanup;
if (!host || cmp = cpuGuestData(host, cpu, &data, &compare_msg);
!host->model || switch (cmp) {
(ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) { 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", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("CPU specification not supported by hypervisor")); _("guest CPU is not compatible with host CPU"));
goto cleanup;
} }
/* 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; goto cleanup;
*hasHwVirt = hasSVM > 0 ? true : false;
}
if (cpu->mode != VIR_CPU_MODE_CUSTOM && if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
!migrating && const char *mode = virCPUModeTypeToString(cpu->mode);
cpuUpdate(cpu, host) < 0) 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; goto cleanup;
cmp = cpuGuestData(host, cpu, &data, &compare_msg); guest->arch = host->arch;
switch (cmp) { if (cpu->match == VIR_CPU_MATCH_MINIMUM)
case VIR_CPU_COMPARE_INCOMPATIBLE: preferred = host->model;
if (compare_msg) { else
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, preferred = cpu->model;
_("guest and host CPU are not compatible: %s"),
compare_msg); guest->type = VIR_CPU_TYPE_GUEST;
} else { guest->fallback = cpu->fallback;
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
_("guest CPU is not compatible with host CPU"));
}
/* fall through */
case VIR_CPU_COMPARE_ERROR:
goto cleanup; goto cleanup;
default: virBufferAdd(buf, guest->model, -1);
break; 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 virBufferAsprintf(buf, ",%c%s", sign, guest->features[i].name);
* '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_HOST_PASSTHROUGH) { ret = 0;
const char *mode = virCPUModeTypeToString(cpu->mode); cleanup:
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) { virObjectUnref(caps);
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, VIR_FREE(compare_msg);
_("CPU mode '%s' is not supported by QEMU" cpuDataFree(data);
" binary"), mode); virCPUDefFree(guest);
goto cleanup; virCPUDefFree(cpu);
} return ret;
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;
guest->arch = host->arch; static int
if (cpu->match == VIR_CPU_MATCH_MINIMUM) qemuBuildCpuArgStr(virQEMUDriverPtr driver,
preferred = host->model; const virDomainDef *def,
else const char *emulator,
preferred = cpu->model; 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; *hasHwVirt = false;
guest->fallback = cpu->fallback;
if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
goto cleanup;
virBufferAdd(&buf, guest->model, -1); if (def->os.arch == VIR_ARCH_I686)
if (guest->vendor_id) default_model = "qemu32";
virBufferAsprintf(&buf, ",vendor=%s", guest->vendor_id); else
for (i = 0; i < guest->nfeatures; i++) { default_model = "qemu64";
char sign;
if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
sign = '-';
else
sign = '+';
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; have_cpu = true;
} else { } else {
/* /*
...@@ -6398,11 +6421,6 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver, ...@@ -6398,11 +6421,6 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
VIR_FREE(compare_msg);
cpuDataFree(data);
virCPUDefFree(guest);
virCPUDefFree(cpu);
virObjectUnref(caps);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册