rpms/libvirt/F-12 libvirt-0.7.1-audio-config.patch, NONE, 1.1 libvirt-0.7.1-backing-perms.patch, NONE, 1.1 libvirt-0.7.1-caps-option.patch, NONE, 1.1 libvirt-0.7.1-fix-cgroup-crash.patch, NONE, 1.1 libvirt-0.7.1-fix-usb-parsing.patch, NONE, 1.1 libvirt-0.7.1-lxc-uri-crash.patch, NONE, 1.1 libvirt-0.7.1-man-page-list.patch, NONE, 1.1 libvirt-0.7.1-migrate-errreport.patch, NONE, 1.1 libvirt-0.7.1-network-collision.patch, NONE, 1.1 libvirt-0.7.1-sanitize-pool.patch, NONE, 1.1 libvirt.spec, 1.196, 1.197

Cole Robinson crobinso at fedoraproject.org
Thu Jun 17 15:39:43 UTC 2010


Author: crobinso

Update of /cvs/pkgs/rpms/libvirt/F-12
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv2069

Modified Files:
	libvirt.spec 
Added Files:
	libvirt-0.7.1-audio-config.patch 
	libvirt-0.7.1-backing-perms.patch 
	libvirt-0.7.1-caps-option.patch 
	libvirt-0.7.1-fix-cgroup-crash.patch 
	libvirt-0.7.1-fix-usb-parsing.patch 
	libvirt-0.7.1-lxc-uri-crash.patch 
	libvirt-0.7.1-man-page-list.patch 
	libvirt-0.7.1-migrate-errreport.patch 
	libvirt-0.7.1-network-collision.patch 
	libvirt-0.7.1-sanitize-pool.patch 
Log Message:
Fix attach-device crash on cgroup cleanup (bz 556791)
Fix crash on bad LXC URI (bz 554191)
Add qemu.conf options for audio workaround
Fix permissions of storage backing stores (bz 579067)
Fix parsing certain USB sysfs files (bz 598272)
Improve migration error reporting (bz 499750)
Sanitize pool target paths (bz 494005)
Add qemu.conf for clear emulator capabilities


libvirt-0.7.1-audio-config.patch:
 qemud/libvirtd.init.in       |    3 +++
 qemud/libvirtd.sysconf       |    3 ++-
 qemud/libvirtd_qemu.aug      |    1 +
 qemud/test_libvirtd_qemu.aug |    6 +++++-
 src/qemu.conf                |   10 ++++++++++
 src/qemu_conf.c              |   17 ++++++++++++-----
 src/qemu_conf.h              |    2 ++
 7 files changed, 35 insertions(+), 7 deletions(-)

--- NEW FILE libvirt-0.7.1-audio-config.patch ---
diff -rup libvirt-0.7.1/qemud/libvirtd.init.in audio/qemud/libvirtd.init.in
--- libvirt-0.7.1/qemud/libvirtd.init.in	2009-07-22 09:37:32.000000000 -0400
+++ audio/qemud/libvirtd.init.in	2010-05-26 12:05:50.584822000 -0400
@@ -47,6 +47,9 @@ KRB5_KTNAME=/etc/libvirt/krb5.tab
 
 test -f @sysconfdir@/sysconfig/libvirtd && . @sysconfdir@/sysconfig/libvirtd
 
+export QEMU_AUDIO_DRV
+export SDL_AUDIODRIVER
+
 LIBVIRTD_CONFIG_ARGS=
 if [ -n "$LIBVIRTD_CONFIG" ]
 then
diff -rup libvirt-0.7.1/qemud/libvirtd_qemu.aug audio/qemud/libvirtd_qemu.aug
--- libvirt-0.7.1/qemud/libvirtd_qemu.aug	2009-09-08 10:16:02.000000000 -0400
+++ audio/qemud/libvirtd_qemu.aug	2010-05-26 12:07:24.169216000 -0400
@@ -36,6 +36,7 @@ module Libvirtd_qemu =
                  | str_array_entry "cgroup_device_acl"
                  | str_entry "save_image_format"
                  | str_entry "hugetlbfs_mount"
+                 | bool_entry "vnc_allow_host_audio"
 
    (* Each enty in the config is one of the following three ... *)
    let entry = vnc_entry
diff -rup libvirt-0.7.1/qemud/libvirtd.sysconf audio/qemud/libvirtd.sysconf
--- libvirt-0.7.1/qemud/libvirtd.sysconf	2010-05-26 12:04:08.379130000 -0400
+++ audio/qemud/libvirtd.sysconf	2010-05-26 12:10:28.263486000 -0400
@@ -11,7 +11,8 @@
 # Override the QEMU/SDL default audio driver probing when
 # starting virtual machines using SDL graphics
 #
-# NB these have no effect for VMs using VNC
+# NB these have no effect for VMs using VNC, unless vnc_allow_host_audio
+# is enabled in /etc/libvirt/qemu.conf
 #QEMU_AUDIO_DRV=sdl
 #
 #SDL_AUDIODRIVER=pulse
diff -rup libvirt-0.7.1/qemud/test_libvirtd_qemu.aug audio/qemud/test_libvirtd_qemu.aug
--- libvirt-0.7.1/qemud/test_libvirtd_qemu.aug	2009-09-08 10:16:02.000000000 -0400
+++ audio/qemud/test_libvirtd_qemu.aug	2010-05-26 12:11:19.540907000 -0400
@@ -92,6 +92,8 @@ cgroup_device_acl = [ \"/dev/null\", \"/
 
 save_image_format = \"gzip\"
 
+vnc_allow_host_audio = 1
+
 hugetlbfs_mount = \"/dev/hugepages\"
 "
 
@@ -195,4 +197,6 @@ hugetlbfs_mount = \"/dev/hugepages\"
 { "#empty" }
 { "save_image_format" = "gzip" }
 { "#empty" }
-{ "hugetlbfs_mount" = "/dev/hugepages" }
\ No newline at end of file
+{ "hugetlbfs_mount" = "/dev/hugepages" }
+{ "#empty" }
+{ "vnc_allow_host_audio" = "1" }
diff -rup libvirt-0.7.1/src/qemu.conf audio/src/qemu.conf
--- libvirt-0.7.1/src/qemu.conf	2009-09-10 05:15:56.000000000 -0400
+++ audio/src/qemu.conf	2010-05-26 12:08:12.419811000 -0400
@@ -152,3 +152,13 @@
 # in a location of  $MOUNTPOINT/libvirt/qemu
 
 # hugetlbfs_mount = "/dev/hugepages"
+#
+
+# QEMU implements an extension for providing audio over a VNC connection,
+# though if your VNC client does not support it, your only chance for getting
+# sound output is through regular audio backends. By default, libvirt will
+# disable all QEMU sound backends if using VNC, since they can cause
+# permissions issues. Enabling this option will make libvirtd honor the
+# QEMU_AUDIO_DRV environment variable when using VNC.
+#
+# vnc_allow_host_audio = 0
diff -rup libvirt-0.7.1/src/qemu_conf.c audio/src/qemu_conf.c
--- libvirt-0.7.1/src/qemu_conf.c	2010-05-26 12:04:08.578062000 -0400
+++ audio/src/qemu_conf.c	2010-05-26 12:09:31.174206000 -0400
@@ -318,6 +318,10 @@ int qemudLoadDriverConfig(struct qemud_d
          }
      }
 
+    p = virConfGetValue (conf, "vnc_allow_host_audio");
+    CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
+    if (p) driver->vncAllowHostAudio = p->l;
+
     virConfFree (conf);
     return 0;
 }
@@ -2113,12 +2117,15 @@ int qemudBuildCommandLine(virConnectPtr 
             ADD_ARG_LIT(def->graphics[0]->data.vnc.keymap);
         }
 
-        /* QEMU implements a VNC extension for providing audio, so we
-         * set the audio backend to none, to prevent it opening the
-         * host OS audio devices since that causes security issues
-         * and is non-sensical when using VNC.
+        /* Unless user requested it, set the audio backend to none, to
+         * prevent it opening the host OS audio devices, since that causes
+         * security issues and might not work when using VNC.
          */
-        ADD_ENV_LIT("QEMU_AUDIO_DRV=none");
+        if (driver->vncAllowHostAudio) {
+            ADD_ENV_COPY("QEMU_AUDIO_DRV");
+        } else {
+            ADD_ENV_LIT("QEMU_AUDIO_DRV=none");
+        }
     } else if ((def->ngraphics == 1) &&
                def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
         char *xauth = NULL;
diff -rup libvirt-0.7.1/src/qemu_conf.h audio/src/qemu_conf.h
--- libvirt-0.7.1/src/qemu_conf.h	2009-09-10 09:45:00.000000000 -0400
+++ audio/src/qemu_conf.h	2010-05-26 12:10:07.196992000 -0400
@@ -110,6 +110,8 @@ struct qemud_driver {
     char *hugetlbfs_mount;
     char *hugepage_path;
 
+    unsigned int vncAllowHostAudio : 1;
+
     virCapsPtr caps;
 
     /* An array of callbacks */

libvirt-0.7.1-backing-perms.patch:
 qemu_driver.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

--- NEW FILE libvirt-0.7.1-backing-perms.patch ---
--- libvirt-0.7.1/src/qemu_driver.c	2010-06-17 11:30:54.501983000 -0400
+++ new/src/qemu_driver.c	2010-06-17 11:20:13.032900000 -0400
@@ -69,7 +69,7 @@
 #include "hostusb.h"
 #include "security.h"
 #include "cgroup.h"
-
+#include "storage_file.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -1895,6 +1895,7 @@ static int qemuDomainSetDeviceOwnership(
 {
     uid_t uid;
     gid_t gid;
+    const char *path;
 
     if (!driver->privileged)
         return 0;
@@ -1912,6 +1913,35 @@ static int qemuDomainSetDeviceOwnership(
             (def->data.disk->readonly || def->data.disk->shared))
             return 0;
 
+        if (!def->data.disk->src)
+            return 0;
+
+        path = def->data.disk->src;
+        do {
+            virStorageFileMetadata meta;
+            int ret;
+
+            memset(&meta, 0, sizeof(meta));
+
+            ret = virStorageFileGetMetadata(conn, path, &meta);
+
+            if (path != def->data.disk->src)
+                VIR_FREE(path);
+            path = NULL;
+
+            if (ret < 0)
+                return -1;
+
+            if (meta.backingStore != NULL &&
+                qemuDomainSetFileOwnership(conn,
+                                           meta.backingStore, uid, gid) < 0) {
+                VIR_FREE(meta.backingStore);
+                return -1;
+            }
+
+            path = meta.backingStore;
+        } while (path != NULL);
+
         return qemuDomainSetFileOwnership(conn, def->data.disk->src, uid, gid);
 
     case VIR_DOMAIN_DEVICE_HOSTDEV:
@@ -1929,6 +1959,7 @@ static int qemuDomainSetAllDeviceOwnersh
     int i;
     uid_t uid;
     gid_t gid;
+    const char *path;
 
     if (!driver->privileged)
         return 0;
@@ -1949,6 +1980,35 @@ static int qemuDomainSetAllDeviceOwnersh
             (def->disks[i]->readonly || def->disks[i]->shared))
             continue;
 
+        if (!def->disks[i]->src)
+            continue;
+
+        path = def->disks[i]->src;
+        do {
+            virStorageFileMetadata meta;
+            int ret;
+
+            memset(&meta, 0, sizeof(meta));
+
+            ret = virStorageFileGetMetadata(conn, path, &meta);
+
+            if (path != def->disks[i]->src)
+                VIR_FREE(path);
+            path = NULL;
+
+            if (ret < 0)
+                return -1;
+
+            if (meta.backingStore != NULL &&
+                qemuDomainSetFileOwnership(conn,
+                                           meta.backingStore, uid, gid) < 0) {
+                VIR_FREE(meta.backingStore);
+                return -1;
+            }
+
+            path = meta.backingStore;
+        } while (path != NULL);
+
         if (qemuDomainSetFileOwnership(conn, def->disks[i]->src, uid, gid) < 0)
             return -1;
     }

libvirt-0.7.1-caps-option.patch:
 qemu.conf     |    9 +++++++++
 qemu_conf.c   |    8 +++++++-
 qemu_conf.h   |    1 +
 qemu_driver.c |   11 +++++++++--
 4 files changed, 26 insertions(+), 3 deletions(-)

--- NEW FILE libvirt-0.7.1-caps-option.patch ---
diff -rup libvirt-0.7.1/src/qemu.conf new/src/qemu.conf
--- libvirt-0.7.1/src/qemu.conf	2010-06-03 15:01:14.288848000 -0400
+++ new/src/qemu.conf	2010-06-03 15:04:05.062031000 -0400
@@ -162,3 +162,12 @@
 # QEMU_AUDIO_DRV environment variable when using VNC.
 #
 # vnc_allow_host_audio = 0
+
+# If clear_emulator_capabilities is enabled, libvirt will drop all
+# privileged capabilities of the QEmu/KVM emulator. This is enabled by
+# default.
+#
+# Warning: Disabling this option means that a compromised guest can
+# exploit the privileges and possibly do damage to the host.
+#
+# clear_emulator_capabilities = 1
diff -rup libvirt-0.7.1/src/qemu_conf.c new/src/qemu_conf.c
--- libvirt-0.7.1/src/qemu_conf.c	2010-06-03 15:01:14.302852000 -0400
+++ new/src/qemu_conf.c	2010-06-03 15:05:09.755183000 -0400
@@ -98,7 +98,9 @@ int qemudLoadDriverConfig(struct qemud_d
     char *group;
     int i;
 
-    /* Setup 2 critical defaults */
+    /* Setup critical defaults */
+    driver->clearEmulatorCapabilities = 1;
+
     if (!(driver->vncListen = strdup("127.0.0.1"))) {
         virReportOOMError(NULL);
         return -1;
@@ -322,6 +324,10 @@ int qemudLoadDriverConfig(struct qemud_d
     CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
     if (p) driver->vncAllowHostAudio = p->l;
 
+    p = virConfGetValue (conf, "clear_emulator_capabilities");
+    CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
+    if (p) driver->clearEmulatorCapabilities = p->l;
+
     virConfFree (conf);
     return 0;
 }
diff -rup libvirt-0.7.1/src/qemu_conf.h new/src/qemu_conf.h
--- libvirt-0.7.1/src/qemu_conf.h	2010-06-03 15:01:14.306860000 -0400
+++ new/src/qemu_conf.h	2010-06-03 15:05:27.968796000 -0400
@@ -111,6 +111,7 @@ struct qemud_driver {
     char *hugepage_path;
 
     unsigned int vncAllowHostAudio : 1;
+    unsigned int clearEmulatorCapabilities : 1;
 
     virCapsPtr caps;
 
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c	2010-06-03 15:01:14.413848000 -0400
+++ new/src/qemu_driver.c	2010-06-03 15:06:08.186798000 -0400
@@ -2063,7 +2063,7 @@ static int qemudStartVMDaemon(virConnect
                               int stdin_fd) {
     const char **argv = NULL, **tmp;
     const char **progenv = NULL;
-    int i, ret;
+    int i, ret, runflags;
     struct stat sb;
     int *tapfds = NULL;
     int ntapfds = 0;
@@ -2205,9 +2205,16 @@ static int qemudStartVMDaemon(virConnect
     for (i = 0 ; i < ntapfds ; i++)
         FD_SET(tapfds[i], &keepfd);
 
+    VIR_DEBUG("Clear emulator capabilities: %d",
+              driver->clearEmulatorCapabilities);
+    runflags = VIR_EXEC_NONBLOCK;
+    if (driver->clearEmulatorCapabilities) {
+        runflags |= VIR_EXEC_CLEAR_CAPS;
+    }
+
     ret = virExecDaemonize(conn, argv, progenv, &keepfd, &child,
                            stdin_fd, &logfile, &logfile,
-                           VIR_EXEC_NONBLOCK | VIR_EXEC_CLEAR_CAPS,
+                           runflags,
                            qemudSecurityHook, &hookData,
                            pidfile);
     VIR_FREE(pidfile);

libvirt-0.7.1-fix-cgroup-crash.patch:
 qemu_driver.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE libvirt-0.7.1-fix-cgroup-crash.patch ---
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c	2010-06-03 13:51:14.398483000 -0400
+++ new/src/qemu_driver.c	2010-06-03 13:56:05.667092000 -0400
@@ -5988,7 +5988,7 @@ static int qemudDomainAttachDevice(virDo
                              virDomainDiskDeviceTypeToString(dev->data.disk->device));
             /* Fallthrough */
         }
-        if (ret != 0) {
+        if (ret != 0 && cgroup) {
             virCgroupDenyDevicePath(cgroup,
                                     dev->data.disk->src);
         }

libvirt-0.7.1-fix-usb-parsing.patch:
 qemu_driver.c |only
 src/hostusb.c |    2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE libvirt-0.7.1-fix-usb-parsing.patch ---
Only in new: qemu_driver.c
diff -rup libvirt-0.7.1/src/hostusb.c new/src/hostusb.c
--- libvirt-0.7.1/src/hostusb.c	2010-06-03 13:51:14.392459000 -0400
+++ new/src/hostusb.c	2010-06-03 14:49:11.763379000 -0400
@@ -123,7 +123,7 @@ static int usbFindBusByVendor(virConnect
             char *tmpstr = de->d_name;
             unsigned found_bus, found_addr;
 
-            if (STREQ(de->d_name, "usb"))
+            if (STRPREFIX(de->d_name, "usb"))
                 tmpstr += 3;
 
             if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) {

libvirt-0.7.1-lxc-uri-crash.patch:
 lxc_driver.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- NEW FILE libvirt-0.7.1-lxc-uri-crash.patch ---
diff -rup libvirt-0.7.1/src/lxc_driver.c new/src/lxc_driver.c
--- libvirt-0.7.1/src/lxc_driver.c	2009-09-10 09:45:00.000000000 -0400
+++ new/src/lxc_driver.c	2010-06-03 15:03:11.524069000 -0400
@@ -96,7 +96,8 @@ static virDrvOpenStatus lxcOpen(virConne
             return VIR_DRV_OPEN_DECLINED;
 
         /* If path isn't '/' then they typoed, tell them correct path */
-        if (STRNEQ(conn->uri->path, "/")) {
+        if (conn->uri->path != NULL &&
+            STRNEQ(conn->uri->path, "/")) {
             lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
                      _("unexpected LXC URI path '%s', try lxc:///"),
                      conn->uri->path);

libvirt-0.7.1-man-page-list.patch:
 virsh.pod |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

--- NEW FILE libvirt-0.7.1-man-page-list.patch ---
commit e5f31f461f63bbad211e84b810d6ba43a705f9dd
Author: Justin Clift <justin at salasaga.org>
Date:   Sun May 30 13:28:42 2010 +1000

    Trivial virsh.pod additions --all for "list" command and similar
    
    This is just a trivial patch to virsh.pod (from git master). It adds the
    following pieces to the virsh man page:
    
      + Shows the --inactive and --all optional parameters for the list
        command.
    
        Closes Bugzilla #575512, reported by Renich Bon Ciric
        https://bugzilla.redhat.com/show_bug.cgi?id=575512
    
      + Corrects the existing description of the list command, to now say
        that only running domains are listed if no domains are specified.
    
        The man page up until this point has said all domains are listed if
        no domains are specified, which is incorrect.
    
      + Adds the "shut off" state to the list of states for the list
        command.
    
      + Adds a missing =back around line 755, that pod2man was complaining
        was missing.

diff --git a/tools/virsh.pod b/tools/virsh.pod
index cf7585d..495bb46 100644
--- a/docs/virsh.pod
+++ b/docs/virsh.pod
@@ -156,10 +156,10 @@ description see:
   L<http://libvirt.org/formatcaps.html>
 The XML also show the NUMA topology information if available.
 
-=item B<list>
+=item B<list> optional I<--inactive> I<--all>
 
 Prints information about one or more domains.  If no domains are
-specified it prints out information about all domains.
+specified it prints out information about running domains.
 
 An example format for the list is as follows:
 
@@ -177,7 +177,7 @@ State is the run state (see below).
 
 B<STATES>
 
-The State field lists 6 states for a domain, and which ones the
+The State field lists 7 states for a domain, and which ones the
 current domain is in.
 
 =over 4
@@ -205,6 +205,11 @@ The domain is in the process of shutting down, i.e. the guest operating system
 has been notified and should be in the process of stopping its operations
 gracefully.
 
+=item B<shut off>
+
+The domain is not running.  Usually this indicates the domain has been
+shut down completely, or has not been started.
+
 =item B<crashed>
 
 The domain has crashed, which is always a violent ending.  Usually

libvirt-0.7.1-migrate-errreport.patch:
 libvirt.c            |   26 ++++++++------
 libvirt_private.syms |    1 
 qemu_driver.c        |   18 +++++++++
 util.c               |   67 ++++++++++++++++++++++++++++++++-----
 virterror.c          |   92 ++++++++++++++++++++++++++++++++++++++-------------
 virterror_internal.h |    2 +
 6 files changed, 164 insertions(+), 42 deletions(-)

--- NEW FILE libvirt-0.7.1-migrate-errreport.patch ---
diff -rup libvirt-0.7.1/src/libvirt.c new/src/libvirt.c
--- libvirt-0.7.1/src/libvirt.c	2010-06-03 15:30:32.615164000 -0400
+++ new/src/libvirt.c	2010-06-03 15:33:22.863409000 -0400
@@ -3054,6 +3054,7 @@ virDomainMigrateVersion2 (virDomainPtr d
     char *cookie = NULL;
     char *dom_xml = NULL;
     int cookielen = 0, ret;
+    virErrorPtr orig_err = NULL;
 
     /* Prepare the migration.
      *
@@ -3102,6 +3103,10 @@ virDomainMigrateVersion2 (virDomainPtr d
     ret = domain->conn->driver->domainMigratePerform
         (domain, cookie, cookielen, uri, flags, dname, bandwidth);
 
+    /* Perform failed. Make sure Finish doesn't overwrite the error */
+    if (ret < 0)
+        orig_err = virSaveLastError();
+
     /* In version 2 of the migration protocol, we pass the
      * status code from the sender to the destination host,
      * so it can do any cleanup if the migration failed.
@@ -3111,6 +3116,10 @@ virDomainMigrateVersion2 (virDomainPtr d
         (dconn, dname, cookie, cookielen, uri, flags, ret);
 
  done:
+    if (orig_err) {
+        virSetError(orig_err);
+        virFreeError(orig_err);
+    }
     VIR_FREE (uri_out);
     VIR_FREE (cookie);
     return ddomain;
@@ -3222,7 +3231,7 @@ virDomainMigrate (virDomainPtr domain,
 
 error:
     /* Copy to connection error object for back compatability */
-    virSetConnError(domain->conn);
+    virDispatchError(domain->conn);
     return NULL;
 }
 
@@ -3269,8 +3278,7 @@ virDomainMigratePrepare (virConnectPtr d
     virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
 
 error:
-    /* Copy to connection error object for back compatability */
-    virSetConnError(dconn);
+    virDispatchError(dconn);
     return -1;
 }
 
@@ -3318,8 +3326,7 @@ virDomainMigratePerform (virDomainPtr do
     virLibDomainError (domain, VIR_ERR_NO_SUPPORT, __FUNCTION__);
 
 error:
-    /* Copy to connection error object for back compatability */
-    virSetConnError(domain->conn);
+    virDispatchError(domain->conn);
     return -1;
 }
 
@@ -3364,8 +3371,7 @@ virDomainMigrateFinish (virConnectPtr dc
     virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
 
 error:
-    /* Copy to connection error object for back compatability */
-    virSetConnError(dconn);
+    virDispatchError(dconn);
     return NULL;
 }
 
@@ -3416,8 +3422,7 @@ virDomainMigratePrepare2 (virConnectPtr 
     virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
 
 error:
-    /* Copy to connection error object for back compatability */
-    virSetConnError(dconn);
+    virDispatchError(dconn);
     return -1;
 }
 
@@ -3464,8 +3469,7 @@ virDomainMigrateFinish2 (virConnectPtr d
     virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
 
 error:
-    /* Copy to connection error object for back compatability */
-    virSetConnError(dconn);
+    virDispatchError(dconn);
     return NULL;
 }
 
diff -rup libvirt-0.7.1/src/libvirt_private.syms new/src/libvirt_private.syms
--- libvirt-0.7.1/src/libvirt_private.syms	2010-06-03 15:30:33.051186000 -0400
+++ new/src/libvirt_private.syms	2010-06-03 15:33:22.869400000 -0400
@@ -461,6 +461,7 @@ virRaiseErrorFull;
 virReportSystemErrorFull;
 virReportOOMErrorFull;
 virStrerror;
+virSetError;
 
 
 # xml.h
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c	2010-06-03 15:30:33.111159000 -0400
+++ new/src/qemu_driver.c	2010-06-03 15:35:22.809404000 -0400
@@ -2297,12 +2297,17 @@ static void qemudShutdownVMDaemon(virCon
                                   virDomainObjPtr vm) {
     int ret;
     int retries = 0;
+    virErrorPtr orig_err;
 
     if (!virDomainIsActive(vm))
         return;
 
     VIR_DEBUG(_("Shutting down VM '%s'\n"), vm->def->name);
 
+    /* This method is routinely used in clean up paths. Disable error
+     * reporting so we don't squash a legit error. */
+    orig_err = virSaveLastError();
+
     if (virKillProcess(vm->pid, 0) == 0 &&
         virKillProcess(vm->pid, SIGTERM) < 0)
         virReportSystemError(conn, errno,
@@ -2377,6 +2382,11 @@ retry:
         vm->def->id = -1;
         vm->newDef = NULL;
     }
+
+    if (orig_err) {
+        virSetError(orig_err);
+        virFreeError(orig_err);
+    }
 }
 
 
@@ -7497,6 +7507,10 @@ qemudDomainMigrateFinish2 (virConnectPtr
     virDomainObjPtr vm;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
+    virErrorPtr orig_err;
+
+    /* Migration failed. Save the current error so nothing squashes it */
+    orig_err = virSaveLastError();
 
     qemuDriverLock(driver);
     vm = virDomainFindByName(&driver->domains, dname);
@@ -7540,6 +7554,10 @@ qemudDomainMigrateFinish2 (virConnectPtr
     }
 
 cleanup:
+    if (orig_err) {
+        virSetError(orig_err);
+        virFreeError(orig_err);
+    }
     if (vm)
         virDomainObjUnlock(vm);
     if (event)
diff -rup libvirt-0.7.1/src/util.c new/src/util.c
--- libvirt-0.7.1/src/util.c	2010-06-03 15:30:33.064159000 -0400
+++ new/src/util.c	2010-06-03 15:33:22.881417000 -0400
@@ -1764,31 +1764,82 @@ int virDiskNameToIndex(const char *name)
 #define AI_CANONIDN 0
 #endif
 
-char *virGetHostname(void)
+/* Who knew getting a hostname could be so delicate.  In Linux (and Unices
+ * in general), many things depend on "hostname" returning a value that will
+ * resolve one way or another.  In the modern world where networks frequently
+ * come and go this is often being hard-coded to resolve to "localhost".  If
+ * it *doesn't* resolve to localhost, then we would prefer to have the FQDN.
+ * That leads us to 3 possibilities:
+ *
+ * 1)  gethostname() returns an FQDN (not localhost) - we return the string
+ *     as-is, it's all of the information we want
+ * 2)  gethostname() returns "localhost" - we return localhost; doing further
+ *     work to try to resolve it is pointless
+ * 3)  gethostname() returns a shortened hostname - in this case, we want to
+ *     try to resolve this to a fully-qualified name.  Therefore we pass it
+ *     to getaddrinfo().  There are two possible responses:
+ *     a)  getaddrinfo() resolves to a FQDN - return the FQDN
+ *     b)  getaddrinfo() resolves to localhost - in this case, the data we got
+ *         from gethostname() is actually more useful than what we got from
+ *         getaddrinfo().  Return the value from gethostname() and hope for
+ *         the best.
+ */
+char *virGetHostname()
 {
     int r;
     char hostname[HOST_NAME_MAX+1], *result;
     struct addrinfo hints, *info;
 
     r = gethostname (hostname, sizeof(hostname));
-    if (r == -1)
+    if (r == -1) {
+        virReportSystemError(NULL, errno,
+                             "%s", _("failed to determine host name"));
         return NULL;
+    }
     NUL_TERMINATE(hostname);
 
+    if (STRPREFIX(hostname, "localhost") || strchr(hostname, '.')) {
+        /* in this case, gethostname returned localhost (meaning we can't
+         * do any further canonicalization), or it returned an FQDN (and
+         * we don't need to do any further canonicalization).  Return the
+         * string as-is; it's up to callers to check whether "localhost"
+         * is allowed.
+         */
+        result = strdup(hostname);
+        goto check_and_return;
+    }
+
+    /* otherwise, it's a shortened, non-localhost, hostname.  Attempt to
+     * canonicalize the hostname by running it through getaddrinfo
+     */
+
     memset(&hints, 0, sizeof(hints));
     hints.ai_flags = AI_CANONNAME|AI_CANONIDN;
     hints.ai_family = AF_UNSPEC;
     r = getaddrinfo(hostname, NULL, &hints, &info);
-    if (r != 0)
-        return NULL;
-    if (info->ai_canonname == NULL) {
-        freeaddrinfo(info);
+    if (r != 0) {
+        ReportError(NULL, VIR_ERR_INTERNAL_ERROR,
+                    _("getaddrinfo failed for '%s': %s"),
+                    hostname, gai_strerror(r));
         return NULL;
     }
 
-    /* Caller frees this string. */
-    result = strdup (info->ai_canonname);
+    if (info->ai_canonname == NULL ||
+        STRPREFIX(info->ai_canonname, "localhost"))
+        /* in this case, we tried to canonicalize and we ended up back with
+         * localhost.  Ignore the canonicalized name and just return the
+         * original hostname
+         */
+        result = strdup(hostname);
+    else
+        /* Caller frees this string. */
+        result = strdup (info->ai_canonname);
+
     freeaddrinfo(info);
+
+check_and_return:
+    if (result == NULL)
+        virReportOOMError(NULL);
     return result;
 }
 
diff -rup libvirt-0.7.1/src/virterror.c new/src/virterror.c
--- libvirt-0.7.1/src/virterror.c	2009-09-14 06:12:53.000000000 -0400
+++ new/src/virterror.c	2010-06-03 15:33:22.886409000 -0400
@@ -287,6 +287,28 @@ virGetLastError(void)
 }
 
 /**
+ * virSetError:
+ *
+ * Set the current error from a previously saved error object
+ *
+ * Can be used to re-set an old error, which may have been squashed by
+ * other functions (like cleanup routines).
+ *
+ * Returns 0 on success, 1 on failure
+ */
+int
+virSetError(virErrorPtr newerr)
+{
+    virErrorPtr err;
+    err = virGetLastError();
+    if (!err)
+        return -1;
+
+    virResetError(err);
+    return virCopyError(newerr, err);
+}
+
+/**
  * virCopyLastError:
  * @to: target to receive the copy
  *
@@ -596,6 +618,52 @@ virSetConnError(virConnectPtr conn)
     }
 }
 
+/**
+ * virDispatchError:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Internal helper to do final stage of error
+ * reporting in public APIs.
+ *
+ *  - Copy the global error to per-connection error if needed
+ *  - Set a generic error message if none is already set
+ *  - Invoke the error callback functions
+ */
+void
+virDispatchError(virConnectPtr conn)
+{
+    virErrorPtr err = virLastErrorObject();
+    virErrorFunc handler = virErrorHandler;
+    void *userData = virUserData;
+
+    /* Should never happen, but doesn't hurt to check */
+    if (!err)
+        return;
+
+    /* Set a generic error message if none is already set */
+    if (err->code == VIR_ERR_OK)
+        virErrorGenericFailure(err);
+
+    /* Copy the global error to per-connection error if needed */
+    if (conn) {
+        virMutexLock(&conn->lock);
+        virCopyError(err, &conn->err);
+
+        if (conn->handler != NULL) {
+            handler = conn->handler;
+            userData = conn->userData;
+        }
+        virMutexUnlock(&conn->lock);
+    }
+
+    /* Invoke the error callback functions */
+    if (handler != NULL) {
+        (handler)(userData, err);
+    } else {
+        virDefaultErrorFunc(err);
+    }
+}
+
 
 
 /**
@@ -634,8 +702,6 @@ virRaiseErrorFull(virConnectPtr conn,
                   const char *fmt, ...)
 {
     virErrorPtr to;
-    void *userData = virUserData;
-    virErrorFunc handler = virErrorHandler;
     char *str;
 
     /*
@@ -653,18 +719,6 @@ virRaiseErrorFull(virConnectPtr conn,
         return;
 
     /*
-     * try to find the best place to save and report the error
-     */
-    if (conn != NULL) {
-        virMutexLock(&conn->lock);
-        if (conn->handler != NULL) {
-            handler = conn->handler;
-            userData = conn->userData;
-        }
-        virMutexUnlock(&conn->lock);
-    }
-
-    /*
      * formats the message
      */
     if (fmt == NULL) {
@@ -683,7 +737,6 @@ virRaiseErrorFull(virConnectPtr conn,
     /*
      * Save the information about the error
      */
-    virResetError(to);
     /*
      * Delibrately not setting conn, dom & net fields since
      * they're utterly unsafe
@@ -701,14 +754,7 @@ virRaiseErrorFull(virConnectPtr conn,
     to->int1 = int1;
     to->int2 = int2;
 
-    /*
-     * now, report it
-     */
-    if (handler != NULL) {
-        handler(userData, to);
-    } else {
-        virDefaultErrorFunc(to);
-    }
+    virDispatchError(conn);
 }
 
 /**
diff -rup libvirt-0.7.1/src/virterror_internal.h new/src/virterror_internal.h
--- libvirt-0.7.1/src/virterror_internal.h	2009-07-23 12:33:02.000000000 -0400
+++ new/src/virterror_internal.h	2010-06-03 15:33:22.890402000 -0400
@@ -89,6 +89,8 @@ void virReportOOMErrorFull(virConnectPtr
 
 void virSetGlobalError(void);
 void virSetConnError(virConnectPtr conn);
+int virSetError(virErrorPtr newerr);
+void virDispatchError(virConnectPtr conn);
 const char *virStrerror(int theerrno, char *errBuf, size_t errBufLen);
 
 #endif

libvirt-0.7.1-network-collision.patch:
 network_driver.c |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

--- NEW FILE libvirt-0.7.1-network-collision.patch ---
diff -rup libvirt-0.7.1/src/network_driver.c new/src/network_driver.c
--- libvirt-0.7.1/src/network_driver.c	2009-09-15 03:49:04.000000000 -0400
+++ new/src/network_driver.c	2010-06-15 13:33:01.900912000 -0400
@@ -43,6 +43,8 @@
 #include <stdio.h>
 #include <sys/wait.h>
 #include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include "virterror_internal.h"
 #include "datatypes.h"
@@ -843,6 +845,102 @@ cleanup:
     return ret;
 }
 
+#define PROC_NET_ROUTE "/proc/net/route"
+
+static int networkCheckRouteCollision(virNetworkObjPtr network)
+{
+    int ret = -1, len;
+    char *cur, *buf = NULL;
+    enum {MAX_ROUTE_SIZE = 1024*64};
+    struct in_addr inaddress, innetmask;
+    unsigned int net_dest;
+
+    if (!network->def->ipAddress || !network->def->netmask)
+        return 0;
+
+    if (inet_pton(AF_INET, network->def->ipAddress, &inaddress) <= 0) {
+        networkReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                           _("cannot parse IP address '%s'"),
+                           network->def->ipAddress);
+        goto error;
+    }
+    if (inet_pton(AF_INET, network->def->netmask, &innetmask) <= 0) {
+        networkReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                           _("cannot parse netmask '%s'"),
+                           network->def->netmask);
+        goto error;
+    }
+
+    net_dest = (inaddress.s_addr & innetmask.s_addr);
+
+    /* Read whole routing table into memory */
+    if ((len = virFileReadAll(PROC_NET_ROUTE, MAX_ROUTE_SIZE, &buf)) < 0)
+        goto error;
+
+    /* Dropping the last character shouldn't hurt */
+    if (len > 0)
+        buf[len-1] = '\0';
+
+    VIR_DEBUG("%s output:\n%s", PROC_NET_ROUTE, buf);
+
+    if (!STRPREFIX (buf, "Iface"))
+        goto out;
+
+    /* First line is just headings, skip it */
+    cur = strchr(buf, '\n');
+    if (cur)
+        cur++;
+
+    while (cur) {
+        char iface[17], dest[128], mask[128];
+        unsigned int addr_val, mask_val;
+        int num;
+
+        /* NUL-terminate the line, so sscanf doesn't go beyond a newline.  */
+        char *nl = strchr(cur, '\n');
+        if (nl) {
+            *nl++ = '\0';
+        }
+
+        num = sscanf(cur, "%16s %127s %*s %*s %*s %*s %*s %127s",
+                     iface, dest, mask);
+        cur = nl;
+
+        if (num != 3) {
+            VIR_DEBUG("Failed to parse %s", PROC_NET_ROUTE);
+            continue;
+        }
+
+        if (virStrToLong_ui(dest, NULL, 16, &addr_val) < 0) {
+            VIR_DEBUG("Failed to convert network address %s to uint", dest);
+            continue;
+        }
+
+        if (virStrToLong_ui(mask, NULL, 16, &mask_val) < 0) {
+            VIR_DEBUG("Failed to convert network mask %s to uint", mask);
+            continue;
+        }
+
+        addr_val &= mask_val;
+
+        if ((net_dest == addr_val) &&
+            (innetmask.s_addr == mask_val)) {
+            networkReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                              _("Network %s/%s is already in use by "
+                                "interface %s"),
+                                network->def->ipAddress,
+                                network->def->netmask, iface);
+            goto error;
+        }
+    }
+
+out:
+    ret = 0;
+error:
+    VIR_FREE(buf);
+    return ret;
+}
+
 static int networkStartNetworkDaemon(virConnectPtr conn,
                                    struct network_driver *driver,
                                    virNetworkObjPtr network) {
@@ -854,6 +952,10 @@ static int networkStartNetworkDaemon(vir
         return -1;
     }
 
+    /* Check to see if network collides with an existing route */
+    if (networkCheckRouteCollision(network) < 0)
+        return -1;
+
     if ((err = brAddBridge(driver->brctl, network->def->bridge))) {
         virReportSystemError(conn, err,
                              _("cannot create bridge '%s'"),

libvirt-0.7.1-sanitize-pool.patch:
 libvirt_private.syms |    1 +
 storage_conf.c       |    7 ++++++-
 storage_driver.c     |    8 +++++++-
 util.c               |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 util.h               |    3 +++
 5 files changed, 66 insertions(+), 2 deletions(-)

--- NEW FILE libvirt-0.7.1-sanitize-pool.patch ---
diff -rup libvirt-0.7.1/src/libvirt_private.syms paths/src/libvirt_private.syms
--- libvirt-0.7.1/src/libvirt_private.syms	2010-05-26 12:48:49.276277000 -0400
+++ paths/src/libvirt_private.syms	2010-05-26 13:00:47.501023000 -0400
@@ -417,6 +417,7 @@ virParseMacAddr;
 virFileDeletePid;
 virFindFileInPath;
 virFileExists;
+virFileSanitizePath;
 virFileHasSuffix;
 virFileLinkPointsTo;
 virFileMakePath;
diff -rup libvirt-0.7.1/src/storage_conf.c paths/src/storage_conf.c
--- libvirt-0.7.1/src/storage_conf.c	2010-05-26 12:48:48.885306000 -0400
+++ paths/src/storage_conf.c	2010-05-26 13:00:17.027330000 -0400
@@ -463,6 +463,7 @@ virStoragePoolDefParseXML(virConnectPtr 
     char *type = NULL;
     char *uuid = NULL;
     char *authType = NULL;
+    char *tmppath;
 
     if (VIR_ALLOC(ret) < 0) {
         virReportOOMError(conn);
@@ -610,11 +611,15 @@ virStoragePoolDefParseXML(virConnectPtr 
             goto cleanup;
     }
 
-    if ((ret->target.path = virXPathString(conn, "string(./target/path)", ctxt)) == NULL) {
+    if ((tmppath = virXPathString(conn, "string(./target/path)", ctxt)) == NULL) {
         virStorageReportError(conn, VIR_ERR_XML_ERROR,
                               "%s", _("missing storage pool target path"));
         goto cleanup;
     }
+    ret->target.path = virFileSanitizePath(tmppath);
+    VIR_FREE(tmppath);
+    if (!ret->target.path)
+        goto cleanup;
 
     if (virStorageDefParsePerms(conn, ctxt, &ret->target.perms,
                                 "./target/permissions", 0700) < 0)
diff -rup libvirt-0.7.1/src/storage_driver.c paths/src/storage_driver.c
--- libvirt-0.7.1/src/storage_driver.c	2009-09-10 09:45:00.000000000 -0400
+++ paths/src/storage_driver.c	2010-05-26 12:59:14.815537000 -0400
@@ -1152,6 +1152,11 @@ storageVolumeLookupByPath(virConnectPtr 
     virStorageDriverStatePtr driver = conn->storagePrivateData;
     unsigned int i;
     virStorageVolPtr ret = NULL;
+    char *cleanpath;
+
+    cleanpath = virFileSanitizePath(path);
+    if (!cleanpath)
+        return NULL;
 
     storageDriverLock(driver);
     for (i = 0 ; i < driver->pools.count && !ret ; i++) {
@@ -1162,7 +1167,7 @@ storageVolumeLookupByPath(virConnectPtr 
 
             stable_path = virStorageBackendStablePath(conn,
                                                       driver->pools.objs[i],
-                                                      path);
+                                                      cleanpath);
             /*
              * virStorageBackendStablePath already does
              * virStorageReportError if it fails; we just need to keep
@@ -1191,6 +1196,7 @@ storageVolumeLookupByPath(virConnectPtr 
                               "%s", _("no storage vol with matching path"));
 
 cleanup:
+    VIR_FREE(cleanpath);
     storageDriverUnlock(driver);
     return ret;
 }
diff -rup libvirt-0.7.1/src/util.c paths/src/util.c
--- libvirt-0.7.1/src/util.c	2010-05-26 12:48:48.840341000 -0400
+++ paths/src/util.c	2010-05-26 12:58:02.088721000 -0400
@@ -1126,6 +1126,55 @@ int virFileExists(const char *path)
     return(0);
 }
 
+/* Remove spurious / characters from a path. The result must be freed */
+char *
+virFileSanitizePath(const char *path)
+{
+    const char *cur = path;
+    char *cleanpath;
+    int idx = 0;
+
+    cleanpath = strdup(path);
+    if (!cleanpath) {
+        virReportOOMError(NULL);
+        return NULL;
+    }
+
+    /* Need to sanitize:
+     * //           -> //
+     * ///          -> /
+     * /../foo      -> /../foo
+     * /foo///bar/  -> /foo/bar
+     */
+
+    /* Starting with // is valid posix, but ///foo == /foo */
+    if (cur[0] == '/' && cur[1] == '/' && cur[2] != '/') {
+        idx = 2;
+        cur += 2;
+    }
+
+    /* Sanitize path in place */
+    while (*cur != '\0') {
+        if (*cur != '/') {
+            cleanpath[idx++] = *cur++;
+            continue;
+        }
+
+        /* Skip all extra / */
+        while (*++cur == '/')
+            continue;
+
+        /* Don't add a trailing / */
+        if (idx != 0 && *cur == '\0')
+            break;
+
+        cleanpath[idx++] = '/';
+    }
+    cleanpath[idx] = '\0';
+
+    return cleanpath;
+}
+
 int virFileMakePath(const char *path)
 {
     struct stat st;
diff -rup libvirt-0.7.1/src/util.h paths/src/util.h
--- libvirt-0.7.1/src/util.h	2010-05-26 12:48:48.749342000 -0400
+++ paths/src/util.h	2010-05-26 12:56:57.494264000 -0400
@@ -107,6 +107,9 @@ char *virFindFileInPath(const char *file
 
 int virFileExists(const char *path);
 
+char *virFileSanitizePath(const char *path);
+
+
 int virFileMakePath(const char *path);
 
 int virFileBuildPath(const char *dir,


Index: libvirt.spec
===================================================================
RCS file: /cvs/pkgs/rpms/libvirt/F-12/libvirt.spec,v
retrieving revision 1.196
retrieving revision 1.197
diff -u -p -r1.196 -r1.197
--- libvirt.spec	18 May 2010 16:42:37 -0000	1.196
+++ libvirt.spec	17 Jun 2010 15:39:42 -0000	1.197
@@ -151,7 +151,7 @@
 Summary: Library providing a simple API virtualization
 Name: libvirt
 Version: 0.7.1
-Release: 16%{?dist}%{?extra_release}
+Release: 17%{?dist}%{?extra_release}
 License: LGPLv2+
 Group: Development/Libraries
 Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz
@@ -223,6 +223,26 @@ Patch27: %{name}-%{version}-fix-usb-busa
 Patch28: %{name}-%{version}-fix-selinux-save.patch
 # Fix USB devices attached via virt-manager (bz 537227)
 Patch29: %{name}-%{version}-fix-usb-product.patch
+# Fix attach-device crash on cgroup cleanup (bz 556791)
+Patch30: %{name}-%{version}-fix-cgroup-crash.patch
+# Fix crash on bad LXC URI (bz 554191)
+Patch31: %{name}-%{version}-lxc-uri-crash.patch
+# Add qemu.conf options for audio workaround
+Patch32: %{name}-%{version}-audio-config.patch
+# Fix permissions of storage backing stores (bz 579067)
+Patch33: %{name}-%{version}-backing-perms.patch
+# Fix parsing certain USB sysfs files (bz 598272)
+Patch34: %{name}-%{version}-fix-usb-parsing.patch
+# Improve migration error reporting (bz 499750)
+Patch35: %{name}-%{version}-migrate-errreport.patch
+# Sanitize pool target paths (bz 494005)
+Patch36: %{name}-%{version}-sanitize-pool.patch
+# Add qemu.conf for clear emulator capabilities
+Patch37: %{name}-%{version}-caps-option.patch
+# Prevent libvirtd inside a VM from breaking network access (bz 235961)
+Patch38: %{name}-%{version}-network-collision.patch
+# Mention --all in 'virsh list' docs (bz 575512)
+Patch39: %{name}-%{version}-man-page-list.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 URL: http://libvirt.org/
@@ -468,6 +488,16 @@ of recent versions of Linux (and other O
 %patch27 -p1
 %patch28 -p1
 %patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+#%patch33 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+%patch37 -p1
+%patch38 -p1
+%patch39 -p1
 
 %build
 # Needed for libvirt-logrotate-create-lxc-uml-dirs.patch
@@ -862,6 +892,18 @@ fi
 %endif
 
 %changelog
+* Tue Jun 15 2010 Cole Robinson <crobinso at redhat.com> - 0.7.1-17.fc12
+- Fix attach-device crash on cgroup cleanup (bz 556791)
+- Fix crash on bad LXC URI (bz 554191)
+- Add qemu.conf options for audio workaround
+- Fix permissions of storage backing stores (bz 579067)
+- Fix parsing certain USB sysfs files (bz 598272)
+- Improve migration error reporting (bz 499750)
+- Sanitize pool target paths (bz 494005)
+- Add qemu.conf for clear emulator capabilities
+- Prevent libvirtd inside a VM from breaking network access (bz 235961)
+- Mention --all in 'virsh list' docs (bz 575512)
+
 * Mon May 17 2010 Cole Robinson <crobinso at redhat.com> - 0.7.1-16.fc12
 - Fix crash with invalid QEmu URI (bz 566070)
 - Fix VNC TLS crash (bz 544305)



More information about the scm-commits mailing list