Blob Blame History Raw
diff -rup libvirt-0.6.0.orig/src/qemu_driver.c libvirt-0.6.0.new/src/qemu_driver.c
--- libvirt-0.6.0.orig/src/qemu_driver.c	2009-01-31 09:04:18.000000000 +0000
+++ libvirt-0.6.0.new/src/qemu_driver.c	2009-02-18 11:15:37.000000000 +0000
@@ -633,6 +633,7 @@ qemudReadMonitorOutput(virConnectPtr con
 {
     int got = 0;
     buf[0] = '\0';
+    timeout *= 1000; /* poll wants milli seconds */
 
     /* Consume & discard the initial greeting */
     while (got < (buflen-1)) {
@@ -694,6 +695,56 @@ qemudReadMonitorOutput(virConnectPtr con
 
 }
 
+
+/*
+ * Returns -1 for error, 0 on success
+ */
+static int
+qemudReadLogOutput(virConnectPtr conn,
+                   virDomainObjPtr vm,
+                   int fd,
+                   char *buf,
+                   int buflen,
+                   qemudHandlerMonitorOutput func,
+                   const char *what,
+                   int timeout)
+{
+    int got = 0;
+    int ret;
+    int retries = timeout*10;
+    buf[0] = '\0';
+
+    while (retries) {
+        while((ret = read(fd, buf+got, buflen-got-1)) > 0) {
+            got += ret;
+            buf[got] = '\0';
+            if ((buflen-got-1) == 0) {
+                qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                 _("Out of space while reading %s log output"), what);
+                return -1;
+            }
+        }
+
+        if (ret < 0 && errno != EINTR) {
+            virReportSystemError(conn, errno,
+                                 _("Failure while reading %s log output"),
+                                 what);
+            return -1;
+        }
+
+        ret = func(conn, vm, buf, fd);
+        if (ret <= 0)
+            return ret;
+
+        usleep(100*1000);
+        retries--;
+    }
+    if (retries == 0)
+        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("Timed out while reading %s log output"), what);
+    return -1;
+}
+
 static int
 qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
                         virDomainObjPtr vm,
@@ -738,7 +789,7 @@ static int qemudOpenMonitor(virConnectPt
                                    vm, monfd,
                                    buf, sizeof(buf),
                                    qemudCheckMonitorPrompt,
-                                   "monitor", 10000) <= 0)
+                                   "monitor", 10) <= 0)
             ret = -1;
         else
             ret = 0;
@@ -770,6 +821,7 @@ static int qemudOpenMonitor(virConnectPt
     return ret;
 }
 
+/* Returns -1 for error, 0 success, 1 continue reading */
 static int qemudExtractMonitorPath(virConnectPtr conn,
                                    const char *haystack,
                                    size_t *offset,
@@ -873,19 +925,16 @@ static int qemudWaitForMonitor(virConnec
         < 0)
         return -1;
 
-    ret = qemudReadMonitorOutput(conn, vm, logfd, buf, sizeof(buf),
-                                 qemudFindCharDevicePTYs,
-                                 "console", 3000);
+    ret = qemudReadLogOutput(conn, vm, logfd, buf, sizeof(buf),
+                             qemudFindCharDevicePTYs,
+                             "console", 3);
     if (close(logfd) < 0)
         qemudLog(QEMUD_WARN, _("Unable to close logfile: %s\n"),
                  strerror(errno));
 
-    if (ret == 1) /* Success */
+    if (ret == 0) /* success */
         return 0;
 
-    if (ret == -1)
-        return -1;
-
     /* Unexpected end of file - inform user of QEMU log data */
     qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                      _("unable to start guest: %s"), buf);