[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] qemu: Fix shutdown regression



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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]