Enable '-compat' if requested in qemu.conf and supported by qemu to instruct qemu to crash when a deprecated command is used and stop returning deprecated fields. This setting is meant for libvirt developers and such. --- src/qemu/qemu_command.c | 80 +++++++++++++++++++ .../qemu-ns.x86_64-latest.args | 1 + 2 files changed, 81 insertions(+) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1b4fa77867..2388b1a1a1 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -10325,6 +10325,84 @@ qemuBuildVsockCommandLine(virCommandPtr cmd, } +typedef enum { + QEMU_COMMAND_DEPRECATION_BEHAVIOR_NONE = 0, + QEMU_COMMAND_DEPRECATION_BEHAVIOR_OMIT, + QEMU_COMMAND_DEPRECATION_BEHAVIOR_REJECT, + QEMU_COMMAND_DEPRECATION_BEHAVIOR_CRASH, + + QEMU_COMMAND_DEPRECATION_BEHAVIOR_LAST +} qemuCommnadDeprecationBehavior; + + +VIR_ENUM_DECL(qemuCommnadDeprecationBehavior); +VIR_ENUM_IMPL(qemuCommnadDeprecationBehavior, + QEMU_COMMAND_DEPRECATION_BEHAVIOR_LAST, + "none", + "omit", + "reject", + "crash"); + +static void +qemuBuildCompatDeprecatedCommandLine(virCommand *cmd, + virQEMUDriverConfig *cfg, + virDomainDef *def, + virQEMUCaps *qemuCaps) +{ + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + qemuDomainXmlNsDefPtr nsdata = def->namespaceData; + qemuCommnadDeprecationBehavior behavior = QEMU_COMMAND_DEPRECATION_BEHAVIOR_NONE; + const char *behaviorStr = cfg->deprecationBehavior; + int tmp; + + if (nsdata && nsdata->deprecationBehavior) + behaviorStr = nsdata->deprecationBehavior; + + if ((tmp = qemuCommnadDeprecationBehaviorTypeFromString(behaviorStr)) < 0) { + VIR_WARN("Unsupported deprecation behavior '%s' for VM '%s'", + behaviorStr, def->name); + return; + } + + behavior = tmp; + + if (behavior == QEMU_COMMAND_DEPRECATION_BEHAVIOR_NONE) + return; + + /* we don't try to enable this feature at all if qemu doesn't support it, + * so that a downgrade of qemu version doesn't impact startup of the VM */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_COMPAT_DEPRECATED)) { + VIR_DEBUG("-compat not supported for VM '%s'", def->name); + return; + } + + /* all active options hide output fields from qemu */ + virBufferAddLit(&buf, "deprecated-output=hide,"); + + switch (behavior) { + case QEMU_COMMAND_DEPRECATION_BEHAVIOR_OMIT: + case QEMU_COMMAND_DEPRECATION_BEHAVIOR_NONE: + case QEMU_COMMAND_DEPRECATION_BEHAVIOR_LAST: + default: + /* output field hiding is default for all cases */ + break; + + case QEMU_COMMAND_DEPRECATION_BEHAVIOR_REJECT: + virBufferAddLit(&buf, "deprecated-input=reject,"); + break; + + case QEMU_COMMAND_DEPRECATION_BEHAVIOR_CRASH: + virBufferAddLit(&buf, "deprecated-input=crash,"); + break; + } + + virBufferTrim(&buf, ","); + + virCommandAddArg(cmd, "-compat"); + virCommandAddArgBuffer(cmd, &buf); +} + + /* * Constructs a argv suitable for launching qemu with config defined * for a given virtual machine. @@ -10385,6 +10463,8 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildNameCommandLine(cmd, cfg, def, qemuCaps) < 0) return NULL; + qemuBuildCompatDeprecatedCommandLine(cmd, cfg, def, qemuCaps); + if (!standalone) virCommandAddArg(cmd, "-S"); /* freeze CPU */ diff --git a/tests/qemuxml2argvdata/qemu-ns.x86_64-latest.args b/tests/qemuxml2argvdata/qemu-ns.x86_64-latest.args index 5a8136a8b7..71b83ca681 100644 --- a/tests/qemuxml2argvdata/qemu-ns.x86_64-latest.args +++ b/tests/qemuxml2argvdata/qemu-ns.x86_64-latest.args @@ -10,6 +10,7 @@ NS=ns \ BAR='' \ /usr/bin/qemu-system-i386 \ -name guest=QEMUGuest1,debug-threads=on \ +-compat deprecated-output=hide,deprecated-input=crash \ -S \ -object '{"qom-type":"secret","id":"masterKey0","format":"raw",\ "file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ -- 2.29.2