[libvirt] [RFC PATCH 08/10] qemu: monitor: check monitor not closed upon send

John Ferlan jferlan at redhat.com
Wed Jan 10 17:23:33 UTC 2018


From: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>

Close monitor sets monitor error if another thread is awating the
response to propagate error condition to that thread. However
if there is no such thread error will not be set. Now if API
thread try to send a message it will hang. This can easily happen
for example if API thread does not reach the point when it take
domain lock and qemu driver is shutdowned.

Let's add checks for whether monitor is closed to send routine
and remove passing of this condition thru setting monitor error.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/qemu/qemu_monitor.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 046caf001..d97506e11 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1001,22 +1001,9 @@ qemuMonitorClose(qemuMonitorPtr mon)
     }
 
     /* In case another thread is waiting for its monitor command to be
-     * processed, we need to wake it up with appropriate error set.
+     * processed, we need to wake it up.
      */
     if (mon->msg) {
-        if (mon->lastError.code == VIR_ERR_OK) {
-            virErrorPtr err = virSaveLastError();
-
-            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
-                           _("QEMU monitor was closed"));
-            virCopyLastError(&mon->lastError);
-            if (err) {
-                virSetError(err);
-                virFreeError(err);
-            } else {
-                virResetLastError();
-            }
-        }
         mon->msg->finished = 1;
         virCondSignal(&mon->notify);
     }
@@ -1048,6 +1035,12 @@ qemuMonitorSend(qemuMonitorPtr mon,
 {
     int ret = -1;
 
+    if (mon->fd < 0) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("QEMU monitor was closed"));
+        return -1;
+    }
+
     /* Check whether qemu quit unexpectedly */
     if (mon->lastError.code != VIR_ERR_OK) {
         VIR_DEBUG("Attempt to send command while error is set %s",
@@ -1071,6 +1064,12 @@ qemuMonitorSend(qemuMonitorPtr mon,
         }
     }
 
+    if (mon->fd < 0) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("QEMU monitor was closed"));
+        goto cleanup;
+    }
+
     if (mon->lastError.code != VIR_ERR_OK) {
         VIR_DEBUG("Send command resulted in error %s",
                   NULLSTR(mon->lastError.message));
-- 
2.13.6




More information about the libvir-list mailing list