Allow to use 'optional' on attribute 'enabled' of async-teardown. This allows a user to exploit the feature if it is provided by QEMU. Also adding tests and documentation. Signed-off-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxx> --- docs/formatdomain.rst | 7 ++-- src/conf/domain_conf.c | 14 ++++---- src/conf/schemas/domaincommon.rng | 2 +- src/qemu/qemu_command.c | 6 ++-- src/qemu/qemu_process.c | 18 ++++++++++ src/qemu/qemu_validate.c | 2 +- ...0-async-teardown-optional.s390x-6.0.0.args | 35 ++++++++++++++++++ ...-async-teardown-optional.s390x-latest.args | 36 +++++++++++++++++++ .../s390-async-teardown-optional.xml | 24 +++++++++++++ tests/qemuxml2argvtest.c | 2 ++ 10 files changed, 132 insertions(+), 14 deletions(-) create mode 100644 tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-6.0.0.args create mode 100644 tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-latest.args create mode 100644 tests/qemuxml2argvdata/s390-async-teardown-optional.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index cd9cb02bf8..61f90e1f11 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2232,9 +2232,10 @@ are: =========== ============================================== =================================================== ============== ``async-teardown`` - Depending on the ``enabled`` attribute (values ``yes``, ``no``) enable or - disable QEMU asynchronous teardown to improve memory reclaiming on a guest. - :since:`Since 9.6.0` (QEMU only) + Depending on the ``enabled`` attribute (values ``yes``, ``no``, ``optional``) + enable or disable QEMU asynchronous teardown to improve memory reclaiming on + a guest. Setting ``optional`` will enable the feature if QEMU supports the + feature and otherwise disable it. :since:`Since 9.6.0` (QEMU only) Time keeping ------------ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 47693a49bf..7191e37a6c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -16691,14 +16691,14 @@ virDomainFeaturesDefParse(virDomainDef *def, break; case VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN: { - virTristateBool enabled; + virQuadstateOption enabled; - if (virXMLPropTristateBool(nodes[i], "enabled", - VIR_XML_PROP_NONE, &enabled) < 0) + if (virXMLPropQuadstateOption(nodes[i], "enabled", + VIR_XML_PROP_NONE, &enabled) < 0) return -1; - if (enabled == VIR_TRISTATE_BOOL_ABSENT) - enabled = VIR_TRISTATE_BOOL_YES; + if (enabled == VIR_QUADSTATE_OPTION_ABSENT) + enabled = VIR_QUADSTATE_OPTION_YES; def->features[val] = enabled; break; @@ -27357,9 +27357,9 @@ virDomainDefFormatFeatures(virBuffer *buf, break; case VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN: - if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT) + if (def->features[i] != VIR_QUADSTATE_OPTION_ABSENT) virBufferAsprintf(&childBuf, "<async-teardown enabled='%s'/>\n", - virTristateBoolTypeToString(def->features[i])); + virQuadstateOptionTypeToString(def->features[i])); break; case VIR_DOMAIN_FEATURE_LAST: diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index c2f56b0490..cc116a8b24 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6664,7 +6664,7 @@ <element name="async-teardown"> <optional> <attribute name="enabled"> - <ref name="virYesNo"/> + <ref name="virYesNoOptional"/> </attribute> </optional> </element> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 77c5335bde..ef5e2c5239 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -10195,10 +10195,12 @@ qemuBuildAsyncTeardownCommandLine(virCommand *cmd, virQEMUCaps *qemuCaps) { g_autofree char *async = NULL; - virTristateBool enabled = def->features[VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN]; + virQuadstateOption enabled = def->features[VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN]; - if (enabled != VIR_TRISTATE_BOOL_ABSENT && + if (enabled != VIR_QUADSTATE_OPTION_ABSENT && virQEMUCapsGet(qemuCaps, QEMU_CAPS_RUN_WITH_ASYNC_TEARDOWN)) { + if (enabled == VIR_QUADSTATE_OPTION_OPTIONAL) + enabled = VIR_QUADSTATE_OPTION_YES; async = g_strdup_printf("async-teardown=%s", virTristateSwitchTypeToString(enabled)); virCommandAddArgList(cmd, "-run-with", async, NULL); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 0644f80161..7db6e0069e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6591,6 +6591,19 @@ qemuProcessUpdateSEVInfo(virDomainObj *vm) } +static void +qemuProcessUpdateAsyncTeardown(virDomainObj *vm) +{ + virDomainDef *def = vm->def; + qemuDomainObjPrivate *priv = vm->privateData; + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_RUN_WITH_ASYNC_TEARDOWN)) + def->features[VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN] = VIR_QUADSTATE_OPTION_YES; + else + def->features[VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN] = VIR_QUADSTATE_OPTION_NO; +} + + /* qemuProcessPrepareChardevSource: * @def: live domain definition * @cfg: driver configuration @@ -6752,6 +6765,11 @@ qemuProcessPrepareDomain(virQEMUDriver *driver, return -1; } + if (vm->def->features[VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN] == VIR_QUADSTATE_OPTION_OPTIONAL) { + VIR_DEBUG("Prepare feature async-teardown enablement from optional"); + qemuProcessUpdateAsyncTeardown(vm); + } + return 0; } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index d5c2b2cd44..fe010397ba 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -220,7 +220,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, break; case VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN: - if (def->features[i] == VIR_TRISTATE_BOOL_YES && + if (def->features[i] == VIR_QUADSTATE_OPTION_YES && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_RUN_WITH_ASYNC_TEARDOWN)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("asynchronous teardown is not available with this QEMU binary")); diff --git a/tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-6.0.0.args b/tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-6.0.0.args new file mode 100644 index 0000000000..57690530a2 --- /dev/null +++ b/tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-6.0.0.args @@ -0,0 +1,35 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-s390x \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine s390-ccw-virtio-6.0,usb=off,dump-guest-core=off,memory-backend=s390.ram \ +-accel tcg \ +-cpu qemu \ +-m size=262144k \ +-object '{"qom-type":"memory-backend-ram","id":"s390.ram","size":268435456}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 9aa4b45c-b9dd-45ef-91fe-862b27b4231f \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device virtio-serial-ccw,id=virtio-serial0,devno=fe.0.0000 \ +-chardev pty,id=charconsole0 \ +-device virtconsole,chardev=charconsole0,id=console0 \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device virtio-balloon-ccw,id=balloon0,devno=fe.0.0001 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-latest.args b/tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-latest.args new file mode 100644 index 0000000000..cc7866499f --- /dev/null +++ b/tests/qemuxml2argvdata/s390-async-teardown-optional.s390x-latest.args @@ -0,0 +1,36 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-s390x \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine s390-ccw-virtio,usb=off,dump-guest-core=off,memory-backend=s390.ram \ +-accel tcg \ +-cpu qemu \ +-m size=262144k \ +-object '{"qom-type":"memory-backend-ram","id":"s390.ram","size":268435456}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 9aa4b45c-b9dd-45ef-91fe-862b27b4231f \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"virtio-serial-ccw","id":"virtio-serial0","devno":"fe.0.0000"}' \ +-chardev pty,id=charconsole0 \ +-device '{"driver":"virtconsole","chardev":"charconsole0","id":"console0"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"virtio-balloon-ccw","id":"balloon0","devno":"fe.0.0001"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-run-with async-teardown=on \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/s390-async-teardown-optional.xml b/tests/qemuxml2argvdata/s390-async-teardown-optional.xml new file mode 100644 index 0000000000..6e4fe3b1dd --- /dev/null +++ b/tests/qemuxml2argvdata/s390-async-teardown-optional.xml @@ -0,0 +1,24 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>9aa4b45c-b9dd-45ef-91fe-862b27b4231f</uuid> + <memory>262144</memory> + <currentMemory>262144</currentMemory> + <os> + <type arch='s390x' machine='s390-ccw-virtio'>hvm</type> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <features> + <async-teardown enabled='optional'/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-s390x</emulator> + <controller type='virtio-serial' index='0'> + </controller> + <console type='pty'> + <target type='virtio'/> + </console> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c44b9bc494..1a84ac1526 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2705,6 +2705,8 @@ mymain(void) DO_TEST_CAPS_ARCH_VER_PARSE_ERROR("s390-async-teardown", "s390x", "6.0.0"); DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown-disabled", "s390x"); DO_TEST_CAPS_ARCH_VER("s390-async-teardown-disabled", "s390x", "6.0.0"); + DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown-optional", "s390x"); + DO_TEST_CAPS_ARCH_VER("s390-async-teardown-optional", "s390x", "6.0.0"); qemuTestDriverFree(&driver); virFileWrapperClearPrefixes(); -- 2.41.0