Blob Blame History Raw
From 1b93c4b30e7b0b7df7a61cf6a759a4b0ccccca20 Mon Sep 17 00:00:00 2001
Message-Id: <1b93c4b30e7b0b7df7a61cf6a759a4b0ccccca20@dist-git>
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
Date: Mon, 19 Jan 2015 10:48:27 +0100
Subject: [PATCH] Check for domain liveness in qemuDomainObjExitMonitor
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

https://bugzilla.redhat.com/show_bug.cgi?id=1161024

The domain might disappear during the time in monitor when
the virDomainObjPtr is unlocked, so the caller needs to check
if it's still alive.

Since most of the callers are going to need it, put the
check inside qemuDomainObjExitMonitor and return -1 if
the domain died in the meantime.

(cherry picked from commit dc2fd51fd727bbb6de172e0ca4b7dd307bb99180)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/THREADS.txt   |  5 +++++
 src/qemu/qemu_domain.c | 16 ++++++++++++++--
 src/qemu/qemu_domain.h |  4 ++--
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/qemu/THREADS.txt b/src/qemu/THREADS.txt
index 50a0cf9..b081bdb 100644
--- a/src/qemu/THREADS.txt
+++ b/src/qemu/THREADS.txt
@@ -156,6 +156,11 @@ To acquire the QEMU monitor lock
     - Acquires the virDomainObjPtr lock
 
   These functions must not be used by an asynchronous job.
+  Note that the virDomainObj is unlocked during the time in
+  monitor and it can be changed, e.g. if QEMU dies, qemuProcessStop
+  may free the live domain definition and put the persistent
+  definition back in vm->def. The callers should check the return
+  value of ExitMonitor to see if the domain is still alive.
 
 
 To acquire the QEMU monitor lock as part of an asynchronous job
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 03ca663..0c3d21f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1609,11 +1609,23 @@ void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
 /* obj must NOT be locked before calling
  *
  * Should be paired with an earlier qemuDomainObjEnterMonitor() call
+ *
+ * Returns -1 if the domain is no longer alive after exiting the monitor.
+ * In that case, the caller should be careful when using obj's data,
+ * e.g. the live definition in vm->def has been freed by qemuProcessStop
+ * and replaced by the persistent definition, so pointers stolen
+ * from the live definition could no longer be valid.
  */
-void qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
-                              virDomainObjPtr obj)
+int qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
+                             virDomainObjPtr obj)
 {
     qemuDomainObjExitMonitorInternal(driver, obj);
+    if (!virDomainObjIsActive(obj)) {
+        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                       _("domain is no longer running"));
+        return -1;
+    }
+    return 0;
 }
 
 /*
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 53501f9..bf37e26 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -248,8 +248,8 @@ void qemuDomainObjReleaseAsyncJob(virDomainObjPtr obj);
 void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
                                virDomainObjPtr obj)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-void qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
-                              virDomainObjPtr obj)
+int qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
+                             virDomainObjPtr obj)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 int qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
                                    virDomainObjPtr obj,
-- 
2.2.1