diff --git a/libvirt-0.4.1-qemu-media-change.patch b/libvirt-0.4.1-qemu-media-change.patch
new file mode 100644
index 0000000..f0845ab
--- /dev/null
+++ b/libvirt-0.4.1-qemu-media-change.patch
@@ -0,0 +1,128 @@
+commit 570fd656d1b67e5d02f52e107946930257e811a7
+Author: Daniel Veillard <veillard@redhat.com>
+Date:   Thu Mar 13 09:17:45 2008 +0000
+
+    * src/qemu_conf.c src/qemu_driver.c: patch from Cole Robinson
+      fixing CD Rom change on live QEmu/KVM domains.
+    Daniel
+
+diff --git a/src/qemu_conf.c b/src/qemu_conf.c
+index e54da5b..ebbd251 100644
+--- a/src/qemu_conf.c
++++ b/src/qemu_conf.c
+@@ -594,9 +594,16 @@ static int qemudParseDiskXML(virConnectPtr conn,
+     }
+ 
+     if (source == NULL) {
+-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SOURCE, target ? "%s" : NULL, target);
+-        goto error;
++        /* There is a case without the source
++         * to the CD-ROM device
++         */
++        if (!device || STRNEQ((const char *) device, "cdrom")) {
++            qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SOURCE,
++                             target ? "%s" : NULL, target);
++            goto error;
++        }
+     }
++
+     if (target == NULL) {
+         qemudReportError(conn, NULL, NULL, VIR_ERR_NO_TARGET, source ? "%s" : NULL, source);
+         goto error;
+@@ -630,7 +637,7 @@ static int qemudParseDiskXML(virConnectPtr conn,
+         goto error;
+     }
+ 
+-    strncpy(disk->src, (const char *)source, NAME_MAX-1);
++    strncpy(disk->src, (source ? (const char *) source : "\0"), NAME_MAX-1);
+     disk->src[NAME_MAX-1] = '\0';
+ 
+     strncpy(disk->dst, (const char *)target, NAME_MAX-1);
+@@ -1747,9 +1754,15 @@ int qemudBuildCommandLine(virConnectPtr conn,
+         char dev[NAME_MAX];
+         char file[PATH_MAX];
+         if (!strcmp(disk->dst, "hdc") &&
+-            disk->device == QEMUD_DISK_CDROM)
+-            snprintf(dev, NAME_MAX, "-%s", "cdrom");
+-        else
++            disk->device == QEMUD_DISK_CDROM) {
++            if (disk->src[0])
++                snprintf(dev, NAME_MAX, "-%s", "cdrom");
++            else {
++                /* Don't put anything on the cmdline for an empty cdrom*/
++                disk = disk->next;
++                continue;
++            }
++        } else
+             snprintf(dev, NAME_MAX, "-%s", disk->dst);
+         snprintf(file, PATH_MAX, "%s", disk->src);
+ 
+@@ -2906,8 +2919,10 @@ char *qemudGenerateXML(virConnectPtr conn,
+                               types[disk->type], devices[disk->device]) < 0)
+             goto no_memory;
+ 
+-        if (virBufferVSprintf(buf, "      <source %s='%s'/>\n", typeAttrs[disk->type], disk->src) < 0)
+-            goto no_memory;
++        if (disk->src[0])
++            if (virBufferVSprintf(buf, "      <source %s='%s'/>\n",
++                                  typeAttrs[disk->type], disk->src) < 0)
++                goto no_memory;
+ 
+         if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", disk->dst) < 0)
+             goto no_memory;
+diff --git a/src/qemu_driver.c b/src/qemu_driver.c
+index 21f0fed..2b4c2a6 100644
+--- a/src/qemu_driver.c
++++ b/src/qemu_driver.c
+@@ -2223,23 +2223,29 @@ static int qemudDomainChangeCDROM(virDomainPtr dom,
+     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+     char *cmd, *reply, *safe_path;
+ 
+-    /* Migrate to file */
+-    safe_path = qemudEscapeMonitorArg(newdisk->src);
+-    if (!safe_path) {
+-        qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+-                         "out of memory");
+-        return -1;
+-    }
+-    if (asprintf (&cmd, "change %s \"%s\"",
+-                  /* XXX qemu may support multiple CDROM in future */
+-                  /* olddisk->dst */ "cdrom",
+-                  safe_path) == -1) {
++    if (newdisk->src[0]) {
++        safe_path = qemudEscapeMonitorArg(newdisk->src);
++        if (!safe_path) {
++            qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
++                             "out of memory");
++            return -1;
++        }
++        if (asprintf (&cmd, "change %s \"%s\"",
++                      /* XXX qemu may support multiple CDROM in future */
++                      /* olddisk->dst */ "cdrom",
++                      safe_path) == -1) {
++            qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
++                             "out of memory");
++            free(safe_path);
++            return -1;
++        }
++        free(safe_path);
++
++    } else if (asprintf(&cmd, "eject cdrom") == -1) {
+         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+                          "out of memory");
+-        free(safe_path);
+         return -1;
+     }
+-    free(safe_path);
+ 
+     if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
+         qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, "cannot change cdrom media");
+@@ -2248,7 +2254,7 @@ static int qemudDomainChangeCDROM(virDomainPtr dom,
+     }
+     free(reply);
+     free(cmd);
+-    strcpy(olddisk->dst, newdisk->dst);
++    strcpy(olddisk->src, newdisk->src);
+     olddisk->type = newdisk->type;
+     return 0;
+ }
diff --git a/libvirt-0.4.1-tap-ifname.patch b/libvirt-0.4.1-tap-ifname.patch
new file mode 100644
index 0000000..c456ade
--- /dev/null
+++ b/libvirt-0.4.1-tap-ifname.patch
@@ -0,0 +1,63 @@
+diff -rupN libvirt-0.4.1.orig/src/bridge.c libvirt-0.4.1.new/src/bridge.c
+--- libvirt-0.4.1.orig/src/bridge.c	2008-02-28 06:16:21.000000000 -0500
++++ libvirt-0.4.1.new/src/bridge.c	2008-03-13 11:25:12.000000000 -0400
+@@ -313,7 +313,6 @@ brDeleteInterface(brControl *ctl ATTRIBU
+ int
+ brAddTap(brControl *ctl,
+          const char *bridge,
+-         unsigned char *macaddr,
+          char *ifname,
+          int maxlen,
+          int *tapfd)
+@@ -357,18 +356,6 @@ brAddTap(brControl *ctl,
+         }
+ 
+         if (ioctl(fd, TUNSETIFF, &try) == 0) {
+-            struct ifreq addr;
+-            memset(&addr, 0, sizeof(addr));
+-            memcpy(addr.ifr_hwaddr.sa_data, macaddr, 6);
+-            addr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
+-
+-            /* Device actually starts in 'UP' state, but it
+-             * needs to be down to set the MAC addr
+-             */
+-            if ((errno = brSetInterfaceUp(ctl, try.ifr_name, 0)))
+-                goto error;
+-            if (ioctl(fd, SIOCSIFHWADDR, &addr) != 0)
+-                goto error;
+             if ((errno = brAddInterface(ctl, bridge, try.ifr_name)))
+                 goto error;
+             if ((errno = brSetInterfaceUp(ctl, try.ifr_name, 1)))
+diff -rupN libvirt-0.4.1.orig/src/bridge.h libvirt-0.4.1.new/src/bridge.h
+--- libvirt-0.4.1.orig/src/bridge.h	2008-02-28 06:16:21.000000000 -0500
++++ libvirt-0.4.1.new/src/bridge.h	2008-03-13 11:25:12.000000000 -0400
+@@ -62,7 +62,6 @@ int     brDeleteInterface       (brContr
+ 
+ int     brAddTap                (brControl *ctl,
+                                  const char *bridge,
+-                                 unsigned char *mac,
+                                  char *ifname,
+                                  int maxlen,
+                                  int *tapfd);
+diff -rupN libvirt-0.4.1.orig/src/qemu_conf.c libvirt-0.4.1.new/src/qemu_conf.c
+--- libvirt-0.4.1.orig/src/qemu_conf.c	2008-03-13 11:24:39.000000000 -0400
++++ libvirt-0.4.1.new/src/qemu_conf.c	2008-03-13 11:25:12.000000000 -0400
+@@ -1540,7 +1540,6 @@ qemudNetworkIfaceConnect(virConnectPtr c
+     }
+ 
+     if ((err = brAddTap(driver->brctl, brname,
+-                        net->mac,
+                         ifname, BR_IFNAME_MAXLEN, &tapfd))) {
+         qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                          "Failed to add tap interface '%s' to bridge '%s' : %s",
+@@ -1548,7 +1547,9 @@ qemudNetworkIfaceConnect(virConnectPtr c
+         goto error;
+     }
+ 
+-    snprintf(tapfdstr, sizeof(tapfdstr), "tap,fd=%d,script=,vlan=%d", tapfd, vlan);
++    snprintf(tapfdstr, sizeof(tapfdstr),
++             "tap,fd=%d,script=,vlan=%d,ifname=%s",
++             tapfd, vlan, ifname);
+ 
+     if (!(retval = strdup(tapfdstr)))
+         goto no_memory;
diff --git a/libvirt-0.4.1-xen-boot-device.patch b/libvirt-0.4.1-xen-boot-device.patch
new file mode 100644
index 0000000..2523601
--- /dev/null
+++ b/libvirt-0.4.1-xen-boot-device.patch
@@ -0,0 +1,21 @@
+commit 2bcf35336cd649e58c08d7cf3452a8d4353bcf85
+Author: Daniel Veillard <veillard@redhat.com>
+Date:   Fri Mar 7 09:23:30 2008 +0000
+
+    * src/xend_internal.c: applied patch from Cole Robinson to not
+      loose the boot tag when defining a fully virtualized xen domain
+    Daniel
+
+diff --git a/src/xend_internal.c b/src/xend_internal.c
+index 8bbc28f..fef54f8 100644
+--- a/src/xend_internal.c
++++ b/src/xend_internal.c
+@@ -1323,7 +1323,7 @@ xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf
+     if (hvm)
+         virBufferVSprintf(buf, "    <loader>%s</loader>\n", loader);
+ 
+-    if (kernel) {
++    if ((kernel) && ((!loader) || (STRNEQ(kernel, loader)))) {
+         virBufferVSprintf(buf, "    <kernel>%s</kernel>\n", kernel);
+         if (initrd && initrd[0])
+             virBufferVSprintf(buf, "    <initrd>%s</initrd>\n", initrd);
diff --git a/libvirt.spec b/libvirt.spec
index d844472..ecd4345 100644
--- a/libvirt.spec
+++ b/libvirt.spec
@@ -21,13 +21,16 @@
 Summary: Library providing a simple API virtualization
 Name: libvirt
 Version: 0.4.1
-Release: 3%{?dist}%{?extra_release}
+Release: 4%{?dist}%{?extra_release}
 License: LGPL
 Group: Development/Libraries
 Source: libvirt-%{version}.tar.gz
 Patch0: libvirt-0.4.1-qemud1.patch
 Patch1: libvirt-0.4.1-qemud2.patch
 Patch2: %{name}-%{version}-daemon-startup.patch
+Patch3: %{name}-%{version}-qemu-media-change.patch
+Patch4: %{name}-%{version}-xen-boot-device.patch
+Patch5: %{name}-%{version}-tap-ifname.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-root
 URL: http://libvirt.org/
 BuildRequires: python python-devel
@@ -142,6 +145,9 @@ of recent versions of Linux (and other OSes).
 %patch0 -p1
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
 
 %build
 # Xen is available only on i386 x86_64 ia64
@@ -178,6 +184,8 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.a
 rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.la
 rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.a
 install -d -m 0755 $RPM_BUILD_ROOT%{_localstatedir}/run/libvirt/
+# Default dir for disk images defined in SELinux policy
+install -d -m 0755 $RPM_BUILD_ROOT%{_localstatedir}/lib/libvirt/images/
 
 # We don't want to install /etc/libvirt/qemu/networks in the main %files list
 # because if the admin wants to delete the default network completely, we don't
@@ -242,6 +250,7 @@ fi
 %{_datadir}/libvirt/networks/default.xml
 %dir %{_localstatedir}/run/libvirt/
 %dir %{_localstatedir}/lib/libvirt/
+%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/images/
 %if %{with_polkit}
 %{_datadir}/PolicyKit/policy/libvirtd.policy
 %endif
@@ -282,6 +291,11 @@ fi
 %doc docs/examples/python
 
 %changelog
+* Thu Mar 13 2008 Daniel P. Berrange <berrange@redhat.com> - 0.4.1-4.fc9
+- Fix QEMU tap device setup
+- Fix Xen boot device XML processing
+- Fixed QEMU cdrom media change
+
 * Mon Mar 10 2008 Daniel P. Berrange <berrange@redhat.com> - 0.4.1-3.fc9
 - Fixed daemon startup when run with --daemon flag