The commit that prevents disk corruption on domain shutdown
(96fc4784177ecb70357518fa863442455e45ad0e) causes regression with QEMU
0.14.* and 0.15.* because of a regression bug in QEMU that was fixed
only recently in QEMU git. The affected versions of QEMU do not quit on
SIGTERM if started with -no-shutdown, which we use to implement fake
reboot. Since -no-shutdown tells QEMU not to quit automatically on guest
shutdown, domains started using the affected QEMU cannot be shutdown
properly and stay in a paused state.
This patch disables fake reboot feature on such QEMU by not using
-no-shutdown, which makes shutdown work as expected. However,
virDomainReboot will not work in this case and it will report "Requested
operation is not valid: Reboot is not supported with this QEMU binary".
---
src/qemu/qemu_capabilities.c | 8 ++++++++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_driver.c | 6 ++++++
4 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 36f47a9..850d46e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -136,6 +136,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"pci-ohci",
"usb-redir",
"usb-hub",
+ "no-shutdown",
);
struct qemu_feature_flags {
@@ -1008,6 +1009,13 @@ qemuCapsComputeCmdFlags(const char *help,
qemuCapsSet(flags, QEMU_CAPS_VHOST_NET);
}
+ /* Do not use -no-shutdown if qemu doesn't support it or SIGTERM handling
+ * is most likely buggy when used with -no-shutdown (which applies for qemu
+ * 0.14.* and 0.15.*)
+ */
+ if (strstr(help, "-no-shutdown") && (version < 14000 || version
> 15999))
+ qemuCapsSet(flags, QEMU_CAPS_NO_SHUTDOWN);
+
/*
* Handling of -incoming arg with varying features
* -incoming tcp (kvm >= 79, qemu >= 0.10.0)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 96b7a3b..74d3ab2 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -110,6 +110,7 @@ enum qemuCapsFlags {
QEMU_CAPS_PCI_OHCI = 71, /* -device pci-ohci */
QEMU_CAPS_USB_REDIR = 72, /* -device usb-redir */
QEMU_CAPS_USB_HUB = 73, /* -device usb-hub */
+ QEMU_CAPS_NO_SHUTDOWN = 74, /* usable -no-shutdown */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ee4b52b..0adc56a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3574,7 +3574,7 @@ qemuBuildCommandLine(virConnectPtr conn,
* when QEMU stops. If we use no-shutdown, then we can
* watch for this event and do a soft/warm reboot.
*/
- if (monitor_json)
+ if (monitor_json && qemuCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN))
virCommandAddArg(cmd, "-no-shutdown");
if (!(def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)))
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f4ee4c3..67c43ab 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1557,6 +1557,12 @@ static int qemuDomainReboot(virDomainPtr dom, unsigned int flags)
{
priv = vm->privateData;
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
+ if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Reboot is not supported with this QEMU
binary"));
+ goto cleanup;
+ }
+
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
--
1.7.6.1