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". NB, the qemu capability is called QEMU_CAPS_NO_FAKE_REBOOT for backward compatibility with running domains started by libvirtd that didn't have this patch in. --- src/qemu/qemu_capabilities.c | 9 +++++++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 6 ++++++ 4 files changed, 17 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 36f47a9..5b9e4a9 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-fake-reboot", ); struct qemu_feature_flags { @@ -1008,6 +1009,14 @@ qemuCapsComputeCmdFlags(const char *help, qemuCapsSet(flags, QEMU_CAPS_VHOST_NET); } + /* Do not use -no-shutdown to implement fake reboot 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 / 1000 == 14 || version / 1000 == 15) + qemuCapsSet(flags, QEMU_CAPS_NO_FAKE_REBOOT); + /* * 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..b4f3ba4 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_FAKE_REBOOT = 74, /* don't fake reboot using -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..aab4cd9 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_FAKE_REBOOT)) 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..d2eb881 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_FAKE_REBOOT)) { + 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list