[libvirt] [PATCH 4/4] qemu: monitor: check monitor not closed upon send

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Wed Oct 25 09:05:08 UTC 2017


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.
---
 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 64efb89..63e6f74 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1000,22 +1000,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);
     }
@@ -1047,6 +1034,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",
@@ -1070,6 +1063,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));
-- 
1.8.3.1




More information about the libvir-list mailing list