d76c62
From 84c5cad5921e96c6106cfd217de2064b64e1464f Mon Sep 17 00:00:00 2001
d76c62
Message-Id: <84c5cad5921e96c6106cfd217de2064b64e1464f@dist-git>
d76c62
From: Michal Privoznik <mprivozn@redhat.com>
d76c62
Date: Thu, 16 Jan 2020 10:03:54 +0100
d76c62
Subject: [PATCH] qemu: Stop domain on failed restore
d76c62
MIME-Version: 1.0
d76c62
Content-Type: text/plain; charset=UTF-8
d76c62
Content-Transfer-Encoding: 8bit
d76c62
d76c62
When resuming a domain from a save file, we read the domain XML
d76c62
from the file, add it onto our internal list of domains, start
d76c62
the qemu process, let it load the incoming migration stream and
d76c62
resume its vCPUs afterwards. If anything goes wrong, the domain
d76c62
object is removed from the list of domains and error is returned
d76c62
to the caller. However, the qemu process might be left behind -
d76c62
if resuming vCPUs fails (e.g. because qemu is unable to acquire
d76c62
write lock on a disk) then due to a bug the qemu process is not
d76c62
killed but the domain object is removed from the list.
d76c62
d76c62
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1718707
d76c62
d76c62
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d76c62
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
d76c62
(cherry picked from commit 4c581527d431939a63be70c201b4ddab703cddbe)
d76c62
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d76c62
Message-Id: <4048f92488a8b8c31c7a17a14b579840a9492328.1579165329.git.mprivozn@redhat.com>
d76c62
Reviewed-by: Ján Tomko <jtomko@redhat.com>
d76c62
---
d76c62
 src/qemu/qemu_driver.c | 23 ++++++++++++-----------
d76c62
 1 file changed, 12 insertions(+), 11 deletions(-)
d76c62
d76c62
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
d76c62
index ce9b1772c1..217d873671 100644
d76c62
--- a/src/qemu/qemu_driver.c
d76c62
+++ b/src/qemu/qemu_driver.c
d76c62
@@ -6800,7 +6800,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
d76c62
 {
d76c62
     qemuDomainObjPrivatePtr priv = vm->privateData;
d76c62
     int ret = -1;
d76c62
-    bool restored = false;
d76c62
+    bool started = false;
d76c62
     virObjectEventPtr event;
d76c62
     VIR_AUTOCLOSE intermediatefd = -1;
d76c62
     g_autoptr(virCommand) cmd = NULL;
d76c62
@@ -6808,6 +6808,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
d76c62
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
d76c62
     virQEMUSaveHeaderPtr header = &data->header;
d76c62
     g_autoptr(qemuDomainSaveCookie) cookie = NULL;
d76c62
+    int rc = 0;
d76c62
 
d76c62
     if (virSaveCookieParseString(data->cookie, (virObjectPtr *)&cookie,
d76c62
                                  virDomainXMLOptionGetSaveCookie(driver->xmlopt)) < 0)
d76c62
@@ -6848,12 +6849,12 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
d76c62
                          VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
d76c62
                          VIR_QEMU_PROCESS_START_PAUSED |
d76c62
                          VIR_QEMU_PROCESS_START_GEN_VMID) == 0)
d76c62
-        restored = true;
d76c62
+        started = true;
d76c62
 
d76c62
     if (intermediatefd != -1) {
d76c62
         virErrorPtr orig_err = NULL;
d76c62
 
d76c62
-        if (!restored) {
d76c62
+        if (!started) {
d76c62
             /* if there was an error setting up qemu, the intermediate
d76c62
              * process will wait forever to write to stdout, so we
d76c62
              * must manually kill it and ignore any error related to
d76c62
@@ -6864,21 +6865,17 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
d76c62
             VIR_FORCE_CLOSE(*fd);
d76c62
         }
d76c62
 
d76c62
-        if (virCommandWait(cmd, NULL) < 0) {
d76c62
-            qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, 0);
d76c62
-            restored = false;
d76c62
-        }
d76c62
+        rc = virCommandWait(cmd, NULL);
d76c62
         VIR_DEBUG("Decompression binary stderr: %s", NULLSTR(errbuf));
d76c62
-
d76c62
         virErrorRestore(&orig_err);
d76c62
     }
d76c62
     if (VIR_CLOSE(*fd) < 0) {
d76c62
         virReportSystemError(errno, _("cannot close file: %s"), path);
d76c62
-        restored = false;
d76c62
+        rc = -1;
d76c62
     }
d76c62
 
d76c62
-    virDomainAuditStart(vm, "restored", restored);
d76c62
-    if (!restored)
d76c62
+    virDomainAuditStart(vm, "restored", started);
d76c62
+    if (!started || rc < 0)
d76c62
         goto cleanup;
d76c62
 
d76c62
     /* qemuProcessStart doesn't unset the qemu error reporting infrastructure
d76c62
@@ -6918,6 +6915,10 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
d76c62
     ret = 0;
d76c62
 
d76c62
  cleanup:
d76c62
+    if (ret < 0 && started) {
d76c62
+        qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED,
d76c62
+                        asyncJob, VIR_QEMU_PROCESS_STOP_MIGRATED);
d76c62
+    }
d76c62
     if (qemuSecurityRestoreSavedStateLabel(driver, vm, path) < 0)
d76c62
         VIR_WARN("failed to restore save state label on %s", path);
d76c62
     return ret;
d76c62
-- 
d76c62
2.25.0
d76c62