[libvirt] [PATCH v2] qemu: Fix shutdown regression with buggy qemu

Jiri Denemark jdenemar at redhat.com
Wed Sep 21 14:06:16 UTC 2011


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




More information about the libvir-list mailing list