From 996d0e47099ca25e7be14be2375e23b1e4e8815f Mon Sep 17 00:00:00 2001 From: Daniel P. Berrange Date: Feb 18 2009 13:51:22 +0000 Subject: Fix QEMU startup timeout/race (rhbz #484649) Setup DBus threading. Don't allow dbus to call _exit / change SIGPIPE (rhbz #484553) Fix timeout when autostarting session daemon --- diff --git a/libvirt-0.6.0-autostart-timeout.patch b/libvirt-0.6.0-autostart-timeout.patch new file mode 100644 index 0000000..bceb928 --- /dev/null +++ b/libvirt-0.6.0-autostart-timeout.patch @@ -0,0 +1,21 @@ +diff -rup libvirt-0.6.0.orig/src/remote_internal.c libvirt-0.6.0.new/src/remote_internal.c +--- libvirt-0.6.0.orig/src/remote_internal.c 2009-02-18 10:56:34.000000000 +0000 ++++ libvirt-0.6.0.new/src/remote_internal.c 2009-02-18 13:35:26.000000000 +0000 +@@ -654,12 +654,13 @@ doRemoteOpen (virConnectPtr conn, + */ + if (errno == ECONNREFUSED && + flags & VIR_DRV_OPEN_REMOTE_AUTOSTART && +- trials < 5) { ++ trials < 20) { + close(priv->sock); + priv->sock = -1; +- if (remoteForkDaemon(conn) == 0) { ++ if (trials > 0 || ++ remoteForkDaemon(conn) == 0) { + trials++; +- usleep(5000 * trials * trials); ++ usleep(1000 * 100 * trials); + goto autostart_retry; + } + } +Only in libvirt-0.6.0.new/src: remote_internal.c~ diff --git a/libvirt-0.6.0-dbus-threads.patch b/libvirt-0.6.0-dbus-threads.patch new file mode 100644 index 0000000..1001ae1 --- /dev/null +++ b/libvirt-0.6.0-dbus-threads.patch @@ -0,0 +1,44 @@ +diff -rup libvirt-0.6.0.orig/qemud/qemud.c libvirt-0.6.0.new/qemud/qemud.c +--- libvirt-0.6.0.orig/qemud/qemud.c 2009-02-18 10:56:34.000000000 +0000 ++++ libvirt-0.6.0.new/qemud/qemud.c 2009-02-18 12:52:18.000000000 +0000 +@@ -860,6 +860,10 @@ static struct qemud_server *qemudNetwork + if (auth_unix_rw == REMOTE_AUTH_POLKIT || + auth_unix_ro == REMOTE_AUTH_POLKIT) { + DBusError derr; ++ ++ dbus_connection_set_change_sigpipe(FALSE); ++ dbus_threads_init_default(); ++ + dbus_error_init(&derr); + server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr); + if (!(server->sysbus)) { +@@ -868,6 +872,7 @@ static struct qemud_server *qemudNetwork + dbus_error_free(&derr); + goto cleanup; + } ++ dbus_connection_set_exit_on_disconnect(server->sysbus, FALSE); + } + #endif + +diff -rup libvirt-0.6.0.orig/src/node_device_hal.c libvirt-0.6.0.new/src/node_device_hal.c +--- libvirt-0.6.0.orig/src/node_device_hal.c 2009-01-16 12:44:22.000000000 +0000 ++++ libvirt-0.6.0.new/src/node_device_hal.c 2009-02-18 12:52:48.000000000 +0000 +@@ -685,6 +685,9 @@ static int halDeviceMonitorStartup(void) + nodeDeviceLock(driverState); + + /* Allocate and initialize a new HAL context */ ++ dbus_connection_set_change_sigpipe(FALSE); ++ dbus_threads_init_default(); ++ + dbus_error_init(&err); + hal_ctx = libhal_ctx_new(); + if (hal_ctx == NULL) { +@@ -696,6 +699,8 @@ static int halDeviceMonitorStartup(void) + fprintf(stderr, "%s: dbus_bus_get failed\n", __FUNCTION__); + goto failure; + } ++ dbus_connection_set_exit_on_disconnect(dbus_conn, FALSE); ++ + if (!libhal_ctx_set_dbus_connection(hal_ctx, dbus_conn)) { + fprintf(stderr, "%s: libhal_ctx_set_dbus_connection failed\n", + __FUNCTION__); diff --git a/libvirt-0.6.0-qemu-startup.patch b/libvirt-0.6.0-qemu-startup.patch new file mode 100644 index 0000000..b424e50 --- /dev/null +++ b/libvirt-0.6.0-qemu-startup.patch @@ -0,0 +1,109 @@ +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); diff --git a/libvirt.spec b/libvirt.spec index f4aebb1..a238d9a 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -47,12 +47,15 @@ Summary: Library providing a simple API virtualization Name: libvirt Version: 0.6.0 -Release: 3%{?dist}%{?extra_release} +Release: 4%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries Source: libvirt-%{version}.tar.gz Patch1: %{name}-%{version}-timeout.patch Patch2: %{name}-%{version}-rpccall.patch +Patch3: %{name}-%{version}-qemu-startup.patch +Patch4: %{name}-%{version}-dbus-threads.patch +Patch5: %{name}-%{version}-autostart-timeout.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://libvirt.org/ BuildRequires: python python-devel @@ -183,6 +186,9 @@ of recent versions of Linux (and other OSes). %setup -q %patch1 -p1 %patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 mv NEWS NEWS.old iconv -f ISO-8859-1 -t UTF-8 < NEWS.old > NEWS @@ -471,6 +477,11 @@ fi %endif %changelog +* Wed Feb 18 2009 Daniel P. Berrange - 0.6.0-4.fc11 +- Fix QEMU startup timeout/race (rhbz #484649) +- Setup DBus threading. Don't allow dbus to call _exit / change SIGPIPE (rhbz #484553) +- Fix timeout when autostarting session daemon + * Wed Feb 11 2009 Richard W.M. Jones - 0.6.0-3.fc11 - Multiple fixes to remove rpmlint warnings/errors (rhbz #226055)