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);