[libvirt] [PATCH] Fix handling of VIR_EVENT_HANDLE_ERROR in QEMU monitor

Daniel P. Berrange berrange at redhat.com
Thu Jun 2 10:52:10 UTC 2011


Commit 4454a9efc728b91e791b1f14c26ea23a19d57f48 introduced bad
behaviour on the VIR_EVENT_HANDLE_ERROR condition. This condition
is only hit when an invalid FD is used in poll() (typically due
to a double-close bug). The QEMU monitor code was treating this
condition as non-fatal, and thus libvirt would poll() in a fast
loop forever burning 100% CPU. VIR_EVENT_HANDLE_ERROR must be
handled in the same way as VIR_EVENT_HANDLE_HANGUP, killing the
QEMU instance.

* src/qemu/qemu_monitor.c: Treat VIR_EVENT_HANDLE_ERROR as EOF
---
 src/qemu/qemu_monitor.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 09a1b8e..26bb814 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -535,14 +535,14 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
 #endif
 
     if (mon->fd != fd || mon->watch != watch) {
-        if (events & VIR_EVENT_HANDLE_HANGUP)
+        if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
             eof = true;
         qemuReportError(VIR_ERR_INTERNAL_ERROR,
                         _("event from unexpected fd %d!=%d / watch %d!=%d"),
                         mon->fd, fd, mon->watch, watch);
         error = true;
     } else if (mon->lastError.code != VIR_ERR_OK) {
-        if (events & VIR_EVENT_HANDLE_HANGUP)
+        if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
             eof = true;
         error = true;
     } else {
@@ -581,8 +581,9 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
         if (!error && !eof &&
             events & VIR_EVENT_HANDLE_ERROR) {
             qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                            _("Error while waiting for monitor"));
-            error = 1;
+                            _("Invalid file descriptor while waiting for monitor"));
+            eof = 1;
+            events &= ~VIR_EVENT_HANDLE_ERROR;
         }
         if (!error && events) {
             qemuReportError(VIR_ERR_INTERNAL_ERROR,
-- 
1.7.4.4




More information about the libvir-list mailing list