Reorganize the module to put all the -machine argument processing code together at the top to form a logical order of processing for qemuBuildCommandLine working top down in the module. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/qemu/qemu_command.c | 464 ++++++++++++++++++++++++------------------------ 1 file changed, 235 insertions(+), 229 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 36fe110..ede651a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -149,6 +149,240 @@ VIR_ENUM_IMPL(qemuNumaPolicy, VIR_DOMAIN_NUMATUNE_MEM_LAST, "preferred", "interleave"); + +/** Start -machine arguments */ +static int +qemuBuildObsoleteAccelArg(virCommandPtr cmd, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + bool disableKVM = false; + bool enableKVM = false; + + switch (def->virtType) { + case VIR_DOMAIN_VIRT_QEMU: + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) + disableKVM = true; + break; + + case VIR_DOMAIN_VIRT_KQEMU: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("the QEMU binary does not support kqemu")); + break; + + case VIR_DOMAIN_VIRT_KVM: + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) { + enableKVM = true; + } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("the QEMU binary does not support kvm")); + return -1; + } + break; + + case VIR_DOMAIN_VIRT_XEN: + /* XXX better check for xenner */ + break; + + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("the QEMU binary does not support %s"), + virDomainVirtTypeToString(def->virtType)); + return -1; + } + + if (disableKVM) + virCommandAddArg(cmd, "-no-kvm"); + if (enableKVM) + virCommandAddArg(cmd, "-enable-kvm"); + + return 0; +} + + +static bool +qemuAppendKeyWrapMachineParm(virBuffer *buf, virQEMUCapsPtr qemuCaps, + int flag, const char *pname, int pstate) +{ + if (pstate != VIR_TRISTATE_SWITCH_ABSENT) { + if (!virQEMUCapsGet(qemuCaps, flag)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s is not available with this QEMU binary"), + pname); + return false; + } + + virBufferAsprintf(buf, ",%s=%s", pname, + virTristateSwitchTypeToString(pstate)); + } + + return true; +} + + +static bool +qemuAppendKeyWrapMachineParms(virBuffer *buf, virQEMUCapsPtr qemuCaps, + const virDomainKeyWrapDef *keywrap) +{ + if (!qemuAppendKeyWrapMachineParm(buf, qemuCaps, QEMU_CAPS_AES_KEY_WRAP, + "aes-key-wrap", keywrap->aes)) + return false; + + if (!qemuAppendKeyWrapMachineParm(buf, qemuCaps, QEMU_CAPS_DEA_KEY_WRAP, + "dea-key-wrap", keywrap->dea)) + return false; + + return true; +} + + +static int +qemuBuildMachineCommandLine(virCommandPtr cmd, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + bool obsoleteAccel = false; + + /* This should *never* be NULL, since we always provide + * a machine in the capabilities data for QEMU. So this + * check is just here as a safety in case the unexpected + * happens */ + if (!def->os.machine) + return 0; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_OPT)) { + /* if no parameter to the machine type is needed, we still use + * '-M' to keep the most of the compatibility with older versions. + */ + virCommandAddArgList(cmd, "-M", def->os.machine, NULL); + if (def->mem.dump_core) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("dump-guest-core is not available " + "with this QEMU binary")); + return -1; + } + + if (def->mem.nosharepages) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disable shared memory is not available " + "with this QEMU binary")); + return -1; + } + + obsoleteAccel = true; + + if (def->keywrap) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("key wrap support is not available " + "with this QEMU binary")); + return -1; + } + } else { + virBuffer buf = VIR_BUFFER_INITIALIZER; + virTristateSwitch vmport = def->features[VIR_DOMAIN_FEATURE_VMPORT]; + + virCommandAddArg(cmd, "-machine"); + virBufferAdd(&buf, def->os.machine, -1); + + if (def->virtType == VIR_DOMAIN_VIRT_QEMU) + virBufferAddLit(&buf, ",accel=tcg"); + else if (def->virtType == VIR_DOMAIN_VIRT_KVM) + virBufferAddLit(&buf, ",accel=kvm"); + else + obsoleteAccel = true; + + /* To avoid the collision of creating USB controllers when calling + * machine->init in QEMU, it needs to set usb=off + */ + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT)) + virBufferAddLit(&buf, ",usb=off"); + + if (vmport) { + if (!virQEMUCapsSupportsVmport(qemuCaps, def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("vmport is not available " + "with this QEMU binary")); + virBufferFreeAndReset(&buf); + return -1; + } + + virBufferAsprintf(&buf, ",vmport=%s", + virTristateSwitchTypeToString(vmport)); + } + + if (def->mem.dump_core) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("dump-guest-core is not available " + "with this QEMU binary")); + virBufferFreeAndReset(&buf); + return -1; + } + + virBufferAsprintf(&buf, ",dump-guest-core=%s", + virTristateSwitchTypeToString(def->mem.dump_core)); + } + + if (def->mem.nosharepages) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_MERGE)) { + virBufferAddLit(&buf, ",mem-merge=off"); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disable shared memory is not available " + "with this QEMU binary")); + virBufferFreeAndReset(&buf); + return -1; + } + } + + if (def->keywrap && + !qemuAppendKeyWrapMachineParms(&buf, qemuCaps, def->keywrap)) { + virBufferFreeAndReset(&buf); + return -1; + } + + if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON) { + if (def->gic_version != VIR_GIC_VERSION_NONE) { + if ((def->os.arch != VIR_ARCH_ARMV7L && + def->os.arch != VIR_ARCH_AARCH64) || + (STRNEQ(def->os.machine, "virt") && + !STRPREFIX(def->os.machine, "virt-"))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("gic-version option is available " + "only for ARM virt machine")); + virBufferFreeAndReset(&buf); + return -1; + } + + /* 2 is the default, so we don't put it as option for + * backwards compatibility + */ + if (def->gic_version != VIR_GIC_VERSION_2) { + if (!virQEMUCapsGet(qemuCaps, + QEMU_CAPS_MACH_VIRT_GIC_VERSION)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("gic-version option is not available " + "with this QEMU binary")); + virBufferFreeAndReset(&buf); + return -1; + } + + virBufferAsprintf(&buf, ",gic-version=%s", + virGICVersionTypeToString(def->gic_version)); + } + } + } + + virCommandAddArgBuffer(cmd, &buf); + } + + if (obsoleteAccel && + qemuBuildObsoleteAccelArg(cmd, def, qemuCaps) < 0) + return -1; + + return 0; +} + static int qemuBuildObjectCommandLinePropsInternal(const char *key, const virJSONValue *value, @@ -4934,234 +5168,6 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver, return ret; } -static int -qemuBuildObsoleteAccelArg(virCommandPtr cmd, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) -{ - bool disableKVM = false; - bool enableKVM = false; - - switch (def->virtType) { - case VIR_DOMAIN_VIRT_QEMU: - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) - disableKVM = true; - break; - - case VIR_DOMAIN_VIRT_KQEMU: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the QEMU binary does not support kqemu")); - break; - - case VIR_DOMAIN_VIRT_KVM: - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) { - enableKVM = true; - } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("the QEMU binary does not support kvm")); - return -1; - } - break; - - case VIR_DOMAIN_VIRT_XEN: - /* XXX better check for xenner */ - break; - - default: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("the QEMU binary does not support %s"), - virDomainVirtTypeToString(def->virtType)); - return -1; - } - - if (disableKVM) - virCommandAddArg(cmd, "-no-kvm"); - if (enableKVM) - virCommandAddArg(cmd, "-enable-kvm"); - - return 0; -} - -static bool -qemuAppendKeyWrapMachineParm(virBuffer *buf, virQEMUCapsPtr qemuCaps, - int flag, const char *pname, int pstate) -{ - if (pstate != VIR_TRISTATE_SWITCH_ABSENT) { - if (!virQEMUCapsGet(qemuCaps, flag)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("%s is not available with this QEMU binary"), pname); - return false; - } - - virBufferAsprintf(buf, ",%s=%s", pname, - virTristateSwitchTypeToString(pstate)); - } - - return true; -} - -static bool -qemuAppendKeyWrapMachineParms(virBuffer *buf, virQEMUCapsPtr qemuCaps, - const virDomainKeyWrapDef *keywrap) -{ - if (!qemuAppendKeyWrapMachineParm(buf, qemuCaps, QEMU_CAPS_AES_KEY_WRAP, - "aes-key-wrap", keywrap->aes)) - return false; - - if (!qemuAppendKeyWrapMachineParm(buf, qemuCaps, QEMU_CAPS_DEA_KEY_WRAP, - "dea-key-wrap", keywrap->dea)) - return false; - - return true; -} - -static int -qemuBuildMachineArgStr(virCommandPtr cmd, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) -{ - bool obsoleteAccel = false; - - /* This should *never* be NULL, since we always provide - * a machine in the capabilities data for QEMU. So this - * check is just here as a safety in case the unexpected - * happens */ - if (!def->os.machine) - return 0; - - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_OPT)) { - /* if no parameter to the machine type is needed, we still use - * '-M' to keep the most of the compatibility with older versions. - */ - virCommandAddArgList(cmd, "-M", def->os.machine, NULL); - if (def->mem.dump_core) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("dump-guest-core is not available " - "with this QEMU binary")); - return -1; - } - - if (def->mem.nosharepages) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("disable shared memory is not available " - "with this QEMU binary")); - return -1; - } - - obsoleteAccel = true; - - if (def->keywrap) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("key wrap support is not available " - "with this QEMU binary")); - return -1; - } - } else { - virBuffer buf = VIR_BUFFER_INITIALIZER; - virTristateSwitch vmport = def->features[VIR_DOMAIN_FEATURE_VMPORT]; - - virCommandAddArg(cmd, "-machine"); - virBufferAdd(&buf, def->os.machine, -1); - - if (def->virtType == VIR_DOMAIN_VIRT_QEMU) - virBufferAddLit(&buf, ",accel=tcg"); - else if (def->virtType == VIR_DOMAIN_VIRT_KVM) - virBufferAddLit(&buf, ",accel=kvm"); - else - obsoleteAccel = true; - - /* To avoid the collision of creating USB controllers when calling - * machine->init in QEMU, it needs to set usb=off - */ - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT)) - virBufferAddLit(&buf, ",usb=off"); - - if (vmport) { - if (!virQEMUCapsSupportsVmport(qemuCaps, def)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("vmport is not available " - "with this QEMU binary")); - virBufferFreeAndReset(&buf); - return -1; - } - - virBufferAsprintf(&buf, ",vmport=%s", - virTristateSwitchTypeToString(vmport)); - } - - if (def->mem.dump_core) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("dump-guest-core is not available " - "with this QEMU binary")); - virBufferFreeAndReset(&buf); - return -1; - } - - virBufferAsprintf(&buf, ",dump-guest-core=%s", - virTristateSwitchTypeToString(def->mem.dump_core)); - } - - if (def->mem.nosharepages) { - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_MERGE)) { - virBufferAddLit(&buf, ",mem-merge=off"); - } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("disable shared memory is not available " - "with this QEMU binary")); - virBufferFreeAndReset(&buf); - return -1; - } - } - - if (def->keywrap && - !qemuAppendKeyWrapMachineParms(&buf, qemuCaps, def->keywrap)) { - virBufferFreeAndReset(&buf); - return -1; - } - - if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON) { - if (def->gic_version != VIR_GIC_VERSION_NONE) { - if ((def->os.arch != VIR_ARCH_ARMV7L && - def->os.arch != VIR_ARCH_AARCH64) || - (STRNEQ(def->os.machine, "virt") && - !STRPREFIX(def->os.machine, "virt-"))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("gic-version option is available " - "only for ARM virt machine")); - virBufferFreeAndReset(&buf); - return -1; - } - - /* 2 is the default, so we don't put it as option for - * backwards compatibility - */ - if (def->gic_version != VIR_GIC_VERSION_2) { - if (!virQEMUCapsGet(qemuCaps, - QEMU_CAPS_MACH_VIRT_GIC_VERSION)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("gic-version option is not available " - "with this QEMU binary")); - virBufferFreeAndReset(&buf); - return -1; - } - - virBufferAsprintf(&buf, ",gic-version=%s", - virGICVersionTypeToString(def->gic_version)); - } - } - } - - virCommandAddArgBuffer(cmd, &buf); - } - - if (obsoleteAccel && - qemuBuildObsoleteAccelArg(cmd, def, qemuCaps) < 0) - return -1; - - return 0; -} - static char * qemuBuildSmpArgStr(const virDomainDef *def, virQEMUCapsPtr qemuCaps) @@ -6798,7 +6804,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (enableFips) virCommandAddArg(cmd, "-enable-fips"); - if (qemuBuildMachineArgStr(cmd, def, qemuCaps) < 0) + if (qemuBuildMachineCommandLine(cmd, def, qemuCaps) < 0) goto error; if (qemuBuildCpuArgStr(driver, def, qemuCaps, -- 2.5.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list