[libvirt] virCommandProcessIO: hangs on poll()

wangxiaojun wangxiaojun at ec.com.cn
Fri Apr 19 07:32:54 UTC 2013


recent qemu (git resp) with param like:           
#>qemu-kvm -S -no-user-config  -nodefaults -nographic  -M none -qmp
monarg -pidfile pidfile

will just hangs forever.  no any output or errors .
and when libvirt Try to get caps via QMP qemuCaps. it run above command.
so virCommandProcessIO  call poll() will be hangs forever.

i patch the libvirt (git resp) with :

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 50712b0..915edaa 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2377,7 +2377,6 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
     virCommandClearCaps(cmd);
     virCommandSetGID(cmd, runGid);
     virCommandSetUID(cmd, runUid);
-
     if (virCommandRun(cmd, &status) < 0)
         goto cleanup;
 
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index ac56a63..84738f9 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -1824,6 +1824,7 @@ virCommandProcessIO(virCommandPtr cmd)
         int i;
         struct pollfd fds[3];
         int nfds = 0;
+        int pfds = 0;
 
         if (cmd->inpipe != -1) {
             fds[nfds].fd = cmd->inpipe;
@@ -1846,8 +1847,8 @@ virCommandProcessIO(virCommandPtr cmd)
 
         if (nfds == 0)
             break;
-
-        if (poll(fds, nfds, -1) < 0) {
+        pfds = poll(fds, nfds, -1);
+        if ( pfds< 0) {
             if (errno == EAGAIN || errno == EINTR)
                 continue;
             virReportSystemError(errno, "%s",
@@ -1855,10 +1856,22 @@ virCommandProcessIO(virCommandPtr cmd)
             goto cleanup;
         }
 
-        for (i = 0; i < nfds ; i++) {
-            if (fds[i].revents & (POLLIN | POLLHUP | POLLERR) &&
+        for (i = 0; i < pfds ; i++) {
+            if (fds[i].revents & (POLLHUP | POLLRDHUP | POLLERR |
POLLNVAL))
+            {
+                if (fds[i].fd == errfd) {
+                    VIR_DEBUG("hangup on stderr");
+                } else if (fds[i].fd == outfd) {
+                    VIR_DEBUG("hangup on stdout");
+                } else {
+                    VIR_DEBUG("hangup on stdin");
+                }
+                errfd = -1;
+            }
+
+            if (fds[i].revents & (POLLIN | POLLHUP | POLLRDHUP |
POLLERR | POLLNVAL) &&
                 (fds[i].fd == errfd || fds[i].fd == outfd)) {
-                char data[1024];
+                char data[1024*2];
                 char **buf;
                 size_t *len;
                 int done;



So everythings is OK.  
i use gentoo OS.   qemu git source and libvirt git source.





More information about the libvir-list mailing list