[libvirt/f16] Fix crash when migrating many guests with vdsm (bz 785789) Fix libvirtd hang in vmware guest (bz 796

Cole Robinson crobinso at fedoraproject.org
Sun Mar 4 15:53:33 UTC 2012


commit afd84ddc60c16650e7fc0cac7908ac3fe9c16d22
Author: Cole Robinson <crobinso at redhat.com>
Date:   Sun Mar 4 10:53:29 2012 -0500

    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

 libvirt-dmidecode-hang.patch       |  153 +++++++++++++++++++++++++++
 libvirt-empty-lvm-hang.patch       |   36 +++++++
 libvirt-gnutls-test-failures.patch |   72 +++++++++++++
 libvirt-large-migrate-crash.patch  |  199 ++++++++++++++++++++++++++++++++++++
 libvirt-no-init-hal-start.patch    |   21 ++++
 libvirt.spec                       |   24 ++++-
 6 files changed, 504 insertions(+), 1 deletions(-)
---
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 <mprivozn at redhat.com>
+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 <lersek at redhat.com>
+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 <lersek at redhat.com>
+
+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 <crobinso at redhat.com>
+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 <eblake at redhat.com>
+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 <mprivozn at redhat.com>
+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 <pkrempa at redhat.com>
+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 <crobinso at redhat.com> - 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 <laine at redhat.com> - 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


More information about the scm-commits mailing list