diff --git a/libvirt-dmidecode-hang.patch b/libvirt-dmidecode-hang.patch new file mode 100644 index 0000000..5d8f298 --- /dev/null +++ b/libvirt-dmidecode-hang.patch @@ -0,0 +1,153 @@ +commit 06b9c5b9231ef4dbd4b5ff69564305cd4f814879 +Author: Michal Privoznik +Date: Tue Jan 3 18:40:55 2012 +0100 + + virCommand: Properly handle POLLHUP + + It is a good practise to set revents to zero before doing any poll(). + Moreover, we should check if event we waited for really occurred or + if any of fds we were polling on didn't encountered hangup. + +diff --git a/src/util/command.c b/src/util/command.c +index f5effdf..bdaa88b 100644 +--- a/src/util/command.c ++++ b/src/util/command.c +@@ -1620,16 +1620,19 @@ virCommandProcessIO(virCommandPtr cmd) + if (infd != -1) { + fds[nfds].fd = infd; + fds[nfds].events = POLLOUT; ++ fds[nfds].revents = 0; + nfds++; + } + if (outfd != -1) { + fds[nfds].fd = outfd; + fds[nfds].events = POLLIN; ++ fds[nfds].revents = 0; + nfds++; + } + if (errfd != -1) { + fds[nfds].fd = errfd; + fds[nfds].events = POLLIN; ++ fds[nfds].revents = 0; + nfds++; + } + +@@ -1645,8 +1648,8 @@ virCommandProcessIO(virCommandPtr cmd) + } + + for (i = 0; i < nfds ; i++) { +- if (fds[i].fd == errfd || +- fds[i].fd == outfd) { ++ if (fds[i].revents & POLLIN && ++ (fds[i].fd == errfd || fds[i].fd == outfd)) { + char data[1024]; + char **buf; + size_t *len; +@@ -1684,7 +1687,10 @@ virCommandProcessIO(virCommandPtr cmd) + memcpy(*buf + *len, data, done); + *len += done; + } +- } else { ++ } ++ ++ if (fds[i].revents & POLLOUT && ++ fds[i].fd == infd) { + int done; + + /* Coverity 5.3.0 can't see that we only get here if +@@ -1710,6 +1716,18 @@ virCommandProcessIO(virCommandPtr cmd) + } + } + ++ if (fds[i].revents & (POLLHUP | POLLERR)) { ++ if (fds[i].fd == errfd) { ++ VIR_DEBUG("hangup on stderr"); ++ errfd = -1; ++ } else if (fds[i].fd == outfd) { ++ VIR_DEBUG("hangup on stdout"); ++ outfd = -1; ++ } else { ++ VIR_DEBUG("hangup on stdin"); ++ infd = -1; ++ } ++ } + } + } + +commit d19149dda888d36cea58b6cdf7446f98bd1bf734 +Author: Laszlo Ersek +Date: Tue Jan 24 15:55:19 2012 +0100 + + virCommandProcessIO(): make poll() usage more robust + + POLLIN and POLLHUP are not mutually exclusive. Currently the following + seems possible: the child writes 3K to its stdout or stderr pipe, and + immediately closes it. We get POLLIN|POLLHUP (I'm not sure that's possible + on Linux, but SUSv4 seems to allow it). We read 1K and throw away the + rest. + + When poll() returns and we're about to check the /revents/ member in a + given array element, let's map all the revents bits to two (independent) + ideas: "let's attempt to read()", and "let's attempt to write()". This + should cover all errors, EOFs, and normal conditions; the read()/write() + call should report any pending error. + + Under this approach, both POLLHUP and POLLERR are mapped to "needs read()" + if we're otherwise prepared for POLLIN. POLLERR also maps to "needs + write()" if we're otherwise prepared for POLLOUT. The rest of the mappings + (POLLPRI etc.) would be easy, but probably useless for pipes. + + Additionally, SUSv4 doesn't appear to forbid POLLIN|POLLERR (or + POLLOUT|POLLERR) set simultaneously. One could argue that the read() or + write() call would return without blocking in these cases (with an error), + so POLLIN / POLLOUT would be justified beside POLLERR. + + The code now penalizes POLLIN|POLLERR differently from plain POLLERR. The + former (ie. read() returning -1) is terminal and we jump to cleanup, while + plain POLLERR masks only the affected file descriptor for the future. + Let's unify those. + + Signed-off-by: Laszlo Ersek + +diff --git a/src/util/command.c b/src/util/command.c +index f05493e..dc3cfc5 100644 +--- a/src/util/command.c ++++ b/src/util/command.c +@@ -1710,7 +1710,7 @@ virCommandProcessIO(virCommandPtr cmd) + } + + for (i = 0; i < nfds ; i++) { +- if (fds[i].revents & POLLIN && ++ if (fds[i].revents & (POLLIN | POLLHUP | POLLERR) && + (fds[i].fd == errfd || fds[i].fd == outfd)) { + char data[1024]; + char **buf; +@@ -1751,7 +1751,7 @@ virCommandProcessIO(virCommandPtr cmd) + } + } + +- if (fds[i].revents & POLLOUT && ++ if (fds[i].revents & (POLLOUT | POLLERR) && + fds[i].fd == infd) { + int done; + +@@ -1777,19 +1777,6 @@ virCommandProcessIO(virCommandPtr cmd) + } + } + } +- +- if (fds[i].revents & (POLLHUP | POLLERR)) { +- if (fds[i].fd == errfd) { +- VIR_DEBUG("hangup on stderr"); +- errfd = -1; +- } else if (fds[i].fd == outfd) { +- VIR_DEBUG("hangup on stdout"); +- outfd = -1; +- } else { +- VIR_DEBUG("hangup on stdin"); +- infd = -1; +- } +- } + } + } + diff --git a/libvirt-empty-lvm-hang.patch b/libvirt-empty-lvm-hang.patch new file mode 100644 index 0000000..ec3a081 --- /dev/null +++ b/libvirt-empty-lvm-hang.patch @@ -0,0 +1,36 @@ +commit 275155f664614fd32bcf5e963488e6f97b66dae4 +Author: Cole Robinson +Date: Wed Jan 25 12:07:14 2012 -0500 + + storage: Fix any VolLookupByPath if we have an empty logical pool + + On F16 at least, empty volume groups don't have a directory under /dev. + The directory only appears once a logical volume is created. + + This tickles some behavior in BackendStablePath which ends with + libvirt sleeping for 5 seconds while waiting for the directory to appear. + This causes all sorts of problems for the virStorageVolLookupByPath API + which virtinst uses, even if trying to resolve a path that is independent + of the logical pool. + + In reality we don't even need to do that checking since logical pools + always have a stable target path. Short circuit the polling in that + case. + + Fixes bug 782261 + +diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c +index d7394e0..306e487 100644 +--- a/src/storage/storage_backend.c ++++ b/src/storage/storage_backend.c +@@ -1347,6 +1347,10 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, + if (!STRPREFIX(pool->def->target.path, "/dev")) + goto ret_strdup; + ++ /* Logical pools are under /dev but already have stable paths */ ++ if (pool->def->type == VIR_STORAGE_POOL_LOGICAL) ++ goto ret_strdup; ++ + /* We loop here because /dev/disk/by-{id,path} may not have existed + * before we started this operation, so we have to give it some time to + * get created. diff --git a/libvirt-gnutls-test-failures.patch b/libvirt-gnutls-test-failures.patch new file mode 100644 index 0000000..ce740d0 --- /dev/null +++ b/libvirt-gnutls-test-failures.patch @@ -0,0 +1,72 @@ +commit 74ff57506c762f7c1f2bdbcce55f6d620687caab +Author: Eric Blake +Date: Fri Jan 6 14:07:23 2012 -0700 + + tests: avoid test failure on rawhide gnutls + + I hit a VERY weird testsuite failure on rawhide, which included + _binary_ output to stderr, followed by a hang waiting for me + to type something! (Here, using ^@ for NUL): + + $ ./commandtest + TEST: commandtest + WARNING: gnome-keyring:: couldn't send data: Bad file descriptor + .WARNING: gnome-keyring:: couldn't send data: Bad file descriptor + .WARNING: gnome-keyring:: couldn't send data: Bad file descriptor + WARNING: gnome-keyring:: couldn't send data: Bad file descriptor + .8^@^@^@8^@^@^@^A^@^@^@^Bay^A^@^@^@)PRIVATE-GNOME-KEYRING-PKCS11-PROTOCOL-V-1 + + I finally traced it to the fact that gnome-keyring, called via + gnutls_global_init which is turn called by virNetTLSInit, opens + an internal fd that it expects to communicate to via a + pthread_atfork handler (never mind that it violates POSIX by + using non-async-signal-safe functions in that handler: + https://bugzilla.redhat.com/show_bug.cgi?id=772320). + + Our problem stems from the fact that we pulled the rug out from + under the library's expectations by closing an fd that it had + just opened. While we aren't responsible for fixing the bugs + in that pthread_atfork handler, we can at least avoid the bugs + by not closing the fd in the first place. + + * tests/commandtest.c (mymain): Avoid closing fds that were opened + by virInitialize. + +diff --git a/tests/commandtest.c b/tests/commandtest.c +index efc48fe..b4b6044 100644 +--- a/tests/commandtest.c ++++ b/tests/commandtest.c +@@ -784,6 +784,22 @@ mymain(void) + setpgid(0, 0); + setsid(); + ++ /* Our test expects particular fd values; to get that, we must not ++ * leak fds that we inherited from a lazy parent. At the same ++ * time, virInitialize may open some fds (perhaps via third-party ++ * libraries that it uses), and we must not kill off an fd that ++ * this process opens as it might break expectations of a ++ * pthread_atfork handler, as well as interfering with our tests ++ * trying to ensure we aren't leaking to our children. The ++ * solution is to do things in two phases - reserve the fds we ++ * want by overwriting any externally inherited fds, then ++ * initialize, then clear the slots for testing. */ ++ if ((fd = open("/dev/null", O_RDONLY)) < 0 || ++ dup2(fd, 3) < 0 || ++ dup2(fd, 4) < 0 || ++ dup2(fd, 5) < 0 || ++ (fd > 5 && VIR_CLOSE(fd) < 0)) ++ return EXIT_FAILURE; + + /* Prime the debug/verbose settings from the env vars, + * since we're about to reset 'environ' */ +@@ -791,8 +807,8 @@ mymain(void) + virTestGetVerbose(); + + virInitialize(); +- /* Kill off any inherited fds that might interfere with our +- * testing. */ ++ ++ /* Phase two of killing interfering fds; see above. */ + fd = 3; + VIR_FORCE_CLOSE(fd); + fd = 4; diff --git a/libvirt-large-migrate-crash.patch b/libvirt-large-migrate-crash.patch new file mode 100644 index 0000000..5af41cd --- /dev/null +++ b/libvirt-large-migrate-crash.patch @@ -0,0 +1,199 @@ +commit 9bc9999b6eb815268798120d7fe8834d822f098d +Author: Michal Privoznik +Date: Tue Oct 11 10:40:36 2011 +0200 + + qemu: Check for domain being active on successful job acquire + + As this is needed. Although some functions check for domain + being active before obtaining job, we need to check it after, + because obtaining job unlocks domain object, during which + a state of domain can be changed. + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index a5be925..0e307e1 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -1948,9 +1948,18 @@ static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags) + + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) + goto cleanup; ++ ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, ++ "%s", _("domain is not running")); ++ goto endjob; ++ } ++ + qemuDomainObjEnterMonitorWithDriver(driver, vm); + ret = qemuMonitorInjectNMI(priv->mon); + qemuDomainObjExitMonitorWithDriver(driver, vm); ++ ++endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) { + vm = NULL; + goto cleanup; +@@ -4397,7 +4406,7 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom, + virDomainObjPtr vm; + char *ret = NULL; + unsigned long balloon; +- int err; ++ int err = 0; + + /* Flags checked by virDomainDefFormat */ + +@@ -4423,9 +4432,17 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom, + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_QUERY) < 0) + goto cleanup; + ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, ++ "%s", _("domain is not running")); ++ goto endjob; ++ } ++ + qemuDomainObjEnterMonitorWithDriver(driver, vm); + err = qemuMonitorGetBalloonInfo(priv->mon, &balloon); + qemuDomainObjExitMonitorWithDriver(driver, vm); ++ ++endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) { + vm = NULL; + goto cleanup; +@@ -7163,6 +7180,12 @@ qemudDomainBlockStatsFlags (virDomainPtr dom, + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) + goto cleanup; + ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, ++ "%s", _("domain is not running")); ++ goto endjob; ++ } ++ + qemuDomainObjEnterMonitor(driver, vm); + tmp = *nparams; + ret = qemuMonitorGetBlockStatsParamsNumber(priv->mon, nparams); +@@ -8682,6 +8705,12 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0) + goto cleanup; + ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, ++ "%s", _("domain is not running")); ++ goto endjob; ++ } ++ + VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth); + qemuDomainObjEnterMonitor(driver, vm); + ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth); +@@ -8690,6 +8719,7 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, + if (ret == 0) + priv->migMaxBandwidth = bandwidth; + ++endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) + vm = NULL; + } else { +@@ -8784,6 +8814,12 @@ qemuDomainSnapshotCreateActive(virConnectPtr conn, + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) + return -1; + ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, ++ "%s", _("domain is not running")); ++ goto endjob; ++ } ++ + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { + /* savevm monitor command pauses the domain emitting an event which + * confuses libvirt since it's not notified when qemu resumes the +@@ -8833,6 +8869,7 @@ cleanup: + _("resuming after snapshot failed")); + } + ++endjob: + if (vm && qemuDomainObjEndJob(driver, vm) == 0) { + /* Only possible if a transient vm quit while our locks were down, + * in which case we don't want to save snapshot metadata. */ +@@ -9055,6 +9092,13 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn, + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) + return -1; + ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, ++ "%s", _("domain is not running")); ++ goto endjob; ++ } ++ ++ + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { + /* In qemu, snapshot_blkdev on a single disk will pause cpus, + * but this confuses libvirt since notifications are not given +@@ -9137,12 +9181,14 @@ cleanup: + (persist && + virDomainSaveConfig(driver->configDir, vm->newDef) < 0)) + ret = -1; +- if (qemuDomainObjEndJob(driver, vm) == 0) { ++ } ++ ++endjob: ++ if (vm && (qemuDomainObjEndJob(driver, vm) == 0)) { + /* Only possible if a transient vm quit while our locks were down, + * in which case we don't want to save snapshot metadata. */ + *vmptr = NULL; + ret = -1; +- } + } + + return ret; +@@ -10286,20 +10332,28 @@ static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd, + goto cleanup; + } + ++ if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) ++ goto cleanup; ++ ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("domain is not running")); ++ goto endjob; ++ } ++ + priv = vm->privateData; + + qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_CUSTOM_MONITOR, -1); + + hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP); + +- if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) +- goto cleanup; + qemuDomainObjEnterMonitorWithDriver(driver, vm); + ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp); + qemuDomainObjExitMonitorWithDriver(driver, vm); ++ ++endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) { + vm = NULL; +- goto cleanup; + } + + cleanup: +@@ -10536,10 +10590,19 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, + + if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) + goto cleanup; ++ ++ if (!virDomainObjIsActive(vm)) { ++ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("domain is not running")); ++ goto endjob; ++ } ++ + qemuDomainObjEnterMonitorWithDriver(driver, vm); + priv = vm->privateData; + ret = qemuMonitorBlockJob(priv->mon, device, bandwidth, info, mode); + qemuDomainObjExitMonitorWithDriver(driver, vm); ++ ++endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) { + vm = NULL; + goto cleanup; diff --git a/libvirt-no-init-hal-start.patch b/libvirt-no-init-hal-start.patch new file mode 100644 index 0000000..521ca9a --- /dev/null +++ b/libvirt-no-init-hal-start.patch @@ -0,0 +1,21 @@ +commit 2dcca3ec0a28c6562ebfbe7a5eae4729fb5de904 +Author: Peter Krempa +Date: Fri Mar 2 15:12:32 2012 +0100 + + daemon: Remove deprecated HAL from init script dependencies + + The init script for the daemon requests to start HAL although it has + been deprecated long time ago. This patch removes the dependency. + +diff --git a/daemon/libvirtd.init.in b/daemon/libvirtd.init.in +index 3c49b1f..f66ddad 100644 +--- a/daemon/libvirtd.init.in ++++ b/daemon/libvirtd.init.in +@@ -8,7 +8,6 @@ + # Required-Start: $network messagebus + # Should-Start: $named + # Should-Start: xend +-# Should-Start: hal + # Should-Start: avahi-daemon + # Required-Stop: $network messagebus + # Should-Stop: $named diff --git a/libvirt.spec b/libvirt.spec index b761536..415b92c 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -243,7 +243,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 0.9.6 -Release: 4%{?dist}%{?extra_release} +Release: 5%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz @@ -264,6 +264,16 @@ Patch14:%{name}-%{version}-test-replace-deprecated-fedora-13-machine.patch Patch15:%{name}-%{version}-qemu-replace-deprecated-fedora-13-machine.patch Patch16:%{name}-%{version}-spec-make-it-easier-to-autoreconf-when-building-rpm.patch Patch17:%{name}-%{version}-Avoid-crash-in-shunloadtest.patch +# Fix crash when migrating many guests with vdsm (bz 785789) +Patch18: %{name}-large-migrate-crash.patch +# Fix libvirtd hang in vmware guest (bz 796451) +Patch19: %{name}-dmidecode-hang.patch +# Don't start HAL in init script (bz 789234) +Patch20: %{name}-no-init-hal-start.patch +# Fix storage lookup errors with empty lvm pool (bz 782261) +Patch21: %{name}-empty-lvm-hang.patch +# Fix test failures with new gnutls +Patch22: %{name}-gnutls-test-failures.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://libvirt.org/ @@ -601,6 +611,11 @@ of recent versions of Linux (and other OSes). %patch15 -p1 %patch16 -p1 %patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 %build %if ! %{with_xen} @@ -1209,6 +1224,13 @@ fi %endif %changelog +* Sun Mar 04 2012 Cole Robinson - 0.9.6-5 +- Fix crash when migrating many guests with vdsm (bz 785789) +- Fix libvirtd hang in vmware guest (bz 796451) +- Don't start HAL in init script (bz 789234) +- Fix storage lookup errors with empty lvm pool (bz 782261) +- Fix test failures with new gnutls + * Mon Dec 19 2011 Laine Stump - 0.9.6-4 - replace "fedora-13" machine type with "pc-0.14" to prepare systems for removal of "fedora-13" from qemu - Bug 754772