diff --git a/.cvsignore b/.cvsignore
index 91a8724..55e6af8 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -3,20 +3,3 @@
 i686
 x86_64
 libvirt-*.tar.gz
-libvirt-0.6.0.tar.gz
-libvirt-0.6.1.tar.gz
-libvirt-0.6.2.tar.gz
-libvirt-0.6.3.tar.gz
-libvirt-0.6.4.tar.gz
-libvirt-0.6.5.tar.gz
-libvirt-0.7.0.tar.gz
-libvirt-0.7.1.tar.gz
-libvirt-0.7.2.tar.gz
-libvirt-0.7.3.tar.gz
-libvirt-0.7.4.tar.gz
-libvirt-0.7.5.tar.gz
-libvirt-0.7.6.tar.gz
-libvirt-0.7.7.tar.gz
-libvirt-0.8.0.tar.gz
-libvirt-0.8.1.tar.gz
-libvirt-0.8.2.tar.gz
diff --git a/libvirt-0.8.2-01-extract-backing-store-format.patch b/libvirt-0.8.2-01-extract-backing-store-format.patch
new file mode 100644
index 0000000..569cf0a
--- /dev/null
+++ b/libvirt-0.8.2-01-extract-backing-store-format.patch
@@ -0,0 +1,356 @@
+From 953440bd12608a20007ee5da5ab69fbbe910bd28 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Mon, 14 Jun 2010 15:53:59 +0100
+Subject: [PATCH 01/11] Extract the backing store format as well as name, if available
+
+When QEMU opens a backing store for a QCow2 file, it will
+normally auto-probe for the format of the backing store,
+rather than assuming it has the same format as the referencing
+file. There is a QCow2 extension that allows an explicit format
+for the backing store to be embedded in the referencing file.
+This closes the auto-probing security hole in QEMU.
+
+This backing store format can be useful for libvirt users
+of virStorageFileGetMetadata, so extract this data and report
+it.
+
+QEMU does not require disk image backing store files to be in
+the same format the file linkee. It will auto-probe the disk
+format for the backing store when opening it. If the backing
+store was intended to be a raw file this could be a security
+hole, because a guest may have written data into its disk that
+then makes the backing store look like a qcow2 file. If it can
+trick QEMU into thinking the raw file is a qcow2 file, it can
+access arbitrary files on the host by adding further backing
+store links.
+
+To address this, callers of virStorageFileGetMeta need to be
+told of the backing store format. If no format is declared,
+they can make a decision whether to allow format probing or
+not.
+---
+ src/util/storage_file.c |  206 +++++++++++++++++++++++++++++++++++++++++------
+ src/util/storage_file.h |    2 +
+ 2 files changed, 183 insertions(+), 25 deletions(-)
+
+diff --git a/src/util/storage_file.c b/src/util/storage_file.c
+index 0adea40..80f743e 100644
+--- a/src/util/storage_file.c
++++ b/src/util/storage_file.c
+@@ -78,12 +78,33 @@ struct FileTypeInfo {
+     int qcowCryptOffset;  /* Byte offset from start of file
+                            * where to find encryption mode,
+                            * -1 if encryption is not used */
+-    int (*getBackingStore)(char **res, const unsigned char *buf, size_t buf_size);
++    int (*getBackingStore)(char **res, int *format,
++                           const unsigned char *buf, size_t buf_size);
+ };
+ 
+-static int cowGetBackingStore(char **, const unsigned char *, size_t);
+-static int qcowXGetBackingStore(char **, const unsigned char *, size_t);
+-static int vmdk4GetBackingStore(char **, const unsigned char *, size_t);
++static int cowGetBackingStore(char **, int *,
++                              const unsigned char *, size_t);
++static int qcow1GetBackingStore(char **, int *,
++                                const unsigned char *, size_t);
++static int qcow2GetBackingStore(char **, int *,
++                                const unsigned char *, size_t);
++static int vmdk4GetBackingStore(char **, int *,
++                                const unsigned char *, size_t);
++
++#define QCOWX_HDR_VERSION (4)
++#define QCOWX_HDR_BACKING_FILE_OFFSET (QCOWX_HDR_VERSION+4)
++#define QCOWX_HDR_BACKING_FILE_SIZE (QCOWX_HDR_BACKING_FILE_OFFSET+8)
++#define QCOWX_HDR_IMAGE_SIZE (QCOWX_HDR_BACKING_FILE_SIZE+4+4)
++
++#define QCOW1_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8+1+1)
++#define QCOW2_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8)
++
++#define QCOW1_HDR_TOTAL_SIZE (QCOW1_HDR_CRYPT+4+8)
++#define QCOW2_HDR_TOTAL_SIZE (QCOW2_HDR_CRYPT+4+4+8+8+4+4+8)
++
++#define QCOW2_HDR_EXTENSION_END 0
++#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
++
+ 
+ 
+ static struct FileTypeInfo const fileTypeInfo[] = {
+@@ -119,11 +140,11 @@ static struct FileTypeInfo const fileTypeInfo[] = {
+     /* QCow */
+     { VIR_STORAGE_FILE_QCOW, "QFI", NULL,
+       LV_BIG_ENDIAN, 4, 1,
+-      4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcowXGetBackingStore },
++      QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore },
+     /* QCow 2 */
+     { VIR_STORAGE_FILE_QCOW2, "QFI", NULL,
+       LV_BIG_ENDIAN, 4, 2,
+-      4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcowXGetBackingStore },
++      QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore },
+     /* VMDK 3 */
+     /* XXX Untested
+     { VIR_STORAGE_FILE_VMDK, "COWD", NULL,
+@@ -142,11 +163,14 @@ static struct FileTypeInfo const fileTypeInfo[] = {
+ 
+ static int
+ cowGetBackingStore(char **res,
++                   int *format,
+                    const unsigned char *buf,
+                    size_t buf_size)
+ {
+ #define COW_FILENAME_MAXLEN 1024
+     *res = NULL;
++    *format = VIR_STORAGE_FILE_AUTO;
++
+     if (buf_size < 4+4+ COW_FILENAME_MAXLEN)
+         return BACKING_STORE_INVALID;
+     if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */
+@@ -160,31 +184,98 @@ cowGetBackingStore(char **res,
+     return BACKING_STORE_OK;
+ }
+ 
++
++static int
++qcow2GetBackingStoreFormat(int *format,
++                           const unsigned char *buf,
++                           size_t buf_size,
++                           size_t extension_start,
++                           size_t extension_end)
++{
++    size_t offset = extension_start;
++
++    /*
++     * The extensions take format of
++     *
++     * int32: magic
++     * int32: length
++     * byte[length]: payload
++     *
++     * Unknown extensions can be ignored by skipping
++     * over "length" bytes in the data stream.
++     */
++    while (offset < (buf_size-8) &&
++           offset < (extension_end-8)) {
++        unsigned int magic =
++            (buf[offset] << 24) +
++            (buf[offset+1] << 16) +
++            (buf[offset+2] << 8) +
++            (buf[offset+3]);
++        unsigned int len =
++            (buf[offset+4] << 24) +
++            (buf[offset+5] << 16) +
++            (buf[offset+6] << 8) +
++            (buf[offset+7]);
++
++        offset += 8;
++
++        if ((offset + len) < offset)
++            break;
++
++        if ((offset + len) > buf_size)
++            break;
++
++        switch (magic) {
++        case QCOW2_HDR_EXTENSION_END:
++            goto done;
++
++        case QCOW2_HDR_EXTENSION_BACKING_FORMAT:
++            if (buf[offset+len] != '\0')
++                break;
++            *format = virStorageFileFormatTypeFromString(
++                ((const char *)buf)+offset);
++            break;
++        }
++
++        offset += len;
++    }
++
++done:
++
++    return 0;
++}
++
++
+ static int
+ qcowXGetBackingStore(char **res,
++                     int *format,
+                      const unsigned char *buf,
+-                     size_t buf_size)
++                     size_t buf_size,
++                     bool isQCow2)
+ {
+     unsigned long long offset;
+     unsigned long size;
+ 
+     *res = NULL;
+-    if (buf_size < 4+4+8+4)
++    if (format)
++        *format = VIR_STORAGE_FILE_AUTO;
++
++    if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4)
+         return BACKING_STORE_INVALID;
+-    offset = (((unsigned long long)buf[4+4] << 56)
+-              | ((unsigned long long)buf[4+4+1] << 48)
+-              | ((unsigned long long)buf[4+4+2] << 40)
+-              | ((unsigned long long)buf[4+4+3] << 32)
+-              | ((unsigned long long)buf[4+4+4] << 24)
+-              | ((unsigned long long)buf[4+4+5] << 16)
+-              | ((unsigned long long)buf[4+4+6] << 8)
+-              | buf[4+4+7]); /* QCowHeader.backing_file_offset */
++    offset = (((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET] << 56)
++              | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+1] << 48)
++              | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+2] << 40)
++              | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+3] << 32)
++              | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+4] << 24)
++              | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+5] << 16)
++              | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+6] << 8)
++              | buf[QCOWX_HDR_BACKING_FILE_OFFSET+7]); /* QCowHeader.backing_file_offset */
+     if (offset > buf_size)
+         return BACKING_STORE_INVALID;
+-    size = ((buf[4+4+8] << 24)
+-            | (buf[4+4+8+1] << 16)
+-            | (buf[4+4+8+2] << 8)
+-            | buf[4+4+8+3]); /* QCowHeader.backing_file_size */
++    size = ((buf[QCOWX_HDR_BACKING_FILE_SIZE] << 24)
++            | (buf[QCOWX_HDR_BACKING_FILE_SIZE+1] << 16)
++            | (buf[QCOWX_HDR_BACKING_FILE_SIZE+2] << 8)
++            | buf[QCOWX_HDR_BACKING_FILE_SIZE+3]); /* QCowHeader.backing_file_size */
+     if (size == 0)
+         return BACKING_STORE_OK;
+     if (offset + size > buf_size || offset + size < offset)
+@@ -197,12 +288,63 @@ qcowXGetBackingStore(char **res,
+     }
+     memcpy(*res, buf + offset, size);
+     (*res)[size] = '\0';
++
++    /*
++     * Traditionally QCow2 files had a layout of
++     *
++     * [header]
++     * [backingStoreName]
++     *
++     * Although the backingStoreName typically followed
++     * the header immediately, this was not required by
++     * the format. By specifying a higher byte offset for
++     * the backing file offset in the header, it was
++     * possible to leave space between the header and
++     * start of backingStore.
++     *
++     * This hack is now used to store extensions to the
++     * qcow2 format:
++     *
++     * [header]
++     * [extensions]
++     * [backingStoreName]
++     *
++     * Thus the file region to search for extensions is
++     * between the end of the header (QCOW2_HDR_TOTAL_SIZE)
++     * and the start of the backingStoreName (offset)
++     */
++    if (isQCow2)
++        qcow2GetBackingStoreFormat(format, buf, buf_size, QCOW2_HDR_TOTAL_SIZE, offset);
++
+     return BACKING_STORE_OK;
+ }
+ 
+ 
+ static int
++qcow1GetBackingStore(char **res,
++                     int *format,
++                     const unsigned char *buf,
++                     size_t buf_size)
++{
++    /* QCow1 doesn't have the extensions capability
++     * used to store backing format */
++    *format = VIR_STORAGE_FILE_AUTO;
++    return qcowXGetBackingStore(res, NULL, buf, buf_size, false);
++}
++
++static int
++qcow2GetBackingStore(char **res,
++                     int *format,
++                     const unsigned char *buf,
++                     size_t buf_size)
++{
++    return qcowXGetBackingStore(res, format, buf, buf_size, true);
++}
++
++
++static int
+ vmdk4GetBackingStore(char **res,
++                     int *format,
+                      const unsigned char *buf,
+                      size_t buf_size)
+ {
+@@ -212,6 +354,14 @@ vmdk4GetBackingStore(char **res,
+     size_t len;
+ 
+     *res = NULL;
++    /*
++     * Technically this should have been VMDK, since
++     * VMDK spec / VMWare impl only support VMDK backed
++     * by VMDK. QEMU isn't following this though and
++     * does probing on VMDK backing files, hence we set
++     * AUTO
++     */
++    *format = VIR_STORAGE_FILE_AUTO;
+ 
+     if (buf_size <= 0x200)
+         return BACKING_STORE_INVALID;
+@@ -358,9 +508,12 @@ virStorageFileGetMetadataFromFD(const char *path,
+         /* Validation passed, we know the file format now */
+         meta->format = fileTypeInfo[i].type;
+         if (fileTypeInfo[i].getBackingStore != NULL) {
+-            char *base;
++            char *backing;
++            int backingFormat;
+ 
+-            switch (fileTypeInfo[i].getBackingStore(&base, head, len)) {
++            switch (fileTypeInfo[i].getBackingStore(&backing,
++                                                    &backingFormat,
++                                                    head, len)) {
+             case BACKING_STORE_OK:
+                 break;
+ 
+@@ -370,13 +523,16 @@ virStorageFileGetMetadataFromFD(const char *path,
+             case BACKING_STORE_ERROR:
+                 return -1;
+             }
+-            if (base != NULL) {
+-                meta->backingStore = absolutePathFromBaseFile(path, base);
+-                VIR_FREE(base);
++            if (backing != NULL) {
++                meta->backingStore = absolutePathFromBaseFile(path, backing);
++                VIR_FREE(backing);
+                 if (meta->backingStore == NULL) {
+                     virReportOOMError();
+                     return -1;
+                 }
++                meta->backingStoreFormat = backingFormat;
++            } else {
++                meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
+             }
+         }
+         return 0;
+diff --git a/src/util/storage_file.h b/src/util/storage_file.h
+index 58533ee..6328ba7 100644
+--- a/src/util/storage_file.h
++++ b/src/util/storage_file.h
+@@ -28,6 +28,7 @@
+ # include <stdbool.h>
+ 
+ enum virStorageFileFormat {
++    VIR_STORAGE_FILE_AUTO = -1,
+     VIR_STORAGE_FILE_RAW = 0,
+     VIR_STORAGE_FILE_DIR,
+     VIR_STORAGE_FILE_BOCHS,
+@@ -47,6 +48,7 @@ VIR_ENUM_DECL(virStorageFileFormat);
+ typedef struct _virStorageFileMetadata {
+     int format;
+     char *backingStore;
++    int backingStoreFormat;
+     unsigned long long capacity;
+     bool encrypted;
+ } virStorageFileMetadata;
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-02-remove-type-field.patch b/libvirt-0.8.2-02-remove-type-field.patch
new file mode 100644
index 0000000..74672f5
--- /dev/null
+++ b/libvirt-0.8.2-02-remove-type-field.patch
@@ -0,0 +1,159 @@
+From cab428b1d4d432965cee6f5afb67265557706715 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Mon, 14 Jun 2010 16:39:32 +0100
+Subject: [PATCH 02/11] Remove 'type' field from FileTypeInfo struct
+
+Instead of including a field in FileTypeInfo struct for the
+disk format, rely on the array index matching the format.
+Use verify() to assert the correct number of elements in the
+array.
+
+* src/util/storage_file.c: remove type field from FileTypeInfo
+---
+ src/util/storage_file.c |  108 +++++++++++++++++++++++-----------------------
+ 1 files changed, 54 insertions(+), 54 deletions(-)
+
+diff --git a/src/util/storage_file.c b/src/util/storage_file.c
+index 80f743e..df0e3a1 100644
+--- a/src/util/storage_file.c
++++ b/src/util/storage_file.c
+@@ -58,7 +58,6 @@ enum {
+ 
+ /* Either 'magic' or 'extension' *must* be provided */
+ struct FileTypeInfo {
+-    int type;           /* One of the constants above */
+     const char *magic;  /* Optional string of file magic
+                          * to check at head of file */
+     const char *extension; /* Optional file extension to check */
+@@ -108,58 +107,59 @@ static int vmdk4GetBackingStore(char **, int *,
+ 
+ 
+ static struct FileTypeInfo const fileTypeInfo[] = {
+-    /* Bochs */
+-    /* XXX Untested
+-    { VIR_STORAGE_FILE_BOCHS, "Bochs Virtual HD Image", NULL,
+-      LV_LITTLE_ENDIAN, 64, 0x20000,
+-      32+16+16+4+4+4+4+4, 8, 1, -1, NULL },*/
+-    /* CLoop */
+-    /* XXX Untested
+-    { VIR_STORAGE_VOL_CLOOP, "#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", NULL,
+-      LV_LITTLE_ENDIAN, -1, 0,
+-      -1, 0, 0, -1, NULL }, */
+-    /* Cow */
+-    { VIR_STORAGE_FILE_COW, "OOOM", NULL,
+-      LV_BIG_ENDIAN, 4, 2,
+-      4+4+1024+4, 8, 1, -1, cowGetBackingStore },
+-    /* DMG */
+-    /* XXX QEMU says there's no magic for dmg, but we should check... */
+-    { VIR_STORAGE_FILE_DMG, NULL, ".dmg",
+-      0, -1, 0,
+-      -1, 0, 0, -1, NULL },
+-    /* XXX there's probably some magic for iso we can validate too... */
+-    { VIR_STORAGE_FILE_ISO, NULL, ".iso",
+-      0, -1, 0,
+-      -1, 0, 0, -1, NULL },
+-    /* Parallels */
+-    /* XXX Untested
+-    { VIR_STORAGE_FILE_PARALLELS, "WithoutFreeSpace", NULL,
+-      LV_LITTLE_ENDIAN, 16, 2,
+-      16+4+4+4+4, 4, 512, -1, NULL },
+-    */
+-    /* QCow */
+-    { VIR_STORAGE_FILE_QCOW, "QFI", NULL,
+-      LV_BIG_ENDIAN, 4, 1,
+-      QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore },
+-    /* QCow 2 */
+-    { VIR_STORAGE_FILE_QCOW2, "QFI", NULL,
+-      LV_BIG_ENDIAN, 4, 2,
+-      QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore },
+-    /* VMDK 3 */
+-    /* XXX Untested
+-    { VIR_STORAGE_FILE_VMDK, "COWD", NULL,
+-      LV_LITTLE_ENDIAN, 4, 1,
+-      4+4+4, 4, 512, -1, NULL },
+-    */
+-    /* VMDK 4 */
+-    { VIR_STORAGE_FILE_VMDK, "KDMV", NULL,
+-      LV_LITTLE_ENDIAN, 4, 1,
+-      4+4+4, 8, 512, -1, vmdk4GetBackingStore },
+-    /* Connectix / VirtualPC */
+-    { VIR_STORAGE_FILE_VPC, "conectix", NULL,
+-      LV_BIG_ENDIAN, 12, 0x10000,
+-      8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL},
++    [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
++    [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
++    [VIR_STORAGE_FILE_BOCHS] = {
++        /*"Bochs Virtual HD Image", */ /* Untested */ NULL,
++        NULL,
++        LV_LITTLE_ENDIAN, 64, 0x20000,
++        32+16+16+4+4+4+4+4, 8, 1, -1, NULL
++    },
++    [VIR_STORAGE_FILE_CLOOP] = {
++        /*"#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", */ /* Untested */ NULL,
++        NULL,
++        LV_LITTLE_ENDIAN, -1, 0,
++        -1, 0, 0, -1, NULL
++    },
++    [VIR_STORAGE_FILE_COW] = {
++        "OOOM", NULL,
++        LV_BIG_ENDIAN, 4, 2,
++        4+4+1024+4, 8, 1, -1, cowGetBackingStore
++    },
++    [VIR_STORAGE_FILE_DMG] = {
++        NULL, /* XXX QEMU says there's no magic for dmg, but we should check... */
++        ".dmg",
++        0, -1, 0,
++        -1, 0, 0, -1, NULL
++    },
++    [VIR_STORAGE_FILE_ISO] = {
++        NULL, /* XXX there's probably some magic for iso we can validate too... */
++        ".iso",
++        0, -1, 0,
++        -1, 0, 0, -1, NULL
++    },
++    [VIR_STORAGE_FILE_QCOW] = {
++        "QFI", NULL,
++        LV_BIG_ENDIAN, 4, 1,
++        QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore,
++    },
++    [VIR_STORAGE_FILE_QCOW2] = {
++        "QFI", NULL,
++        LV_BIG_ENDIAN, 4, 2,
++        QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore,
++    },
++    [VIR_STORAGE_FILE_VMDK] = {
++        "KDMV", NULL,
++        LV_LITTLE_ENDIAN, 4, 1,
++        4+4+4, 8, 512, -1, vmdk4GetBackingStore
++    },
++    [VIR_STORAGE_FILE_VPC] = {
++        "conectix", NULL,
++        LV_BIG_ENDIAN, 12, 0x10000,
++        8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL
++    },
+ };
++verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
+ 
+ static int
+ cowGetBackingStore(char **res,
+@@ -506,7 +506,7 @@ virStorageFileGetMetadataFromFD(const char *path,
+         }
+ 
+         /* Validation passed, we know the file format now */
+-        meta->format = fileTypeInfo[i].type;
++        meta->format = i;
+         if (fileTypeInfo[i].getBackingStore != NULL) {
+             char *backing;
+             int backingFormat;
+@@ -546,7 +546,7 @@ virStorageFileGetMetadataFromFD(const char *path,
+         if (!virFileHasSuffix(path, fileTypeInfo[i].extension))
+             continue;
+ 
+-        meta->format = fileTypeInfo[i].type;
++        meta->format = i;
+         return 0;
+     }
+ 
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-03-refactor-metadata-extract.patch b/libvirt-0.8.2-03-refactor-metadata-extract.patch
new file mode 100644
index 0000000..d868825
--- /dev/null
+++ b/libvirt-0.8.2-03-refactor-metadata-extract.patch
@@ -0,0 +1,585 @@
+From 57482ca0be29e9e92e242c9acb577e0b770c01d1 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Tue, 15 Jun 2010 14:58:10 +0100
+Subject: [PATCH 03/11] Refactor virStorageFileGetMetadataFromFD to separate functionality
+
+The virStorageFileGetMetadataFromFD did two jobs in one. First
+it probed for storage type, then it extracted metadata for the
+type. It is desirable to be able to separate these jobs, allowing
+probing without querying metadata, and querying metadata without
+probing.
+
+To prepare for this, split out probing code into a new pair of
+methods
+
+  virStorageFileProbeFormatFromFD
+  virStorageFileProbeFormat
+
+* src/util/storage_file.c, src/util/storage_file.h,
+  src/libvirt_private.syms: Introduce virStorageFileProbeFormat
+  and virStorageFileProbeFormatFromFD
+---
+ src/libvirt_private.syms |    2 +
+ src/util/storage_file.c  |  460 +++++++++++++++++++++++++++++++++-------------
+ src/util/storage_file.h  |    4 +
+ 3 files changed, 335 insertions(+), 131 deletions(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 778ceb1..4607f49 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -628,6 +628,8 @@ virStorageGenerateQcowPassphrase;
+ # storage_file.h
+ virStorageFileFormatTypeToString;
+ virStorageFileFormatTypeFromString;
++virStorageFileProbeFormat;
++virStorageFileProbeFormatFromFD;
+ virStorageFileGetMetadata;
+ virStorageFileGetMetadataFromFD;
+ virStorageFileIsSharedFS;
+diff --git a/src/util/storage_file.c b/src/util/storage_file.c
+index df0e3a1..221268b 100644
+--- a/src/util/storage_file.c
++++ b/src/util/storage_file.c
+@@ -104,6 +104,9 @@ static int vmdk4GetBackingStore(char **, int *,
+ #define QCOW2_HDR_EXTENSION_END 0
+ #define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
+ 
++/* VMDK needs at least this to find backing store,
++ * other formats are less */
++#define STORAGE_MAX_HEAD (20*512)
+ 
+ 
+ static struct FileTypeInfo const fileTypeInfo[] = {
+@@ -349,9 +352,14 @@ vmdk4GetBackingStore(char **res,
+                      size_t buf_size)
+ {
+     static const char prefix[] = "parentFileNameHint=\"";
+-
+-    char desc[20*512 + 1], *start, *end;
++    char *desc, *start, *end;
+     size_t len;
++    int ret = BACKING_STORE_ERROR;
++
++    if (VIR_ALLOC_N(desc, STORAGE_MAX_HEAD + 1) < 0) {
++        virReportOOMError();
++        goto cleanup;
++    }
+ 
+     *res = NULL;
+     /*
+@@ -363,29 +371,42 @@ vmdk4GetBackingStore(char **res,
+      */
+     *format = VIR_STORAGE_FILE_AUTO;
+ 
+-    if (buf_size <= 0x200)
+-        return BACKING_STORE_INVALID;
++    if (buf_size <= 0x200) {
++        ret = BACKING_STORE_INVALID;
++        goto cleanup;
++    }
+     len = buf_size - 0x200;
+-    if (len > sizeof(desc) - 1)
+-        len = sizeof(desc) - 1;
++    if (len > STORAGE_MAX_HEAD)
++        len = STORAGE_MAX_HEAD;
+     memcpy(desc, buf + 0x200, len);
+     desc[len] = '\0';
+     start = strstr(desc, prefix);
+-    if (start == NULL)
+-        return BACKING_STORE_OK;
++    if (start == NULL) {
++        ret = BACKING_STORE_OK;
++        goto cleanup;
++    }
+     start += strlen(prefix);
+     end = strchr(start, '"');
+-    if (end == NULL)
+-        return BACKING_STORE_INVALID;
+-    if (end == start)
+-        return BACKING_STORE_OK;
++    if (end == NULL) {
++        ret = BACKING_STORE_INVALID;
++        goto cleanup;
++    }
++    if (end == start) {
++        ret = BACKING_STORE_OK;
++        goto cleanup;
++    }
+     *end = '\0';
+     *res = strdup(start);
+     if (*res == NULL) {
+         virReportOOMError();
+-        return BACKING_STORE_ERROR;
++        goto cleanup;
+     }
+-    return BACKING_STORE_OK;
++
++    ret = BACKING_STORE_OK;
++
++cleanup:
++    VIR_FREE(desc);
++    return ret;
+ }
+ 
+ /**
+@@ -411,148 +432,325 @@ absolutePathFromBaseFile(const char *base_file, const char *path)
+     return res;
+ }
+ 
+-/**
+- * Probe the header of a file to determine what type of disk image
+- * it is, and info about its capacity if available.
+- */
+-int
+-virStorageFileGetMetadataFromFD(const char *path,
+-                                int fd,
+-                                virStorageFileMetadata *meta)
++
++static bool
++virStorageFileMatchesMagic(int format,
++                           unsigned char *buf,
++                           size_t buflen)
+ {
+-    unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */
+-    int len, i;
++    int mlen;
+ 
+-    memset(meta, 0, sizeof (*meta));
++    if (fileTypeInfo[format].magic == NULL)
++        return false;
+ 
+-    /* If all else fails, call it a raw file */
+-    meta->format = VIR_STORAGE_FILE_RAW;
++    /* Validate magic data */
++    mlen = strlen(fileTypeInfo[format].magic);
++    if (mlen > buflen)
++        return false;
+ 
+-    if ((len = read(fd, head, sizeof(head))) < 0) {
+-        virReportSystemError(errno, _("cannot read header '%s'"), path);
+-        return -1;
++    if (memcmp(buf, fileTypeInfo[format].magic, mlen) != 0)
++        return false;
++
++    return true;
++}
++
++
++static bool
++virStorageFileMatchesExtension(int format,
++                               const char *path)
++{
++    if (fileTypeInfo[format].extension == NULL)
++        return false;
++
++    if (virFileHasSuffix(path, fileTypeInfo[format].extension))
++        return true;
++
++    return false;
++}
++
++
++static bool
++virStorageFileMatchesVersion(int format,
++                             unsigned char *buf,
++                             size_t buflen)
++{
++    int version;
++
++    /* Validate version number info */
++    if (fileTypeInfo[format].versionOffset == -1)
++        return false;
++
++    if ((fileTypeInfo[format].versionOffset + 4) > buflen)
++        return false;
++
++    if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) {
++        version =
++            (buf[fileTypeInfo[format].versionOffset+3] << 24) |
++            (buf[fileTypeInfo[format].versionOffset+2] << 16) |
++            (buf[fileTypeInfo[format].versionOffset+1] << 8) |
++            (buf[fileTypeInfo[format].versionOffset]);
++    } else {
++        version =
++            (buf[fileTypeInfo[format].versionOffset] << 24) |
++            (buf[fileTypeInfo[format].versionOffset+1] << 16) |
++            (buf[fileTypeInfo[format].versionOffset+2] << 8) |
++            (buf[fileTypeInfo[format].versionOffset+3]);
+     }
++    if (version != fileTypeInfo[format].versionNumber)
++        return false;
+ 
+-    /* First check file magic */
+-    for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) {
+-        int mlen;
+-
+-        if (fileTypeInfo[i].magic == NULL)
+-            continue;
+-
+-        /* Validate magic data */
+-        mlen = strlen(fileTypeInfo[i].magic);
+-        if (mlen > len)
+-            continue;
+-        if (memcmp(head, fileTypeInfo[i].magic, mlen) != 0)
+-            continue;
+-
+-        /* Validate version number info */
+-        if (fileTypeInfo[i].versionNumber != -1) {
+-            int version;
+-
+-            if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) {
+-                version = (head[fileTypeInfo[i].versionOffset+3] << 24) |
+-                    (head[fileTypeInfo[i].versionOffset+2] << 16) |
+-                    (head[fileTypeInfo[i].versionOffset+1] << 8) |
+-                    head[fileTypeInfo[i].versionOffset];
+-            } else {
+-                version = (head[fileTypeInfo[i].versionOffset] << 24) |
+-                    (head[fileTypeInfo[i].versionOffset+1] << 16) |
+-                    (head[fileTypeInfo[i].versionOffset+2] << 8) |
+-                    head[fileTypeInfo[i].versionOffset+3];
+-            }
+-            if (version != fileTypeInfo[i].versionNumber)
+-                continue;
+-        }
++    return true;
++}
+ 
+-        /* Optionally extract capacity from file */
+-        if (fileTypeInfo[i].sizeOffset != -1) {
+-            if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) {
+-                meta->capacity =
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7] << 56) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 48) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 40) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 32) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 24) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 16) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 8) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset]);
+-            } else {
+-                meta->capacity =
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset] << 56) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 48) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 40) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 32) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 24) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 16) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 8) |
+-                    ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7]);
+-            }
+-            /* Avoid unlikely, but theoretically possible overflow */
+-            if (meta->capacity > (ULLONG_MAX / fileTypeInfo[i].sizeMultiplier))
+-                continue;
+-            meta->capacity *= fileTypeInfo[i].sizeMultiplier;
+-        }
+ 
+-        if (fileTypeInfo[i].qcowCryptOffset != -1) {
+-            int crypt_format;
++static int
++virStorageFileGetMetadataFromBuf(int format,
++                                 const char *path,
++                                 unsigned char *buf,
++                                 size_t buflen,
++                                 virStorageFileMetadata *meta)
++{
++    /* XXX we should consider moving virStorageBackendUpdateVolInfo
++     * code into this method, for non-magic files
++     */
++    if (!fileTypeInfo[format].magic) {
++        return 0;
++    }
+ 
+-            crypt_format = (head[fileTypeInfo[i].qcowCryptOffset] << 24) |
+-                (head[fileTypeInfo[i].qcowCryptOffset+1] << 16) |
+-                (head[fileTypeInfo[i].qcowCryptOffset+2] << 8) |
+-                head[fileTypeInfo[i].qcowCryptOffset+3];
+-            meta->encrypted = crypt_format != 0;
++    /* Optionally extract capacity from file */
++    if (fileTypeInfo[format].sizeOffset != -1) {
++        if ((fileTypeInfo[format].sizeOffset + 8) > buflen)
++            return 1;
++
++        if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) {
++            meta->capacity =
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7] << 56) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 48) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 40) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 32) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 24) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 16) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 8) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset]);
++        } else {
++            meta->capacity =
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset] << 56) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 48) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 40) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 32) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 24) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 16) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 8) |
++                ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7]);
+         }
++        /* Avoid unlikely, but theoretically possible overflow */
++        if (meta->capacity > (ULLONG_MAX / fileTypeInfo[format].sizeMultiplier))
++            return 1;
++        meta->capacity *= fileTypeInfo[format].sizeMultiplier;
++    }
+ 
+-        /* Validation passed, we know the file format now */
+-        meta->format = i;
+-        if (fileTypeInfo[i].getBackingStore != NULL) {
+-            char *backing;
+-            int backingFormat;
++    if (fileTypeInfo[format].qcowCryptOffset != -1) {
++        int crypt_format;
+ 
+-            switch (fileTypeInfo[i].getBackingStore(&backing,
+-                                                    &backingFormat,
+-                                                    head, len)) {
+-            case BACKING_STORE_OK:
+-                break;
++        crypt_format =
++            (buf[fileTypeInfo[format].qcowCryptOffset] << 24) |
++            (buf[fileTypeInfo[format].qcowCryptOffset+1] << 16) |
++            (buf[fileTypeInfo[format].qcowCryptOffset+2] << 8) |
++            (buf[fileTypeInfo[format].qcowCryptOffset+3]);
++        meta->encrypted = crypt_format != 0;
++    }
+ 
+-            case BACKING_STORE_INVALID:
+-                continue;
++    if (fileTypeInfo[format].getBackingStore != NULL) {
++        char *backing;
++        int backingFormat;
++        int ret = fileTypeInfo[format].getBackingStore(&backing,
++                                                       &backingFormat,
++                                                       buf, buflen);
++        if (ret == BACKING_STORE_INVALID)
++            return 1;
++
++        if (ret == BACKING_STORE_ERROR)
++            return -1;
+ 
+-            case BACKING_STORE_ERROR:
++        if (backing != NULL) {
++            meta->backingStore = absolutePathFromBaseFile(path, backing);
++            VIR_FREE(backing);
++            if (meta->backingStore == NULL) {
++                virReportOOMError();
+                 return -1;
+             }
+-            if (backing != NULL) {
+-                meta->backingStore = absolutePathFromBaseFile(path, backing);
+-                VIR_FREE(backing);
+-                if (meta->backingStore == NULL) {
+-                    virReportOOMError();
+-                    return -1;
+-                }
+-                meta->backingStoreFormat = backingFormat;
+-            } else {
+-                meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
+-            }
++            meta->backingStoreFormat = backingFormat;
++        } else {
++            meta->backingStore = NULL;
++            meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
++        }
++    }
++
++    return 0;
++}
++
++
++static int
++virStorageFileProbeFormatFromBuf(const char *path,
++                                 unsigned char *buf,
++                                 size_t buflen)
++{
++    int format = VIR_STORAGE_FILE_RAW;
++    int i;
++
++    /* First check file magic */
++    for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) {
++        if (virStorageFileMatchesMagic(i, buf, buflen) &&
++            virStorageFileMatchesVersion(i, buf, buflen)) {
++            format = i;
++            goto cleanup;
+         }
+-        return 0;
+     }
+ 
+     /* No magic, so check file extension */
+-    for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) {
+-        if (fileTypeInfo[i].extension == NULL)
+-            continue;
++    for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) {
++        if (virStorageFileMatchesExtension(i, path)) {
++            format = i;
++            goto cleanup;
++        }
++    }
+ 
+-        if (!virFileHasSuffix(path, fileTypeInfo[i].extension))
+-            continue;
++cleanup:
++    return format;
++}
+ 
+-        meta->format = i;
+-        return 0;
++
++/**
++ * virStorageFileProbeFormatFromFD:
++ *
++ * Probe for the format of 'fd' (which is an open file descriptor
++ * pointing to 'path'), returning the detected disk format.
++ *
++ * Callers are advised never to trust the returned 'format'
++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
++ * malicious guest can turn a file into any other non-raw
++ * format at will.
++ *
++ * Best option: Don't use this function
++ */
++int
++virStorageFileProbeFormatFromFD(const char *path, int fd)
++{
++    unsigned char *head;
++    ssize_t len = STORAGE_MAX_HEAD;
++    int ret = -1;
++
++    if (VIR_ALLOC_N(head, len) < 0) {
++        virReportOOMError();
++        return -1;
+     }
+ 
+-    return 0;
++    if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
++        virReportSystemError(errno, _("cannot set to start of '%s'"), path);
++        goto cleanup;
++    }
++
++    if ((len = read(fd, head, len)) < 0) {
++        virReportSystemError(errno, _("cannot read header '%s'"), path);
++        goto cleanup;
++    }
++
++    ret = virStorageFileProbeFormatFromBuf(path, head, len);
++
++cleanup:
++    VIR_FREE(head);
++    return ret;
++}
++
++
++/**
++ * virStorageFileProbeFormat:
++ *
++ * Probe for the format of 'path', returning the detected
++ * disk format.
++ *
++ * Callers are advised never to trust the returned 'format'
++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
++ * malicious guest can turn a raw file into any other non-raw
++ * format at will.
++ *
++ * Best option: Don't use this function
++ */
++int
++virStorageFileProbeFormat(const char *path)
++{
++    int fd, ret;
++
++    if ((fd = open(path, O_RDONLY)) < 0) {
++        virReportSystemError(errno, _("cannot open file '%s'"), path);
++        return -1;
++    }
++
++    ret = virStorageFileProbeFormatFromFD(path, fd);
++
++    close(fd);
++
++    return ret;
+ }
+ 
++/**
++ * virStorageFileGetMetadataFromFD:
++ *
++ * Probe for the format of 'fd' (which is an open file descriptor
++ * for the file 'path'), filling 'meta' with the detected
++ * format and other associated metadata.
++ *
++ * Callers are advised never to trust the returned 'meta->format'
++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
++ * malicious guest can turn a raw file into any other non-raw
++ * format at will.
++ */
++int
++virStorageFileGetMetadataFromFD(const char *path,
++                                int fd,
++                                virStorageFileMetadata *meta)
++{
++    unsigned char *head;
++    ssize_t len = STORAGE_MAX_HEAD;
++    int ret = -1;
++
++    if (VIR_ALLOC_N(head, len) < 0) {
++        virReportOOMError();
++        return -1;
++    }
++
++    memset(meta, 0, sizeof (*meta));
++
++    if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
++        virReportSystemError(errno, _("cannot set to start of '%s'"), path);
++        goto cleanup;
++    }
++
++    if ((len = read(fd, head, len)) < 0) {
++        virReportSystemError(errno, _("cannot read header '%s'"), path);
++        goto cleanup;
++    }
++
++    meta->format = virStorageFileProbeFormatFromBuf(path, head, len);
++
++    ret = virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta);
++
++cleanup:
++    VIR_FREE(head);
++    return ret;
++}
++
++/**
++ * virStorageFileGetMetadata:
++ *
++ * Probe for the format of 'path', filling 'meta' with the detected
++ * format and other associated metadata.
++ *
++ * Callers are advised never to trust the returned 'meta->format'
++ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
++ * malicious guest can turn a raw file into any other non-raw
++ * format at will.
++ */
+ int
+ virStorageFileGetMetadata(const char *path,
+                           virStorageFileMetadata *meta)
+diff --git a/src/util/storage_file.h b/src/util/storage_file.h
+index 6328ba7..3420d44 100644
+--- a/src/util/storage_file.h
++++ b/src/util/storage_file.h
+@@ -57,6 +57,10 @@ typedef struct _virStorageFileMetadata {
+ #  define DEV_BSIZE 512
+ # endif
+ 
++int virStorageFileProbeFormat(const char *path);
++int virStorageFileProbeFormatFromFD(const char *path,
++                                    int fd);
++
+ int virStorageFileGetMetadata(const char *path,
+                               virStorageFileMetadata *meta);
+ int virStorageFileGetMetadataFromFD(const char *path,
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-04-require-storage-format.patch b/libvirt-0.8.2-04-require-storage-format.patch
new file mode 100644
index 0000000..deb4c37
--- /dev/null
+++ b/libvirt-0.8.2-04-require-storage-format.patch
@@ -0,0 +1,285 @@
+From 726a63a437efd96510ce316bf30d16f213d4db27 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Tue, 15 Jun 2010 16:15:51 +0100
+Subject: [PATCH 04/11] Require format to be passed into virStorageFileGetMetadata
+
+Require the disk image to be passed into virStorageFileGetMetadata.
+If this is set to VIR_STORAGE_FILE_AUTO, then the format will be
+resolved using probing. This makes it easier to control when
+probing will be used
+
+* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
+  src/security/security_selinux.c, src/security/virt-aa-helper.c:
+  Set VIR_STORAGE_FILE_AUTO when calling virStorageFileGetMetadata.
+* src/storage/storage_backend_fs.c: Probe for disk format before
+  calling virStorageFileGetMetadata.
+* src/util/storage_file.h, src/util/storage_file.c: Remove format
+  from virStorageFileMeta struct & require it to be passed into
+  method.
+---
+ src/qemu/qemu_driver.c           |   27 +++++++++++++++++---
+ src/qemu/qemu_security_dac.c     |    4 ++-
+ src/security/security_selinux.c  |    4 ++-
+ src/security/virt-aa-helper.c    |    4 ++-
+ src/storage/storage_backend_fs.c |   11 ++++++--
+ src/util/storage_file.c          |   50 +++++++++++++++++++++++++------------
+ src/util/storage_file.h          |    3 +-
+ 7 files changed, 76 insertions(+), 27 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 487bfa3..97f2990 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -3069,7 +3069,9 @@ static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
+             }
+         }
+ 
+-        rc = virStorageFileGetMetadata(path, &meta);
++        rc = virStorageFileGetMetadata(path,
++                                       VIR_STORAGE_FILE_AUTO,
++                                       &meta);
+         if (rc < 0)
+             VIR_WARN("Unable to lookup parent image for %s", path);
+ 
+@@ -3119,7 +3121,9 @@ static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
+             }
+         }
+ 
+-        rc = virStorageFileGetMetadata(path, &meta);
++        rc = virStorageFileGetMetadata(path,
++                                       VIR_STORAGE_FILE_AUTO,
++                                       &meta);
+         if (rc < 0)
+             VIR_WARN("Unable to lookup parent image for %s", path);
+ 
+@@ -9614,6 +9618,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
+     virDomainDiskDefPtr disk = NULL;
+     struct stat sb;
+     int i;
++    int format;
+ 
+     virCheckFlags(0, -1);
+ 
+@@ -9658,7 +9663,21 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
+     }
+ 
+     /* Probe for magic formats */
+-    if (virStorageFileGetMetadataFromFD(path, fd, &meta) < 0)
++    if (disk->driverType) {
++        if ((format = virStorageFileFormatTypeFromString(disk->driverType)) < 0) {
++            qemuReportError(VIR_ERR_INTERNAL_ERROR,
++                            _("unknown disk format %s for %s"),
++                            disk->driverType, disk->src);
++            goto cleanup;
++        }
++    } else {
++        if ((format = virStorageFileProbeFormat(disk->src)) < 0)
++            goto cleanup;
++    }
++
++    if (virStorageFileGetMetadataFromFD(path, fd,
++                                        format,
++                                        &meta) < 0)
+         goto cleanup;
+ 
+     /* Get info for normal formats */
+@@ -9706,7 +9725,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
+        highest allocated extent from QEMU */
+     if (virDomainObjIsActive(vm) &&
+         disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
+-        meta.format != VIR_STORAGE_FILE_RAW &&
++        format != VIR_STORAGE_FILE_RAW &&
+         S_ISBLK(sb.st_mode)) {
+         qemuDomainObjPrivatePtr priv = vm->privateData;
+         if (qemuDomainObjBeginJob(vm) < 0)
+diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
+index 95015b0..acfe48e 100644
+--- a/src/qemu/qemu_security_dac.c
++++ b/src/qemu/qemu_security_dac.c
+@@ -115,7 +115,9 @@ qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
+         virStorageFileMetadata meta;
+         int ret;
+ 
+-        ret = virStorageFileGetMetadata(path, &meta);
++        ret = virStorageFileGetMetadata(path,
++                                        VIR_STORAGE_FILE_AUTO,
++                                        &meta);
+ 
+         if (path != disk->src)
+             VIR_FREE(path);
+diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
+index e5eef19..5c0f002 100644
+--- a/src/security/security_selinux.c
++++ b/src/security/security_selinux.c
+@@ -457,7 +457,9 @@ SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
+         virStorageFileMetadata meta;
+         int ret;
+ 
+-        ret = virStorageFileGetMetadata(path, &meta);
++        ret = virStorageFileGetMetadata(path,
++                                        VIR_STORAGE_FILE_AUTO,
++                                        &meta);
+ 
+         if (path != disk->src)
+             VIR_FREE(path);
+diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
+index c66f107..2c045e6 100644
+--- a/src/security/virt-aa-helper.c
++++ b/src/security/virt-aa-helper.c
+@@ -830,7 +830,9 @@ get_files(vahControl * ctl)
+             do {
+                 virStorageFileMetadata meta;
+ 
+-                ret = virStorageFileGetMetadata(path, &meta);
++                ret = virStorageFileGetMetadata(path,
++                                                VIR_STORAGE_FILE_AUTO,
++                                                &meta);
+ 
+                 if (path != ctl->def->disks[i]->src)
+                     VIR_FREE(path);
+diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
+index f0cd770..d3ac0fe 100644
+--- a/src/storage/storage_backend_fs.c
++++ b/src/storage/storage_backend_fs.c
+@@ -75,14 +75,19 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
+ 
+     memset(&meta, 0, sizeof(meta));
+ 
+-    if (virStorageFileGetMetadataFromFD(target->path, fd, &meta) < 0) {
++    if ((target->format = virStorageFileProbeFormatFromFD(target->path, fd)) < 0) {
+         close(fd);
+         return -1;
+     }
+ 
+-    close(fd);
++    if (virStorageFileGetMetadataFromFD(target->path, fd,
++                                        target->format,
++                                        &meta) < 0) {
++        close(fd);
++        return -1;
++    }
+ 
+-    target->format = meta.format;
++    close(fd);
+ 
+     if (backingStore) {
+         *backingStore = meta.backingStore;
+diff --git a/src/util/storage_file.c b/src/util/storage_file.c
+index 221268b..9712d92 100644
+--- a/src/util/storage_file.c
++++ b/src/util/storage_file.c
+@@ -696,18 +696,23 @@ virStorageFileProbeFormat(const char *path)
+ /**
+  * virStorageFileGetMetadataFromFD:
+  *
+- * Probe for the format of 'fd' (which is an open file descriptor
+- * for the file 'path'), filling 'meta' with the detected
+- * format and other associated metadata.
++ * Extract metadata about the storage volume with the specified
++ * image format. If image format is VIR_STORAGE_FILE_AUTO, it
++ * will probe to automatically identify the format. 
+  *
+- * Callers are advised never to trust the returned 'meta->format'
+- * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+- * malicious guest can turn a raw file into any other non-raw
+- * format at will.
++ * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a
++ * format, since a malicious guest can turn a raw file into any
++ * other non-raw format at will.
++ *
++ * If the returned meta.backingStoreFormat is VIR_STORAGE_FILE_AUTO
++ * it indicates the image didn't specify an explicit format for its
++ * backing store. Callers are advised against probing for the
++ * backing store format in this case.
+  */
+ int
+ virStorageFileGetMetadataFromFD(const char *path,
+                                 int fd,
++                                int format,
+                                 virStorageFileMetadata *meta)
+ {
+     unsigned char *head;
+@@ -731,9 +736,16 @@ virStorageFileGetMetadataFromFD(const char *path,
+         goto cleanup;
+     }
+ 
+-    meta->format = virStorageFileProbeFormatFromBuf(path, head, len);
++    if (format == VIR_STORAGE_FILE_AUTO)
++        format = virStorageFileProbeFormatFromBuf(path, head, len);
++
++    if (format < 0 ||
++        format >= VIR_STORAGE_FILE_LAST) {
++        virReportSystemError(EINVAL, _("unknown storage file format %d"), format);
++        return -1;
++    }
+ 
+-    ret = virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta);
++    ret = virStorageFileGetMetadataFromBuf(format, path, head, len, meta);
+ 
+ cleanup:
+     VIR_FREE(head);
+@@ -743,16 +755,22 @@ cleanup:
+ /**
+  * virStorageFileGetMetadata:
+  *
+- * Probe for the format of 'path', filling 'meta' with the detected
+- * format and other associated metadata.
++ * Extract metadata about the storage volume with the specified
++ * image format. If image format is VIR_STORAGE_FILE_AUTO, it
++ * will probe to automatically identify the format. 
+  *
+- * Callers are advised never to trust the returned 'meta->format'
+- * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+- * malicious guest can turn a raw file into any other non-raw
+- * format at will.
++ * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a
++ * format, since a malicious guest can turn a raw file into any
++ * other non-raw format at will.
++ *
++ * If the returned meta.backingStoreFormat is VIR_STORAGE_FILE_AUTO
++ * it indicates the image didn't specify an explicit format for its
++ * backing store. Callers are advised against probing for the
++ * backing store format in this case.
+  */
+ int
+ virStorageFileGetMetadata(const char *path,
++                          int format,
+                           virStorageFileMetadata *meta)
+ {
+     int fd, ret;
+@@ -762,7 +780,7 @@ virStorageFileGetMetadata(const char *path,
+         return -1;
+     }
+ 
+-    ret = virStorageFileGetMetadataFromFD(path, fd, meta);
++    ret = virStorageFileGetMetadataFromFD(path, fd, format, meta);
+ 
+     close(fd);
+ 
+diff --git a/src/util/storage_file.h b/src/util/storage_file.h
+index 3420d44..6853182 100644
+--- a/src/util/storage_file.h
++++ b/src/util/storage_file.h
+@@ -46,7 +46,6 @@ enum virStorageFileFormat {
+ VIR_ENUM_DECL(virStorageFileFormat);
+ 
+ typedef struct _virStorageFileMetadata {
+-    int format;
+     char *backingStore;
+     int backingStoreFormat;
+     unsigned long long capacity;
+@@ -62,9 +61,11 @@ int virStorageFileProbeFormatFromFD(const char *path,
+                                     int fd);
+ 
+ int virStorageFileGetMetadata(const char *path,
++                              int format,
+                               virStorageFileMetadata *meta);
+ int virStorageFileGetMetadataFromFD(const char *path,
+                                     int fd,
++                                    int format,
+                                     virStorageFileMetadata *meta);
+ 
+ int virStorageFileIsSharedFS(const char *path);
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-05-disk-path-iterator.patch b/libvirt-0.8.2-05-disk-path-iterator.patch
new file mode 100644
index 0000000..4f74940
--- /dev/null
+++ b/libvirt-0.8.2-05-disk-path-iterator.patch
@@ -0,0 +1,170 @@
+From ac5067f1e2e98181ee0e9230f756697f50d853eb Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Mon, 14 Jun 2010 18:09:15 +0100
+Subject: [PATCH 05/11] Add an API for iterating over disk paths
+
+There is duplicated code which iterates over disk backing stores
+performing some action. Provide a convenient helper for doing
+this to eliminate duplication & risk of mistakes with disk format
+probing
+
+* src/conf/domain_conf.c, src/conf/domain_conf.h,
+  src/libvirt_private.syms: Add virDomainDiskDefForeachPath()
+---
+ src/conf/domain_conf.c   |   99 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/conf/domain_conf.h   |   11 +++++
+ src/libvirt_private.syms |    1 +
+ 3 files changed, 111 insertions(+), 0 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 378c06e..b20ca97 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -45,6 +45,7 @@
+ #include "macvtap.h"
+ #include "nwfilter_conf.h"
+ #include "ignore-value.h"
++#include "storage_file.h"
+ 
+ #define VIR_FROM_THIS VIR_FROM_DOMAIN
+ 
+@@ -7273,4 +7274,102 @@ done:
+ }
+ 
+ 
++int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
++                                bool allowProbing,
++                                bool ignoreOpenFailure,
++                                virDomainDiskDefPathIterator iter,
++                                void *opaque)
++{
++    virHashTablePtr paths;
++    int format;
++    int ret = -1;
++    size_t depth = 0;
++    char *nextpath = NULL;
++
++    if (!disk->src)
++        return 0;
++
++    if (disk->driverType) {
++        const char *formatStr = disk->driverType;
++        if (STREQ(formatStr, "aio"))
++            formatStr = "raw"; /* Xen compat */
++
++        if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) {
++            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
++                                 _("unknown disk format '%s' for %s"),
++                                 disk->driverType, disk->src);
++            return -1;
++        }
++    } else {
++        if (allowProbing) {
++            format = VIR_STORAGE_FILE_AUTO;
++        } else {
++            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
++                                 _("no disk format for %s and probing is disabled"),
++                                 disk->src);
++            return -1;
++        }
++    }
++
++    paths = virHashCreate(5);
++
++    do {
++        virStorageFileMetadata meta;
++        const char *path = nextpath ? nextpath : disk->src;
++        int fd;
++
++        if (iter(disk, path, depth, opaque) < 0)
++            goto cleanup;
++
++        if (virHashLookup(paths, path)) {
++            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
++                                 _("backing store for %s is self-referential"),
++                                 disk->src);
++            goto cleanup;
++        }
++
++        if ((fd = open(path, O_RDONLY)) < 0) {
++            if (ignoreOpenFailure) {
++                char ebuf[1024];
++                VIR_WARN("Ignoring open failure on %s: %s", path,
++                         virStrerror(errno, ebuf, sizeof(ebuf)));
++                break;
++            } else {
++                virReportSystemError(errno,
++                                     _("unable to open disk path %s"),
++                                     path);
++                goto cleanup;
++            }
++        }
++
++        if (virStorageFileGetMetadataFromFD(path, fd, format, &meta) < 0) {
++            close(fd);
++            goto cleanup;
++        }
++        close(fd);
++
++        if (virHashAddEntry(paths, path, (void*)0x1) < 0) {
++            virReportOOMError();
++            goto cleanup;
++        }
++
++        depth++;
++        nextpath = meta.backingStore;
++
++        format = meta.backingStoreFormat;
++
++        if (format == VIR_STORAGE_FILE_AUTO &&
++            !allowProbing)
++            format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */
++    } while (nextpath);
++
++    ret = 0;
++
++cleanup:
++    virHashFree(paths, NULL);
++    VIR_FREE(nextpath);
++
++    return ret;
++}
++
+ #endif /* ! PROXY */
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 01da17e..d46869e 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -1079,6 +1079,17 @@ int virDomainChrDefForeach(virDomainDefPtr def,
+                            void *opaque);
+ 
+ 
++typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
++                                            const char *path,
++                                            size_t depth,
++                                            void *opaque);
++
++int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
++                                bool allowProbing,
++                                bool ignoreOpenFailure,
++                                virDomainDiskDefPathIterator iter,
++                                void *opaque);
++
+ VIR_ENUM_DECL(virDomainVirt)
+ VIR_ENUM_DECL(virDomainBoot)
+ VIR_ENUM_DECL(virDomainFeature)
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 4607f49..b5f3695 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -225,6 +225,7 @@ virDomainSnapshotDefFormat;
+ virDomainSnapshotAssignDef;
+ virDomainObjAssignDef;
+ virDomainChrDefForeach;
++virDomainDiskDefForeachPath;
+ 
+ 
+ # domain_event.h
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-06-use-disk-iterator.patch b/libvirt-0.8.2-06-use-disk-iterator.patch
new file mode 100644
index 0000000..028710e
--- /dev/null
+++ b/libvirt-0.8.2-06-use-disk-iterator.patch
@@ -0,0 +1,506 @@
+From 54c1bb731d2b19a46a594cf9682c022f1e1114d2 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Tue, 15 Jun 2010 16:40:47 +0100
+Subject: [PATCH 06/11] Convert all disk backing store loops to shared helper API
+
+Update the QEMU cgroups code, QEMU DAC security driver, SELinux
+and AppArmour security drivers over to use the shared helper API
+virDomainDiskDefForeachPath().
+
+* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
+  src/security/security_selinux.c, src/security/virt-aa-helper.c:
+  Convert over to use virDomainDiskDefForeachPath()
+---
+ src/qemu/qemu_driver.c          |  161 ++++++++++++++++----------------------
+ src/qemu/qemu_security_dac.c    |   47 ++++--------
+ src/security/security_selinux.c |   67 +++++++----------
+ src/security/virt-aa-helper.c   |   71 ++++++++----------
+ 4 files changed, 142 insertions(+), 204 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 97f2990..99aeffa 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -3040,107 +3040,82 @@ static const char *const defaultDeviceACL[] = {
+ #define DEVICE_PTY_MAJOR 136
+ #define DEVICE_SND_MAJOR 116
+ 
+-static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
+-                               virDomainObjPtr vm,
+-                               virDomainDiskDefPtr disk)
+-{
+-    char *path = disk->src;
+-    int ret = -1;
+ 
+-    while (path != NULL) {
+-        virStorageFileMetadata meta;
+-        int rc;
++static int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
++                                  const char *path,
++                                  size_t depth ATTRIBUTE_UNUSED,
++                                  void *opaque)
++{
++    virCgroupPtr cgroup = opaque;
++    int rc;
+ 
+-        VIR_DEBUG("Process path '%s' for disk", path);
+-        rc = virCgroupAllowDevicePath(cgroup, path);
+-        if (rc != 0) {
+-            /* Get this for non-block devices */
+-            if (rc == -EINVAL) {
+-                VIR_DEBUG("Ignoring EINVAL for %s", path);
+-            } else if (rc == -EACCES) { /* Get this for root squash NFS */
+-                VIR_DEBUG("Ignoring EACCES for %s", path);
+-            } else {
+-                virReportSystemError(-rc,
+-                                     _("Unable to allow device %s for %s"),
+-                                     path, vm->def->name);
+-                if (path != disk->src)
+-                    VIR_FREE(path);
+-                goto cleanup;
+-            }
++    VIR_DEBUG("Process path %s for disk", path);
++    /* XXX RO vs RW */
++    rc = virCgroupAllowDevicePath(cgroup, path);
++    if (rc != 0) {
++        /* Get this for non-block devices */
++        if (rc == -EINVAL) {
++            VIR_DEBUG("Ignoring EINVAL for %s", path);
++        } else if (rc == -EACCES) { /* Get this for root squash NFS */
++            VIR_DEBUG("Ignoring EACCES for %s", path);
++        } else {
++            virReportSystemError(-rc,
++                                 _("Unable to allow access for disk path %s"),
++                                 path);
++            return -1;
+         }
+-
+-        rc = virStorageFileGetMetadata(path,
+-                                       VIR_STORAGE_FILE_AUTO,
+-                                       &meta);
+-        if (rc < 0)
+-            VIR_WARN("Unable to lookup parent image for %s", path);
+-
+-        if (path != disk->src)
+-            VIR_FREE(path);
+-        path = NULL;
+-
+-        if (rc < 0)
+-            break; /* Treating as non fatal */
+-
+-        path = meta.backingStore;
+     }
++    return 0;
++}
+ 
+-    ret = 0;
+ 
+-cleanup:
+-    return ret;
++static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
++                               virDomainDiskDefPtr disk)
++{
++    return virDomainDiskDefForeachPath(disk,
++                                       true,
++                                       true,
++                                       qemuSetupDiskPathAllow,
++                                       cgroup);
+ }
+ 
+ 
+-static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
+-                                  virDomainObjPtr vm,
+-                                  virDomainDiskDefPtr disk)
++static int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
++                                    const char *path,
++                                    size_t depth ATTRIBUTE_UNUSED,
++                                    void *opaque)
+ {
+-    char *path = disk->src;
+-    int ret = -1;
+-
+-    while (path != NULL) {
+-        virStorageFileMetadata meta;
+-        int rc;
++    virCgroupPtr cgroup = opaque;
++    int rc;
+ 
+-        VIR_DEBUG("Process path '%s' for disk", path);
+-        rc = virCgroupDenyDevicePath(cgroup, path);
+-        if (rc != 0) {
+-            /* Get this for non-block devices */
+-            if (rc == -EINVAL) {
+-                VIR_DEBUG("Ignoring EINVAL for %s", path);
+-            } else if (rc == -EACCES) { /* Get this for root squash NFS */
+-                VIR_DEBUG("Ignoring EACCES for %s", path);
+-            } else {
+-                virReportSystemError(-rc,
+-                                     _("Unable to deny device %s for %s"),
+-                                     path, vm->def->name);
+-                if (path != disk->src)
+-                    VIR_FREE(path);
+-                goto cleanup;
+-            }
++    VIR_DEBUG("Process path %s for disk", path);
++    /* XXX RO vs RW */
++    rc = virCgroupDenyDevicePath(cgroup, path);
++    if (rc != 0) {
++        /* Get this for non-block devices */
++        if (rc == -EINVAL) {
++            VIR_DEBUG("Ignoring EINVAL for %s", path);
++        } else if (rc == -EACCES) { /* Get this for root squash NFS */
++            VIR_DEBUG("Ignoring EACCES for %s", path);
++        } else {
++            virReportSystemError(-rc,
++                                 _("Unable to allow access for disk path %s"),
++                                 path);
++            return -1;
+         }
+-
+-        rc = virStorageFileGetMetadata(path,
+-                                       VIR_STORAGE_FILE_AUTO,
+-                                       &meta);
+-        if (rc < 0)
+-            VIR_WARN("Unable to lookup parent image for %s", path);
+-
+-        if (path != disk->src)
+-            VIR_FREE(path);
+-        path = NULL;
+-
+-        if (rc < 0)
+-            break; /* Treating as non fatal */
+-
+-        path = meta.backingStore;
+     }
++    return 0;
++}
+ 
+-    ret = 0;
+ 
+-cleanup:
+-    return ret;
++static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
++                                  virDomainDiskDefPtr disk)
++{
++    return virDomainDiskDefForeachPath(disk,
++                                       true,
++                                       true,
++                                       qemuTeardownDiskPathDeny,
++                                       cgroup);
+ }
+ 
+ 
+@@ -3204,7 +3179,7 @@ static int qemuSetupCgroup(struct qemud_driver *driver,
+         }
+ 
+         for (i = 0; i < vm->def->ndisks ; i++) {
+-            if (qemuSetupDiskCgroup(cgroup, vm, vm->def->disks[i]) < 0)
++            if (qemuSetupDiskCgroup(cgroup, vm->def->disks[i]) < 0)
+                 goto cleanup;
+         }
+ 
+@@ -8035,7 +8010,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
+                                 vm->def->name);
+                 goto endjob;
+             }
+-            if (qemuSetupDiskCgroup(cgroup, vm, dev->data.disk) < 0)
++            if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
+                 goto endjob;
+         }
+ 
+@@ -8080,7 +8055,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
+             /* Fallthrough */
+         }
+         if (ret != 0 && cgroup) {
+-            if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
++            if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+                 VIR_WARN("Failed to teardown cgroup for disk path %s",
+                          NULLSTR(dev->data.disk->src));
+         }
+@@ -8280,7 +8255,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
+                                 vm->def->name);
+                 goto endjob;
+             }
+-            if (qemuSetupDiskCgroup(cgroup, vm, dev->data.disk) < 0)
++            if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
+                 goto endjob;
+         }
+ 
+@@ -8303,7 +8278,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
+         }
+ 
+         if (ret != 0 && cgroup) {
+-            if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
++            if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+                 VIR_WARN("Failed to teardown cgroup for disk path %s",
+                          NULLSTR(dev->data.disk->src));
+         }
+@@ -8430,7 +8405,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
+         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
+ 
+     if (cgroup != NULL) {
+-        if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
++        if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+             VIR_WARN("Failed to teardown cgroup for disk path %s",
+                      NULLSTR(dev->data.disk->src));
+     }
+@@ -8493,7 +8468,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
+         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
+ 
+     if (cgroup != NULL) {
+-        if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
++        if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+             VIR_WARN("Failed to teardown cgroup for disk path %s",
+                      NULLSTR(dev->data.disk->src));
+     }
+diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
+index acfe48e..770010d 100644
+--- a/src/qemu/qemu_security_dac.c
++++ b/src/qemu/qemu_security_dac.c
+@@ -98,45 +98,28 @@ err:
+ 
+ 
+ static int
++qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
++                                    const char *path,
++                                    size_t depth ATTRIBUTE_UNUSED,
++                                    void *opaque ATTRIBUTE_UNUSED)
++{
++    return qemuSecurityDACSetOwnership(path, driver->user, driver->group);
++}
++
++
++static int
+ qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
+                                      virDomainDiskDefPtr disk)
+ 
+ {
+-    const char *path;
+-
+     if (!driver->privileged || !driver->dynamicOwnership)
+         return 0;
+ 
+-    if (!disk->src)
+-        return 0;
+-
+-    path = disk->src;
+-    do {
+-        virStorageFileMetadata meta;
+-        int ret;
+-
+-        ret = virStorageFileGetMetadata(path,
+-                                        VIR_STORAGE_FILE_AUTO,
+-                                        &meta);
+-
+-        if (path != disk->src)
+-            VIR_FREE(path);
+-        path = NULL;
+-
+-        if (ret < 0)
+-            return -1;
+-
+-        if (meta.backingStore != NULL &&
+-            qemuSecurityDACSetOwnership(meta.backingStore,
+-                                        driver->user, driver->group) < 0) {
+-            VIR_FREE(meta.backingStore);
+-            return -1;
+-        }
+-
+-        path = meta.backingStore;
+-    } while (path != NULL);
+-
+-    return qemuSecurityDACSetOwnership(disk->src, driver->user, driver->group);
++    return virDomainDiskDefForeachPath(disk,
++                                       true,
++                                       false,
++                                       qemuSecurityDACSetSecurityFileLabel,
++                                       NULL);
+ }
+ 
+ 
+diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
+index 5c0f002..d191118 100644
+--- a/src/security/security_selinux.c
++++ b/src/security/security_selinux.c
+@@ -439,54 +439,43 @@ SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
++SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
++                            const char *path,
++                            size_t depth,
++                            void *opaque)
++{
++    const virSecurityLabelDefPtr secdef = opaque;
++
++    if (depth == 0) {
++        if (disk->shared) {
++            return SELinuxSetFilecon(path, default_image_context);
++        } else if (disk->readonly) {
++            return SELinuxSetFilecon(path, default_content_context);
++        } else if (secdef->imagelabel) {
++            return SELinuxSetFilecon(path, secdef->imagelabel);
++        } else {
++            return 0;
++        }
++    } else {
++        return SELinuxSetFilecon(path, default_content_context);
++    }
++}
++
++static int
+ SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
+                              virDomainDiskDefPtr disk)
+ 
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+-    const char *path;
+ 
+     if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
+         return 0;
+ 
+-    if (!disk->src)
+-        return 0;
+-
+-    path = disk->src;
+-    do {
+-        virStorageFileMetadata meta;
+-        int ret;
+-
+-        ret = virStorageFileGetMetadata(path,
+-                                        VIR_STORAGE_FILE_AUTO,
+-                                        &meta);
+-
+-        if (path != disk->src)
+-            VIR_FREE(path);
+-        path = NULL;
+-
+-        if (ret < 0)
+-           break;
+-
+-        if (meta.backingStore != NULL &&
+-            SELinuxSetFilecon(meta.backingStore,
+-                              default_content_context) < 0) {
+-            VIR_FREE(meta.backingStore);
+-            return -1;
+-        }
+-
+-        path = meta.backingStore;
+-    } while (path != NULL);
+-
+-    if (disk->shared) {
+-        return SELinuxSetFilecon(disk->src, default_image_context);
+-    } else if (disk->readonly) {
+-        return SELinuxSetFilecon(disk->src, default_content_context);
+-    } else if (secdef->imagelabel) {
+-        return SELinuxSetFilecon(disk->src, secdef->imagelabel);
+-    }
+-
+-    return 0;
++    return virDomainDiskDefForeachPath(disk,
++                                       true,
++                                       false,
++                                       SELinuxSetSecurityFileLabel,
++                                       secdef);
+ }
+ 
+ 
+diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
+index 2c045e6..9ed0cd3 100644
+--- a/src/security/virt-aa-helper.c
++++ b/src/security/virt-aa-helper.c
+@@ -36,7 +36,6 @@
+ #include "uuid.h"
+ #include "hostusb.h"
+ #include "pci.h"
+-#include "storage_file.h"
+ 
+ static char *progname;
+ 
+@@ -801,6 +800,28 @@ file_iterate_pci_cb(pciDevice *dev ATTRIBUTE_UNUSED,
+ }
+ 
+ static int
++add_file_path(virDomainDiskDefPtr disk,
++              const char *path,
++              size_t depth,
++              void *opaque)
++{
++    virBufferPtr buf = opaque;
++    int ret;
++
++    if (depth == 0) {
++        if (disk->readonly)
++            ret = vah_add_file(buf, path, "r");
++        else
++            ret = vah_add_file(buf, path, "rw");
++    } else {
++        ret = vah_add_file(buf, path, "r");
++    }
++
++    return ret;
++}
++
++
++static int
+ get_files(vahControl * ctl)
+ {
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+@@ -821,45 +842,15 @@ get_files(vahControl * ctl)
+         goto clean;
+     }
+ 
+-    for (i = 0; i < ctl->def->ndisks; i++)
+-        if (ctl->def->disks[i] && ctl->def->disks[i]->src) {
+-            int ret;
+-            const char *path;
+-
+-            path = ctl->def->disks[i]->src;
+-            do {
+-                virStorageFileMetadata meta;
+-
+-                ret = virStorageFileGetMetadata(path,
+-                                                VIR_STORAGE_FILE_AUTO,
+-                                                &meta);
+-
+-                if (path != ctl->def->disks[i]->src)
+-                    VIR_FREE(path);
+-                path = NULL;
+-
+-                if (ret < 0) {
+-                    vah_warning("could not open path, skipping");
+-                    continue;
+-                }
+-
+-                if (meta.backingStore != NULL &&
+-                    (ret = vah_add_file(&buf, meta.backingStore, "rw")) != 0) {
+-                    VIR_FREE(meta.backingStore);
+-                    goto clean;
+-                }
+-
+-                path = meta.backingStore;
+-            } while (path != NULL);
+-
+-            if (ctl->def->disks[i]->readonly)
+-                ret = vah_add_file(&buf, ctl->def->disks[i]->src, "r");
+-            else
+-                ret = vah_add_file(&buf, ctl->def->disks[i]->src, "rw");
+-
+-            if (ret != 0)
+-                goto clean;
+-        }
++    for (i = 0; i < ctl->def->ndisks; i++) {
++        int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
++                                              true,
++                                              false,
++                                              add_file_path,
++                                              &buf);
++        if (ret != 0)
++            goto clean;
++    }
+ 
+     for (i = 0; i < ctl->def->nserials; i++)
+         if (ctl->def->serials[i] && ctl->def->serials[i]->data.file.path)
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-07-secdriver-params.patch b/libvirt-0.8.2-07-secdriver-params.patch
new file mode 100644
index 0000000..08adca0
--- /dev/null
+++ b/libvirt-0.8.2-07-secdriver-params.patch
@@ -0,0 +1,1152 @@
+From bbf8c57b06ec1b63ae814114867eaceebb7dc166 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Tue, 15 Jun 2010 17:44:19 +0100
+Subject: [PATCH 07/11] Pass security driver object into all security driver callbacks
+
+The implementation of security driver callbacks often needs
+to access the security driver object. Currently only a handful
+of callbacks include the driver object as a parameter. Later
+patches require this is many more places.
+
+* src/qemu/qemu_driver.c: Pass in the security driver object
+  to all callbacks
+* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c,
+  src/security/security_apparmor.c, src/security/security_driver.h,
+  src/security/security_selinux.c: Add a virSecurityDriverPtr
+  param to all security callbacks
+---
+ src/qemu/qemu_driver.c           |   88 ++++++++++++++++++++-----------
+ src/qemu/qemu_security_dac.c     |   44 +++++++++++-----
+ src/qemu/qemu_security_stacked.c |  107 +++++++++++++++++++++++++-------------
+ src/security/security_apparmor.c |   57 +++++++++++++-------
+ src/security/security_driver.h   |   40 ++++++++++----
+ src/security/security_selinux.c  |   56 +++++++++++++------
+ 6 files changed, 260 insertions(+), 132 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 99aeffa..616547c 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -1278,7 +1278,8 @@ qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaq
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainReserveSecurityLabel &&
+-        driver->securityDriver->domainReserveSecurityLabel(obj) < 0)
++        driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver,
++                                                           obj) < 0)
+         goto error;
+ 
+     if (obj->def->id >= driver->nextvmid)
+@@ -3401,13 +3402,15 @@ static int qemudStartVMDaemon(virConnectPtr conn,
+     DEBUG0("Generating domain security label (if required)");
+     if (driver->securityDriver &&
+         driver->securityDriver->domainGenSecurityLabel &&
+-        driver->securityDriver->domainGenSecurityLabel(vm) < 0)
++        driver->securityDriver->domainGenSecurityLabel(driver->securityDriver,
++                                                       vm) < 0)
+         goto cleanup;
+ 
+     DEBUG0("Generating setting domain security labels (if required)");
+     if (driver->securityDriver &&
+         driver->securityDriver->domainSetSecurityAllLabel &&
+-        driver->securityDriver->domainSetSecurityAllLabel(vm, stdin_path) < 0) {
++        driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver,
++                                                          vm, stdin_path) < 0) {
+         if (stdin_path && virStorageFileIsSharedFS(stdin_path) != 1)
+             goto cleanup;
+     }
+@@ -3766,10 +3769,12 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver,
+     /* Reset Security Labels */
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityAllLabel)
+-        driver->securityDriver->domainRestoreSecurityAllLabel(vm, migrated);
++        driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver,
++                                                              vm, migrated);
+     if (driver->securityDriver &&
+         driver->securityDriver->domainReleaseSecurityLabel)
+-        driver->securityDriver->domainReleaseSecurityLabel(vm);
++        driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver,
++                                                           vm);
+ 
+     /* Clear out dynamically assigned labels */
+     if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
+@@ -5171,7 +5176,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
+     if ((!bypassSecurityDriver) &&
+         driver->securityDriver &&
+         driver->securityDriver->domainSetSavedStateLabel &&
+-        driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1)
++        driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
++                                                         vm, path) == -1)
+         goto endjob;
+ 
+     if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
+@@ -5206,7 +5212,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
+     if ((!bypassSecurityDriver) &&
+         driver->securityDriver &&
+         driver->securityDriver->domainRestoreSavedStateLabel &&
+-        driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1)
++        driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
++                                                             vm, path) == -1)
+         VIR_WARN("failed to restore save state label on %s", path);
+ 
+     if (cgroup != NULL) {
+@@ -5253,7 +5260,8 @@ endjob:
+             if ((!bypassSecurityDriver) &&
+                 driver->securityDriver &&
+                 driver->securityDriver->domainRestoreSavedStateLabel &&
+-                driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1)
++                driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
++                                                                     vm, path) == -1)
+                 VIR_WARN("failed to restore save state label on %s", path);
+         }
+ 
+@@ -5488,7 +5496,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainSetSavedStateLabel &&
+-        driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1)
++        driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
++                                                         vm, path) == -1)
+         goto endjob;
+ 
+     /* Migrate will always stop the VM, so the resume condition is
+@@ -5531,7 +5540,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSavedStateLabel &&
+-        driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1)
++        driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
++                                                             vm, path) == -1)
+         goto endjob;
+ 
+ endjob:
+@@ -5914,12 +5924,13 @@ static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr sec
+      *   QEMU monitor hasn't seen SIGHUP/ERR on poll().
+      */
+     if (virDomainObjIsActive(vm)) {
+-        if (driver->securityDriver && driver->securityDriver->domainGetSecurityProcessLabel) {
+-            if (driver->securityDriver->domainGetSecurityProcessLabel(vm, seclabel) == -1) {
+-                qemuReportError(VIR_ERR_INTERNAL_ERROR,
+-                                "%s", _("Failed to get security label"));
+-                goto cleanup;
+-            }
++        if (driver->securityDriver &&
++            driver->securityDriver->domainGetSecurityProcessLabel &&
++            driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver,
++                                                                  vm, seclabel) < 0) {
++            qemuReportError(VIR_ERR_INTERNAL_ERROR,
++                            "%s", _("Failed to get security label"));
++            goto cleanup;
+         }
+     }
+ 
+@@ -6325,7 +6336,8 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
+ out:
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSavedStateLabel &&
+-        driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1)
++        driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
++                                                             vm, path) == -1)
+         VIR_WARN("failed to restore save state label on %s", path);
+ 
+     return ret;
+@@ -7039,7 +7051,8 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainSetSecurityImageLabel &&
+-        driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
++                                                            vm, disk) < 0)
+         return -1;
+ 
+     if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags)))
+@@ -7068,7 +7081,8 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityDriver->domainRestoreSecurityImageLabel(vm, origdisk) < 0)
++        driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
++                                                                vm, origdisk) < 0)
+         VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src);
+ 
+     VIR_FREE(origdisk->src);
+@@ -7086,7 +7100,8 @@ error:
+     VIR_FREE(driveAlias);
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
++                                                                vm, disk) < 0)
+         VIR_WARN("Unable to restore security label on new media %s", disk->src);
+     return -1;
+ }
+@@ -7113,7 +7128,8 @@ static int qemudDomainAttachPciDiskDevice(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainSetSecurityImageLabel &&
+-        driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
++                                                            vm, disk) < 0)
+         return -1;
+ 
+     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+@@ -7180,7 +7196,8 @@ error:
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
++                                                                vm, disk) < 0)
+         VIR_WARN("Unable to restore security label on %s", disk->src);
+ 
+     return -1;
+@@ -7322,7 +7339,8 @@ static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainSetSecurityImageLabel &&
+-        driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
++                                                            vm, disk) < 0)
+         return -1;
+ 
+     /* We should have an address already, so make sure */
+@@ -7408,7 +7426,8 @@ error:
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
++                                                                vm, disk) < 0)
+         VIR_WARN("Unable to restore security label on %s", disk->src);
+ 
+     return -1;
+@@ -7435,7 +7454,8 @@ static int qemudDomainAttachUsbMassstorageDevice(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainSetSecurityImageLabel &&
+-        driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
++                                                            vm, disk) < 0)
+         return -1;
+ 
+     if (!disk->src) {
+@@ -7491,7 +7511,8 @@ error:
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0)
++        driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
++                                                                vm, disk) < 0)
+         VIR_WARN("Unable to restore security label on %s", disk->src);
+ 
+     return -1;
+@@ -7928,7 +7949,8 @@ static int qemudDomainAttachHostDevice(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainSetSecurityHostdevLabel &&
+-        driver->securityDriver->domainSetSecurityHostdevLabel(vm, hostdev) < 0)
++        driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
++                                                              vm, hostdev) < 0)
+         return -1;
+ 
+     switch (hostdev->source.subsys.type) {
+@@ -7956,7 +7978,8 @@ static int qemudDomainAttachHostDevice(struct qemud_driver *driver,
+ error:
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityHostdevLabel &&
+-        driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, hostdev) < 0)
++        driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
++                                                                  vm, hostdev) < 0)
+         VIR_WARN0("Unable to restore host device labelling on hotplug fail");
+ 
+     return -1;
+@@ -8401,7 +8424,8 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityDriver->domainRestoreSecurityImageLabel(vm, dev->data.disk) < 0)
++        driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
++                                                                vm, dev->data.disk) < 0)
+         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
+ 
+     if (cgroup != NULL) {
+@@ -8464,7 +8488,8 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityDriver->domainRestoreSecurityImageLabel(vm, dev->data.disk) < 0)
++        driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
++                                                                vm, dev->data.disk) < 0)
+         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
+ 
+     if (cgroup != NULL) {
+@@ -8889,7 +8914,8 @@ static int qemudDomainDetachHostDevice(struct qemud_driver *driver,
+ 
+     if (driver->securityDriver &&
+         driver->securityDriver->domainRestoreSecurityHostdevLabel &&
+-        driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, dev->data.hostdev) < 0)
++        driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
++                                                                  vm, dev->data.hostdev) < 0)
+         VIR_WARN0("Failed to restore host device labelling");
+ 
+     return ret;
+diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
+index 770010d..0bbcf69 100644
+--- a/src/qemu/qemu_security_dac.c
++++ b/src/qemu/qemu_security_dac.c
+@@ -108,7 +108,8 @@ qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
++qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                     virDomainObjPtr vm ATTRIBUTE_UNUSED,
+                                      virDomainDiskDefPtr disk)
+ 
+ {
+@@ -124,7 +125,8 @@ qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACRestoreSecurityImageLabelInt(virDomainObjPtr vm ATTRIBUTE_UNUSED,
++qemuSecurityDACRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                            virDomainObjPtr vm ATTRIBUTE_UNUSED,
+                                             virDomainDiskDefPtr disk,
+                                             int migrated)
+ {
+@@ -166,10 +168,11 @@ qemuSecurityDACRestoreSecurityImageLabelInt(virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACRestoreSecurityImageLabel(virDomainObjPtr vm,
++qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv,
++                                         virDomainObjPtr vm,
+                                          virDomainDiskDefPtr disk)
+ {
+-    return qemuSecurityDACRestoreSecurityImageLabelInt(vm, disk, 0);
++    return qemuSecurityDACRestoreSecurityImageLabelInt(drv, vm, disk, 0);
+ }
+ 
+ 
+@@ -192,7 +195,8 @@ qemuSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACSetSecurityHostdevLabel(virDomainObjPtr vm,
++qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                       virDomainObjPtr vm,
+                                        virDomainHostdevDefPtr dev)
+ 
+ {
+@@ -261,7 +265,8 @@ qemuSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACRestoreSecurityHostdevLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
++qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                           virDomainObjPtr vm ATTRIBUTE_UNUSED,
+                                            virDomainHostdevDefPtr dev)
+ 
+ {
+@@ -407,7 +412,8 @@ qemuSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm,
++qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv,
++                                       virDomainObjPtr vm,
+                                        int migrated)
+ {
+     int i;
+@@ -420,12 +426,14 @@ qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm,
+               vm->def->name, migrated);
+ 
+     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+-        if (qemuSecurityDACRestoreSecurityHostdevLabel(vm,
++        if (qemuSecurityDACRestoreSecurityHostdevLabel(drv,
++                                                       vm,
+                                                        vm->def->hostdevs[i]) < 0)
+             rc = -1;
+     }
+     for (i = 0 ; i < vm->def->ndisks ; i++) {
+-        if (qemuSecurityDACRestoreSecurityImageLabelInt(vm,
++        if (qemuSecurityDACRestoreSecurityImageLabelInt(drv,
++                                                        vm,
+                                                         vm->def->disks[i],
+                                                         migrated) < 0)
+             rc = -1;
+@@ -461,7 +469,9 @@ qemuSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path ATTRIBUTE_UNUSED)
++qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv,
++                                   virDomainObjPtr vm,
++                                   const char *stdin_path ATTRIBUTE_UNUSED)
+ {
+     int i;
+ 
+@@ -472,11 +482,15 @@ qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path AT
+         /* XXX fixme - we need to recursively label the entriy tree :-( */
+         if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
+             continue;
+-        if (qemuSecurityDACSetSecurityImageLabel(vm, vm->def->disks[i]) < 0)
++        if (qemuSecurityDACSetSecurityImageLabel(drv,
++                                                 vm,
++                                                 vm->def->disks[i]) < 0)
+             return -1;
+     }
+     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+-        if (qemuSecurityDACSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0)
++        if (qemuSecurityDACSetSecurityHostdevLabel(drv,
++                                                   vm,
++                                                   vm->def->hostdevs[i]) < 0)
+             return -1;
+     }
+ 
+@@ -503,7 +517,8 @@ qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path AT
+ 
+ 
+ static int
+-qemuSecurityDACSetSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
++qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                  virDomainObjPtr vm ATTRIBUTE_UNUSED,
+                                   const char *savefile)
+ {
+     if (!driver->privileged)
+@@ -514,7 +529,8 @@ qemuSecurityDACSetSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-qemuSecurityDACRestoreSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
++qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                      virDomainObjPtr vm ATTRIBUTE_UNUSED,
+                                       const char *savefile)
+ {
+     if (!driver->privileged)
+diff --git a/src/qemu/qemu_security_stacked.c b/src/qemu/qemu_security_stacked.c
+index df76135..432d095 100644
+--- a/src/qemu/qemu_security_stacked.c
++++ b/src/qemu/qemu_security_stacked.c
+@@ -57,18 +57,21 @@ qemuSecurityStackedVerify(virDomainDefPtr def)
+ 
+ 
+ static int
+-qemuSecurityStackedGenLabel(virDomainObjPtr vm)
++qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                            virDomainObjPtr vm)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainGenSecurityLabel &&
+-        driver->securitySecondaryDriver->domainGenSecurityLabel(vm) < 0)
++        driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver,
++                                                                vm) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainGenSecurityLabel &&
+-        driver->securityPrimaryDriver->domainGenSecurityLabel(vm) < 0)
++        driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver,
++                                                              vm) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -76,18 +79,21 @@ qemuSecurityStackedGenLabel(virDomainObjPtr vm)
+ 
+ 
+ static int
+-qemuSecurityStackedReleaseLabel(virDomainObjPtr vm)
++qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                virDomainObjPtr vm)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainReleaseSecurityLabel &&
+-        driver->securitySecondaryDriver->domainReleaseSecurityLabel(vm) < 0)
++        driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver,
++                                                                    vm) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainReleaseSecurityLabel &&
+-        driver->securityPrimaryDriver->domainReleaseSecurityLabel(vm) < 0)
++        driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver,
++                                                                  vm) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -95,18 +101,21 @@ qemuSecurityStackedReleaseLabel(virDomainObjPtr vm)
+ 
+ 
+ static int
+-qemuSecurityStackedReserveLabel(virDomainObjPtr vm)
++qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                virDomainObjPtr vm)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainReserveSecurityLabel &&
+-        driver->securitySecondaryDriver->domainReserveSecurityLabel(vm) < 0)
++        driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver,
++                                                                    vm) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainReserveSecurityLabel &&
+-        driver->securityPrimaryDriver->domainReserveSecurityLabel(vm) < 0)
++        driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver,
++                                                                  vm) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -114,19 +123,22 @@ qemuSecurityStackedReserveLabel(virDomainObjPtr vm)
+ 
+ 
+ static int
+-qemuSecurityStackedSetSecurityImageLabel(virDomainObjPtr vm,
++qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                         virDomainObjPtr vm,
+                                          virDomainDiskDefPtr disk)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainSetSecurityImageLabel &&
+-        driver->securitySecondaryDriver->domainSetSecurityImageLabel(vm, disk) < 0)
++        driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver,
++                                                                     vm, disk) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainSetSecurityImageLabel &&
+-        driver->securityPrimaryDriver->domainSetSecurityImageLabel(vm, disk) < 0)
++        driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver,
++                                                                   vm, disk) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -134,19 +146,22 @@ qemuSecurityStackedSetSecurityImageLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
+-qemuSecurityStackedRestoreSecurityImageLabel(virDomainObjPtr vm,
++qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                             virDomainObjPtr vm,
+                                              virDomainDiskDefPtr disk)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainRestoreSecurityImageLabel &&
+-        driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0)
++        driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver,
++                                                                         vm, disk) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainRestoreSecurityImageLabel &&
+-        driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0)
++        driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver,
++                                                                       vm, disk) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -154,7 +169,8 @@ qemuSecurityStackedRestoreSecurityImageLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
+-qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm,
++qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                           virDomainObjPtr vm,
+                                            virDomainHostdevDefPtr dev)
+ 
+ {
+@@ -162,12 +178,14 @@ qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm,
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainSetSecurityHostdevLabel &&
+-        driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0)
++        driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver,
++                                                                       vm, dev) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainSetSecurityHostdevLabel &&
+-        driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0)
++        driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver,
++                                                                     vm, dev) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -175,20 +193,22 @@ qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
+-qemuSecurityStackedRestoreSecurityHostdevLabel(virDomainObjPtr vm,
++qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                               virDomainObjPtr vm,
+                                                virDomainHostdevDefPtr dev)
+-
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel &&
+-        driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0)
++        driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver,
++                                                                           vm, dev) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel &&
+-        driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0)
++        driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver,
++                                                                         vm, dev) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -196,18 +216,22 @@ qemuSecurityStackedRestoreSecurityHostdevLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
+-qemuSecurityStackedSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path)
++qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                       virDomainObjPtr vm,
++                                       const char *stdin_path)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainSetSecurityAllLabel &&
+-        driver->securitySecondaryDriver->domainSetSecurityAllLabel(vm, stdin_path) < 0)
++        driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver,
++                                                                   vm, stdin_path) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainSetSecurityAllLabel &&
+-        driver->securityPrimaryDriver->domainSetSecurityAllLabel(vm, stdin_path) < 0)
++        driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver,
++                                                                 vm, stdin_path) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -215,19 +239,22 @@ qemuSecurityStackedSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_pat
+ 
+ 
+ static int
+-qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm,
++qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                           virDomainObjPtr vm,
+                                            int migrated)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainRestoreSecurityAllLabel &&
+-        driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(vm, migrated) < 0)
++        driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver,
++                                                                       vm, migrated) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainRestoreSecurityAllLabel &&
+-        driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(vm, migrated) < 0)
++        driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver,
++                                                                     vm, migrated) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -235,19 +262,22 @@ qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
+-qemuSecurityStackedSetSavedStateLabel(virDomainObjPtr vm,
++qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                      virDomainObjPtr vm,
+                                       const char *savefile)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainSetSavedStateLabel &&
+-        driver->securitySecondaryDriver->domainSetSavedStateLabel(vm, savefile) < 0)
++        driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver,
++                                                                  vm, savefile) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainSetSavedStateLabel &&
+-        driver->securityPrimaryDriver->domainSetSavedStateLabel(vm, savefile) < 0)
++        driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver,
++                                                                vm, savefile) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -255,19 +285,22 @@ qemuSecurityStackedSetSavedStateLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
+-qemuSecurityStackedRestoreSavedStateLabel(virDomainObjPtr vm,
++qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                          virDomainObjPtr vm,
+                                           const char *savefile)
+ {
+     int rc = 0;
+ 
+     if (driver->securitySecondaryDriver &&
+         driver->securitySecondaryDriver->domainRestoreSavedStateLabel &&
+-        driver->securitySecondaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0)
++        driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver,
++                                                                      vm, savefile) < 0)
+         rc = -1;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainRestoreSavedStateLabel &&
+-        driver->securityPrimaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0)
++        driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver,
++                                                                    vm, savefile) < 0)
+         rc = -1;
+ 
+     return rc;
+@@ -296,14 +329,16 @@ qemuSecurityStackedSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+ }
+ 
+ static int
+-qemuSecurityStackedGetProcessLabel(virDomainObjPtr vm,
++qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                   virDomainObjPtr vm,
+                                    virSecurityLabelPtr seclabel)
+ {
+     int rc = 0;
+ 
+     if (driver->securityPrimaryDriver &&
+         driver->securityPrimaryDriver->domainGetSecurityProcessLabel &&
+-        driver->securityPrimaryDriver->domainGetSecurityProcessLabel(vm,
++        driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver,
++                                                                     vm,
+                                                                      seclabel) < 0)
+         rc = -1;
+ 
+diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
+index e883f69..cb5c739 100644
+--- a/src/security/security_apparmor.c
++++ b/src/security/security_apparmor.c
+@@ -148,7 +148,8 @@ profile_status_file(const char *str)
+  * load (add) a profile. Will create one if necessary
+  */
+ static int
+-load_profile(const char *profile, virDomainObjPtr vm,
++load_profile(virSecurityDriverPtr drv,
++             const char *profile, virDomainObjPtr vm,
+              const char *fn)
+ {
+     int rc = -1, status, ret;
+@@ -281,7 +282,8 @@ cleanup:
+  * NULL.
+  */
+ static int
+-reload_profile(virDomainObjPtr vm, const char *fn)
++reload_profile(virSecurityDriverPtr drv,
++               virDomainObjPtr vm, const char *fn)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+     int rc = -1;
+@@ -295,7 +297,7 @@ reload_profile(virDomainObjPtr vm, const char *fn)
+ 
+     /* Update the profile only if it is loaded */
+     if (profile_loaded(secdef->imagelabel) >= 0) {
+-        if (load_profile(secdef->imagelabel, vm, fn) < 0) {
++        if (load_profile(drv, secdef->imagelabel, vm, fn) < 0) {
+             virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+                                    _("cannot update AppArmor profile "
+                                      "\'%s\'"),
+@@ -357,7 +359,8 @@ AppArmorSecurityDriverOpen(virSecurityDriverPtr drv)
+  * called on shutdown.
+ */
+ static int
+-AppArmorGenSecurityLabel(virDomainObjPtr vm)
++AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                         virDomainObjPtr vm)
+ {
+     int rc = -1;
+     char *profile_name = NULL;
+@@ -411,14 +414,15 @@ AppArmorGenSecurityLabel(virDomainObjPtr vm)
+ }
+ 
+ static int
+-AppArmorSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path)
++AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
++                            virDomainObjPtr vm, const char *stdin_path)
+ {
+     if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
+         return 0;
+ 
+     /* if the profile is not already loaded, then load one */
+     if (profile_loaded(vm->def->seclabel.label) < 0) {
+-        if (load_profile(vm->def->seclabel.label, vm, stdin_path) < 0) {
++        if (load_profile(drv, vm->def->seclabel.label, vm, stdin_path) < 0) {
+             virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+                                    _("cannot generate AppArmor profile "
+                                    "\'%s\'"), vm->def->seclabel.label);
+@@ -433,7 +437,9 @@ AppArmorSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path)
+  * running.
+  */
+ static int
+-AppArmorGetSecurityProcessLabel(virDomainObjPtr vm, virSecurityLabelPtr sec)
++AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                virDomainObjPtr vm,
++                                virSecurityLabelPtr sec)
+ {
+     int rc = -1;
+     char *profile_name = NULL;
+@@ -465,7 +471,8 @@ AppArmorGetSecurityProcessLabel(virDomainObjPtr vm, virSecurityLabelPtr sec)
+  * more details. Currently called via qemudShutdownVMDaemon.
+  */
+ static int
+-AppArmorReleaseSecurityLabel(virDomainObjPtr vm)
++AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                             virDomainObjPtr vm)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+ 
+@@ -478,7 +485,8 @@ AppArmorReleaseSecurityLabel(virDomainObjPtr vm)
+ 
+ 
+ static int
+-AppArmorRestoreSecurityAllLabel(virDomainObjPtr vm,
++AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                virDomainObjPtr vm,
+                                 int migrated ATTRIBUTE_UNUSED)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+@@ -533,15 +541,17 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
+ 
+ /* Called when hotplugging */
+ static int
+-AppArmorRestoreSecurityImageLabel(virDomainObjPtr vm,
++AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv,
++                                  virDomainObjPtr vm,
+                                   virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
+ {
+-    return reload_profile(vm, NULL);
++    return reload_profile(drv, vm, NULL);
+ }
+ 
+ /* Called when hotplugging */
+ static int
+-AppArmorSetSecurityImageLabel(virDomainObjPtr vm, virDomainDiskDefPtr disk)
++AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
++                              virDomainObjPtr vm, virDomainDiskDefPtr disk)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+     int rc = -1;
+@@ -566,7 +576,7 @@ AppArmorSetSecurityImageLabel(virDomainObjPtr vm, virDomainDiskDefPtr disk)
+ 
+         /* update the profile only if it is loaded */
+         if (profile_loaded(secdef->imagelabel) >= 0) {
+-            if (load_profile(secdef->imagelabel, vm, disk->src) < 0) {
++            if (load_profile(drv, secdef->imagelabel, vm, disk->src) < 0) {
+                 virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+                                      _("cannot update AppArmor profile "
+                                      "\'%s\'"),
+@@ -600,14 +610,16 @@ AppArmorSecurityVerify(virDomainDefPtr def)
+ }
+ 
+ static int
+-AppArmorReserveSecurityLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED)
++AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                             virDomainObjPtr vm ATTRIBUTE_UNUSED)
+ {
+     /* NOOP. Nothing to reserve with AppArmor */
+     return 0;
+ }
+ 
+ static int
+-AppArmorSetSecurityHostdevLabel(virDomainObjPtr vm,
++AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                virDomainObjPtr vm,
+                                 virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
+ 
+ {
+@@ -621,7 +633,8 @@ AppArmorSetSecurityHostdevLabel(virDomainObjPtr vm,
+ }
+ 
+ static int
+-AppArmorRestoreSecurityHostdevLabel(virDomainObjPtr vm,
++AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                    virDomainObjPtr vm,
+                                     virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
+ 
+ {
+@@ -634,18 +647,20 @@ AppArmorRestoreSecurityHostdevLabel(virDomainObjPtr vm,
+ }
+ 
+ static int
+-AppArmorSetSavedStateLabel(virDomainObjPtr vm,
+-                          const char *savefile)
++AppArmorSetSavedStateLabel(virSecurityDriverPtr drv,
++                           virDomainObjPtr vm,
++                           const char *savefile)
+ {
+-    return reload_profile(vm, savefile);
++    return reload_profile(drv, vm, savefile);
+ }
+ 
+ 
+ static int
+-AppArmorRestoreSavedStateLabel(virDomainObjPtr vm,
++AppArmorRestoreSavedStateLabel(virSecurityDriverPtr drv,
++                               virDomainObjPtr vm,
+                                const char *savefile ATTRIBUTE_UNUSED)
+ {
+-    return reload_profile(vm, NULL);
++    return reload_profile(drv, vm, NULL);
+ }
+ 
+ virSecurityDriver virAppArmorSecurityDriver = {
+diff --git a/src/security/security_driver.h b/src/security/security_driver.h
+index 99260a4..61c9eb0 100644
+--- a/src/security/security_driver.h
++++ b/src/security/security_driver.h
+@@ -28,32 +28,48 @@ typedef enum {
+ 
+ typedef struct _virSecurityDriver virSecurityDriver;
+ typedef virSecurityDriver *virSecurityDriverPtr;
++
++typedef struct _virSecurityDriverState virSecurityDriverState;
++typedef virSecurityDriverState *virSecurityDriverStatePtr;
++
+ typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
+ typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv);
+-typedef int (*virSecurityDomainRestoreImageLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
++                                                   virDomainObjPtr vm,
+                                                    virDomainDiskDefPtr disk);
+ typedef int (*virSecurityDomainSetSocketLabel) (virSecurityDriverPtr drv,
+                                                 virDomainObjPtr vm);
+ typedef int (*virSecurityDomainClearSocketLabel)(virSecurityDriverPtr drv,
+                                                 virDomainObjPtr vm);
+-typedef int (*virSecurityDomainSetImageLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv,
++                                               virDomainObjPtr vm,
+                                                virDomainDiskDefPtr disk);
+-typedef int (*virSecurityDomainRestoreHostdevLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv,
++                                                     virDomainObjPtr vm,
+                                                      virDomainHostdevDefPtr dev);
+-typedef int (*virSecurityDomainSetHostdevLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv,
++                                                 virDomainObjPtr vm,
+                                                  virDomainHostdevDefPtr dev);
+-typedef int (*virSecurityDomainSetSavedStateLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv,
++                                                    virDomainObjPtr vm,
+                                                     const char *savefile);
+-typedef int (*virSecurityDomainRestoreSavedStateLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv,
++                                                        virDomainObjPtr vm,
+                                                         const char *savefile);
+-typedef int (*virSecurityDomainGenLabel) (virDomainObjPtr sec);
+-typedef int (*virSecurityDomainReserveLabel) (virDomainObjPtr sec);
+-typedef int (*virSecurityDomainReleaseLabel) (virDomainObjPtr sec);
+-typedef int (*virSecurityDomainSetAllLabel) (virDomainObjPtr sec,
++typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv,
++                                          virDomainObjPtr sec);
++typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv,
++                                              virDomainObjPtr sec);
++typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv,
++                                              virDomainObjPtr sec);
++typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv,
++                                             virDomainObjPtr sec,
+                                              const char *stdin_path);
+-typedef int (*virSecurityDomainRestoreAllLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv,
++                                                 virDomainObjPtr vm,
+                                                  int migrated);
+-typedef int (*virSecurityDomainGetProcessLabel) (virDomainObjPtr vm,
++typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv,
++                                                 virDomainObjPtr vm,
+                                                  virSecurityLabelPtr sec);
+ typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv,
+                                                  virDomainObjPtr vm);
+diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
+index d191118..cc3812b 100644
+--- a/src/security/security_selinux.c
++++ b/src/security/security_selinux.c
+@@ -156,7 +156,8 @@ SELinuxInitialize(void)
+ }
+ 
+ static int
+-SELinuxGenSecurityLabel(virDomainObjPtr vm)
++SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                        virDomainObjPtr vm)
+ {
+     int rc = -1;
+     char mcs[1024];
+@@ -220,7 +221,8 @@ done:
+ }
+ 
+ static int
+-SELinuxReserveSecurityLabel(virDomainObjPtr vm)
++SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                            virDomainObjPtr vm)
+ {
+     security_context_t pctx;
+     context_t ctx = NULL;
+@@ -275,7 +277,8 @@ SELinuxSecurityDriverOpen(virSecurityDriverPtr drv)
+ }
+ 
+ static int
+-SELinuxGetSecurityProcessLabel(virDomainObjPtr vm,
++SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                               virDomainObjPtr vm,
+                                virSecurityLabelPtr sec)
+ {
+     security_context_t ctx;
+@@ -387,7 +390,8 @@ err:
+ }
+ 
+ static int
+-SELinuxRestoreSecurityImageLabelInt(virDomainObjPtr vm,
++SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                    virDomainObjPtr vm,
+                                     virDomainDiskDefPtr disk,
+                                     int migrated)
+ {
+@@ -431,10 +435,11 @@ SELinuxRestoreSecurityImageLabelInt(virDomainObjPtr vm,
+ 
+ 
+ static int
+-SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm,
++SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv,
++                                 virDomainObjPtr vm,
+                                  virDomainDiskDefPtr disk)
+ {
+-    return SELinuxRestoreSecurityImageLabelInt(vm, disk, 0);
++    return SELinuxRestoreSecurityImageLabelInt(drv, vm, disk, 0);
+ }
+ 
+ 
+@@ -462,7 +467,8 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
+ }
+ 
+ static int
+-SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
++SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                             virDomainObjPtr vm,
+                              virDomainDiskDefPtr disk)
+ 
+ {
+@@ -500,7 +506,8 @@ SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ }
+ 
+ static int
+-SELinuxSetSecurityHostdevLabel(virDomainObjPtr vm,
++SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                               virDomainObjPtr vm,
+                                virDomainHostdevDefPtr dev)
+ 
+ {
+@@ -568,7 +575,8 @@ SELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ }
+ 
+ static int
+-SELinuxRestoreSecurityHostdevLabel(virDomainObjPtr vm,
++SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                                   virDomainObjPtr vm,
+                                    virDomainHostdevDefPtr dev)
+ 
+ {
+@@ -715,7 +723,8 @@ SELinuxRestoreSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm,
++SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                               virDomainObjPtr vm,
+                                int migrated ATTRIBUTE_UNUSED)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+@@ -728,11 +737,14 @@ SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm,
+         return 0;
+ 
+     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+-        if (SELinuxRestoreSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0)
++        if (SELinuxRestoreSecurityHostdevLabel(drv,
++                                               vm,
++                                               vm->def->hostdevs[i]) < 0)
+             rc = -1;
+     }
+     for (i = 0 ; i < vm->def->ndisks ; i++) {
+-        if (SELinuxRestoreSecurityImageLabelInt(vm,
++        if (SELinuxRestoreSecurityImageLabelInt(drv,
++                                                vm,
+                                                 vm->def->disks[i],
+                                                 migrated) < 0)
+             rc = -1;
+@@ -756,7 +768,8 @@ SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm,
+ }
+ 
+ static int
+-SELinuxReleaseSecurityLabel(virDomainObjPtr vm)
++SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                            virDomainObjPtr vm)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+ 
+@@ -779,7 +792,8 @@ SELinuxReleaseSecurityLabel(virDomainObjPtr vm)
+ 
+ 
+ static int
+-SELinuxSetSavedStateLabel(virDomainObjPtr vm,
++SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                          virDomainObjPtr vm,
+                           const char *savefile)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+@@ -792,7 +806,8 @@ SELinuxSetSavedStateLabel(virDomainObjPtr vm,
+ 
+ 
+ static int
+-SELinuxRestoreSavedStateLabel(virDomainObjPtr vm,
++SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++                              virDomainObjPtr vm,
+                               const char *savefile)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+@@ -963,7 +978,9 @@ SELinuxSetSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ 
+ 
+ static int
+-SELinuxSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path)
++SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
++                           virDomainObjPtr vm,
++                           const char *stdin_path)
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+     int i;
+@@ -978,11 +995,14 @@ SELinuxSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path)
+                      vm->def->disks[i]->src, vm->def->disks[i]->dst);
+             continue;
+         }
+-        if (SELinuxSetSecurityImageLabel(vm, vm->def->disks[i]) < 0)
++        if (SELinuxSetSecurityImageLabel(drv,
++                                         vm, vm->def->disks[i]) < 0)
+             return -1;
+     }
+     for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+-        if (SELinuxSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0)
++        if (SELinuxSetSecurityHostdevLabel(drv,
++                                           vm,
++                                           vm->def->hostdevs[i]) < 0)
+             return -1;
+     }
+ 
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-08-disable-disk-probing.patch b/libvirt-0.8.2-08-disable-disk-probing.patch
new file mode 100644
index 0000000..5952ad5
--- /dev/null
+++ b/libvirt-0.8.2-08-disable-disk-probing.patch
@@ -0,0 +1,468 @@
+From dac2b936e77f6c76c11f162e4b175492e4803acb Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Tue, 15 Jun 2010 17:58:58 +0100
+Subject: [PATCH 08/11] Disable all disk probing in QEMU driver & add config option to re-enable
+
+Disk format probing is now disabled by default. A new config
+option in /etc/qemu/qemu.conf will re-enable it for existing
+deployments where this causes trouble
+---
+ src/qemu/libvirtd_qemu.aug       |    1 +
+ src/qemu/qemu.conf               |   12 ++++++++++++
+ src/qemu/qemu_conf.c             |    4 ++++
+ src/qemu/qemu_conf.h             |    1 +
+ src/qemu/qemu_driver.c           |   36 +++++++++++++++++++++++-------------
+ src/qemu/qemu_security_dac.c     |    2 +-
+ src/qemu/test_libvirtd_qemu.aug  |    4 ++++
+ src/security/security_apparmor.c |   12 ++++++++----
+ src/security/security_driver.c   |   16 ++++++++++++++--
+ src/security/security_driver.h   |   10 ++++++++--
+ src/security/security_selinux.c  |    9 ++++++---
+ src/security/virt-aa-helper.c    |   10 +++++++++-
+ tests/seclabeltest.c             |    2 +-
+ 13 files changed, 92 insertions(+), 27 deletions(-)
+
+diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
+index 7c9f271..47d0525 100644
+--- a/src/qemu/libvirtd_qemu.aug
++++ b/src/qemu/libvirtd_qemu.aug
+@@ -40,6 +40,7 @@ module Libvirtd_qemu =
+                  | bool_entry "relaxed_acs_check"
+                  | bool_entry "vnc_allow_host_audio"
+                  | bool_entry "clear_emulator_capabilities"
++                 | bool_entry "allow_disk_format_probing"
+ 
+    (* Each enty in the config is one of the following three ... *)
+    let entry = vnc_entry
+diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
+index 93934f3..dc8eb83 100644
+--- a/src/qemu/qemu.conf
++++ b/src/qemu/qemu.conf
+@@ -187,3 +187,15 @@
+ # exploit the privileges and possibly do damage to the host.
+ #
+ # clear_emulator_capabilities = 1
++
++
++
++# If allow_disk_format_probing is enabled, libvirt will probe disk
++# images to attempt to identify their format, when not otherwise
++# specified in the XML. This is disabled by default.
++#
++# WARNING: Enabling probing is a security hole in almost all
++# deployments. It is strongly recommended that users update their
++# guest XML <disk> elements to include  <driver type='XXXX'/>
++# elements instead of enabling this option.
++# allow_disk_format_probing = 1
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 988220b..3ba48bf 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -365,6 +365,10 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
+     CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
+     if (p) driver->clearEmulatorCapabilities = p->l;
+ 
++    p = virConfGetValue (conf, "allow_disk_format_probing");
++    CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
++    if (p) driver->allowDiskFormatProbing = p->l;
++
+     virConfFree (conf);
+     return 0;
+ }
+diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
+index ab5f158..30e9f20 100644
+--- a/src/qemu/qemu_conf.h
++++ b/src/qemu/qemu_conf.h
+@@ -141,6 +141,7 @@ struct qemud_driver {
+     unsigned int relaxedACS : 1;
+     unsigned int vncAllowHostAudio : 1;
+     unsigned int clearEmulatorCapabilities : 1;
++    unsigned int allowDiskFormatProbing : 1;
+ 
+     virCapsPtr caps;
+ 
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 616547c..3c479c5 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -1322,7 +1322,8 @@ qemudSecurityInit(struct qemud_driver *qemud_drv)
+     qemuSecurityDACSetDriver(qemud_drv);
+ 
+     ret = virSecurityDriverStartup(&security_drv,
+-                                   qemud_drv->securityDriverName);
++                                   qemud_drv->securityDriverName,
++                                   qemud_drv->allowDiskFormatProbing);
+     if (ret == -1) {
+         VIR_ERROR0(_("Failed to start security driver"));
+         return -1;
+@@ -3070,11 +3071,12 @@ static int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ }
+ 
+ 
+-static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
++static int qemuSetupDiskCgroup(struct qemud_driver *driver,
++                               virCgroupPtr cgroup,
+                                virDomainDiskDefPtr disk)
+ {
+     return virDomainDiskDefForeachPath(disk,
+-                                       true,
++                                       driver->allowDiskFormatProbing,
+                                        true,
+                                        qemuSetupDiskPathAllow,
+                                        cgroup);
+@@ -3109,11 +3111,12 @@ static int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ }
+ 
+ 
+-static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
++static int qemuTeardownDiskCgroup(struct qemud_driver *driver,
++                                  virCgroupPtr cgroup,
+                                   virDomainDiskDefPtr disk)
+ {
+     return virDomainDiskDefForeachPath(disk,
+-                                       true,
++                                       driver->allowDiskFormatProbing,
+                                        true,
+                                        qemuTeardownDiskPathDeny,
+                                        cgroup);
+@@ -3180,7 +3183,7 @@ static int qemuSetupCgroup(struct qemud_driver *driver,
+         }
+ 
+         for (i = 0; i < vm->def->ndisks ; i++) {
+-            if (qemuSetupDiskCgroup(cgroup, vm->def->disks[i]) < 0)
++            if (qemuSetupDiskCgroup(driver, cgroup, vm->def->disks[i]) < 0)
+                 goto cleanup;
+         }
+ 
+@@ -8033,7 +8036,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
+                                 vm->def->name);
+                 goto endjob;
+             }
+-            if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
++            if (qemuSetupDiskCgroup(driver, cgroup, dev->data.disk) < 0)
+                 goto endjob;
+         }
+ 
+@@ -8078,7 +8081,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
+             /* Fallthrough */
+         }
+         if (ret != 0 && cgroup) {
+-            if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
++            if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
+                 VIR_WARN("Failed to teardown cgroup for disk path %s",
+                          NULLSTR(dev->data.disk->src));
+         }
+@@ -8278,7 +8281,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
+                                 vm->def->name);
+                 goto endjob;
+             }
+-            if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
++            if (qemuSetupDiskCgroup(driver, cgroup, dev->data.disk) < 0)
+                 goto endjob;
+         }
+ 
+@@ -8301,7 +8304,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
+         }
+ 
+         if (ret != 0 && cgroup) {
+-            if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
++            if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
+                 VIR_WARN("Failed to teardown cgroup for disk path %s",
+                          NULLSTR(dev->data.disk->src));
+         }
+@@ -8429,7 +8432,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
+         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
+ 
+     if (cgroup != NULL) {
+-        if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
++        if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
+             VIR_WARN("Failed to teardown cgroup for disk path %s",
+                      NULLSTR(dev->data.disk->src));
+     }
+@@ -8493,7 +8496,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
+         VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
+ 
+     if (cgroup != NULL) {
+-        if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
++        if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
+             VIR_WARN("Failed to teardown cgroup for disk path %s",
+                      NULLSTR(dev->data.disk->src));
+     }
+@@ -9672,8 +9675,15 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
+             goto cleanup;
+         }
+     } else {
+-        if ((format = virStorageFileProbeFormat(disk->src)) < 0)
++        if (driver->allowDiskFormatProbing) {
++            if ((format = virStorageFileProbeFormat(disk->src)) < 0)
++                goto cleanup;
++        } else {
++            qemuReportError(VIR_ERR_INTERNAL_ERROR,
++                            _("no disk format for %s and probing is disabled"),
++                            disk->src);
+             goto cleanup;
++        }
+     }
+ 
+     if (virStorageFileGetMetadataFromFD(path, fd,
+diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
+index 0bbcf69..55dc0c6 100644
+--- a/src/qemu/qemu_security_dac.c
++++ b/src/qemu/qemu_security_dac.c
+@@ -117,7 +117,7 @@ qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+         return 0;
+ 
+     return virDomainDiskDefForeachPath(disk,
+-                                       true,
++                                       driver->allowDiskFormatProbing,
+                                        false,
+                                        qemuSecurityDACSetSecurityFileLabel,
+                                        NULL);
+diff --git a/src/qemu/test_libvirtd_qemu.aug b/src/qemu/test_libvirtd_qemu.aug
+index 3326cc5..f0c4a0d 100644
+--- a/src/qemu/test_libvirtd_qemu.aug
++++ b/src/qemu/test_libvirtd_qemu.aug
+@@ -101,6 +101,8 @@ relaxed_acs_check = 1
+ vnc_allow_host_audio = 1
+ 
+ clear_emulator_capabilities = 0
++
++allow_disk_format_probing = 1
+ "
+ 
+    test Libvirtd_qemu.lns get conf =
+@@ -212,3 +214,5 @@ clear_emulator_capabilities = 0
+ { "vnc_allow_host_audio" = "1" }
+ { "#empty" }
+ { "clear_emulator_capabilities" = "0" }
++{ "#empty" }
++{ "allow_disk_format_probing" = "1" }
+diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
+index cb5c739..c5f9829 100644
+--- a/src/security/security_apparmor.c
++++ b/src/security/security_apparmor.c
+@@ -157,6 +157,8 @@ load_profile(virSecurityDriverPtr drv,
+     char *xml = NULL;
+     int pipefd[2];
+     pid_t child;
++    const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
++        ? "1" : "0";
+ 
+     if (pipe(pipefd) < -1) {
+         virReportSystemError(errno, "%s", _("unable to create pipe"));
+@@ -172,19 +174,19 @@ load_profile(virSecurityDriverPtr drv,
+ 
+     if (create) {
+         const char *const argv[] = {
+-            VIRT_AA_HELPER, "-c", "-u", profile, NULL
++            VIRT_AA_HELPER, "-p", probe, "-c", "-u", profile, NULL
+         };
+         ret = virExec(argv, NULL, NULL, &child,
+                       pipefd[0], NULL, NULL, VIR_EXEC_NONE);
+     } else if (fn) {
+         const char *const argv[] = {
+-            VIRT_AA_HELPER, "-r", "-u", profile, "-f", fn, NULL
++            VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, "-f", fn, NULL
+         };
+         ret = virExec(argv, NULL, NULL, &child,
+                       pipefd[0], NULL, NULL, VIR_EXEC_NONE);
+     } else {
+         const char *const argv[] = {
+-            VIRT_AA_HELPER, "-r", "-u", profile, NULL
++            VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, NULL
+         };
+         ret = virExec(argv, NULL, NULL, &child,
+                       pipefd[0], NULL, NULL, VIR_EXEC_NONE);
+@@ -347,9 +349,11 @@ AppArmorSecurityDriverProbe(void)
+  * currently not used.
+  */
+ static int
+-AppArmorSecurityDriverOpen(virSecurityDriverPtr drv)
++AppArmorSecurityDriverOpen(virSecurityDriverPtr drv,
++                           bool allowDiskFormatProbing)
+ {
+     virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI);
++    virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
+     return 0;
+ }
+ 
+diff --git a/src/security/security_driver.c b/src/security/security_driver.c
+index aac9f78..9e32fa4 100644
+--- a/src/security/security_driver.c
++++ b/src/security/security_driver.c
+@@ -56,7 +56,8 @@ virSecurityDriverVerify(virDomainDefPtr def)
+ 
+ int
+ virSecurityDriverStartup(virSecurityDriverPtr *drv,
+-                         const char *name)
++                         const char *name,
++                         bool allowDiskFormatProbing)
+ {
+     unsigned int i;
+ 
+@@ -72,7 +73,7 @@ virSecurityDriverStartup(virSecurityDriverPtr *drv,
+         switch (tmp->probe()) {
+         case SECURITY_DRIVER_ENABLE:
+             virSecurityDriverInit(tmp);
+-            if (tmp->open(tmp) == -1) {
++            if (tmp->open(tmp, allowDiskFormatProbing) == -1) {
+                 return -1;
+             } else {
+                 *drv = tmp;
+@@ -125,3 +126,14 @@ virSecurityDriverGetModel(virSecurityDriverPtr drv)
+ {
+     return drv->name;
+ }
++
++void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
++                                                bool allowDiskFormatProbing)
++{
++    drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
++}
++
++bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
++{
++    return drv->_private.allowDiskFormatProbing;
++}
+diff --git a/src/security/security_driver.h b/src/security/security_driver.h
+index 61c9eb0..d768f32 100644
+--- a/src/security/security_driver.h
++++ b/src/security/security_driver.h
+@@ -33,7 +33,8 @@ typedef struct _virSecurityDriverState virSecurityDriverState;
+ typedef virSecurityDriverState *virSecurityDriverStatePtr;
+ 
+ typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
+-typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv);
++typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv,
++                                      bool allowDiskFormatProbing);
+ typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
+                                                    virDomainObjPtr vm,
+                                                    virDomainDiskDefPtr disk);
+@@ -102,12 +103,14 @@ struct _virSecurityDriver {
+      */
+     struct {
+         char doi[VIR_SECURITY_DOI_BUFLEN];
++        bool allowDiskFormatProbing;
+     } _private;
+ };
+ 
+ /* Global methods */
+ int virSecurityDriverStartup(virSecurityDriverPtr *drv,
+-                             const char *name);
++                             const char *name,
++                             bool allowDiskFormatProbing);
+ 
+ int
+ virSecurityDriverVerify(virDomainDefPtr def);
+@@ -120,7 +123,10 @@ virSecurityDriverVerify(virDomainDefPtr def);
+ void virSecurityDriverInit(virSecurityDriverPtr drv);
+ int virSecurityDriverSetDOI(virSecurityDriverPtr drv,
+                             const char *doi);
++void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
++                                                bool allowDiskFormatProbing);
+ const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
+ const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
++bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
+ 
+ #endif /* __VIR_SECURITY_H__ */
+diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
+index cc3812b..a9dd836 100644
+--- a/src/security/security_selinux.c
++++ b/src/security/security_selinux.c
+@@ -266,13 +266,15 @@ SELinuxSecurityDriverProbe(void)
+ }
+ 
+ static int
+-SELinuxSecurityDriverOpen(virSecurityDriverPtr drv)
++SELinuxSecurityDriverOpen(virSecurityDriverPtr drv,
++                          bool allowDiskFormatProbing)
+ {
+     /*
+      * Where will the DOI come from?  SELinux configuration, or qemu
+      * configuration? For the moment, we'll just set it to "0".
+      */
+     virSecurityDriverSetDOI(drv, SECURITY_SELINUX_VOID_DOI);
++    virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
+     return SELinuxInitialize();
+ }
+ 
+@@ -467,18 +469,19 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
+ }
+ 
+ static int
+-SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
++SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv,
+                              virDomainObjPtr vm,
+                              virDomainDiskDefPtr disk)
+ 
+ {
+     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
++    bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
+ 
+     if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
+         return 0;
+ 
+     return virDomainDiskDefForeachPath(disk,
+-                                       true,
++                                       allowDiskFormatProbing,
+                                        false,
+                                        SELinuxSetSecurityFileLabel,
+                                        secdef);
+diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
+index 9ed0cd3..521545d 100644
+--- a/src/security/virt-aa-helper.c
++++ b/src/security/virt-aa-helper.c
+@@ -40,6 +40,7 @@
+ static char *progname;
+ 
+ typedef struct {
++    bool allowDiskFormatProbing;
+     char uuid[PROFILE_NAME_SIZE];       /* UUID of vm */
+     bool dryrun;                /* dry run */
+     char cmd;                   /* 'c'   create
+@@ -844,7 +845,7 @@ get_files(vahControl * ctl)
+ 
+     for (i = 0; i < ctl->def->ndisks; i++) {
+         int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
+-                                              true,
++                                              ctl->allowDiskFormatProbing,
+                                               false,
+                                               add_file_path,
+                                               &buf);
+@@ -943,6 +944,7 @@ vahParseArgv(vahControl * ctl, int argc, char **argv)
+ {
+     int arg, idx = 0;
+     struct option opt[] = {
++        {"probing", 1, 0, 'p' },
+         {"add", 0, 0, 'a'},
+         {"create", 0, 0, 'c'},
+         {"dryrun", 0, 0, 'd'},
+@@ -991,6 +993,12 @@ vahParseArgv(vahControl * ctl, int argc, char **argv)
+                     PROFILE_NAME_SIZE) == NULL)
+                     vah_error(ctl, 1, "error copying UUID");
+                 break;
++            case 'p':
++                if (STREQ(optarg, "1"))
++                    ctl->allowDiskFormatProbing = true;
++                else
++                    ctl->allowDiskFormatProbing = false;
++                break;
+             default:
+                 vah_error(ctl, 1, "unsupported option");
+                 break;
+diff --git a/tests/seclabeltest.c b/tests/seclabeltest.c
+index 26d1f86..ef3f026 100644
+--- a/tests/seclabeltest.c
++++ b/tests/seclabeltest.c
+@@ -15,7 +15,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
+     const char *doi, *model;
+     virSecurityDriverPtr security_drv;
+ 
+-    ret = virSecurityDriverStartup (&security_drv, "selinux");
++    ret = virSecurityDriverStartup (&security_drv, "selinux", false);
+     if (ret == -1)
+     {
+         fprintf (stderr, "Failed to start security driver");
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-09-set-default-driver.patch b/libvirt-0.8.2-09-set-default-driver.patch
new file mode 100644
index 0000000..93c4ca5
--- /dev/null
+++ b/libvirt-0.8.2-09-set-default-driver.patch
@@ -0,0 +1,94 @@
+From 3534cd47a57ee9cf7041472511444784f14d6939 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Mon, 14 Jun 2010 16:08:55 +0100
+Subject: [PATCH 09/11] Add ability to set a default driver name/type when parsing disks
+
+Record a default driver name/type in capabilities struct. Use this
+when parsing disks if value is not set in XML config.
+
+* src/conf/capabilities.h: Record default driver name/type for disks
+* src/conf/domain_conf.c: Fallback to default driver name/type
+  when parsing disks
+* src/qemu/qemu_driver.c: Set default driver name/type to raw
+---
+ src/conf/capabilities.h |    2 ++
+ src/conf/domain_conf.c  |   16 +++++++++++++++-
+ src/qemu/qemu_driver.c  |    8 ++++++++
+ 3 files changed, 25 insertions(+), 1 deletions(-)
+
+diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
+index 9290c82..f676eb8 100644
+--- a/src/conf/capabilities.h
++++ b/src/conf/capabilities.h
+@@ -123,6 +123,8 @@ struct _virCaps {
+     virCapsGuestPtr *guests;
+     unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN];
+     unsigned int emulatorRequired : 1;
++    const char *defaultDiskDriverName;
++    const char *defaultDiskDriverType;
+     void *(*privateDataAllocFunc)(void);
+     void (*privateDataFreeFunc)(void *);
+     int (*privateDataXMLFormat)(virBufferPtr, void *);
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index b20ca97..f3b8cfa 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -1639,6 +1639,16 @@ virDomainDiskDefParseXML(virCapsPtr caps,
+     def->serial = serial;
+     serial = NULL;
+ 
++    if (!def->driverType &&
++        caps->defaultDiskDriverType &&
++        !(def->driverType = strdup(caps->defaultDiskDriverType)))
++        goto no_memory;
++
++    if (!def->driverName &&
++        caps->defaultDiskDriverName &&
++        !(def->driverName = strdup(caps->defaultDiskDriverName)))
++        goto no_memory;
++
+     if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
+         && virDomainDiskDefAssignAddress(caps, def) < 0)
+         goto error;
+@@ -1659,6 +1669,9 @@ cleanup:
+ 
+     return def;
+ 
++no_memory:
++    virReportOOMError();
++
+  error:
+     virDomainDiskDefFree(def);
+     def = NULL;
+@@ -4275,7 +4288,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
+     if (n && VIR_ALLOC_N(def->disks, n) < 0)
+         goto no_memory;
+     for (i = 0 ; i < n ; i++) {
+-        virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, nodes[i],
++        virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps,
++                                                            nodes[i],
+                                                             flags);
+         if (!disk)
+             goto error;
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 3c479c5..14b790e 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -1357,6 +1357,14 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
+         return NULL;
+     }
+ 
++    if (driver->allowDiskFormatProbing) {
++        caps->defaultDiskDriverName = NULL;
++        caps->defaultDiskDriverType = NULL;
++    } else {
++        caps->defaultDiskDriverName = "qemu";
++        caps->defaultDiskDriverType = "raw";
++    }
++
+     /* Domain XML parser hooks */
+     caps->privateDataAllocFunc = qemuDomainObjPrivateAlloc;
+     caps->privateDataFreeFunc = qemuDomainObjPrivateFree;
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-10-qemu-img-format-handling.patch b/libvirt-0.8.2-10-qemu-img-format-handling.patch
new file mode 100644
index 0000000..813bf16
--- /dev/null
+++ b/libvirt-0.8.2-10-qemu-img-format-handling.patch
@@ -0,0 +1,291 @@
+From 2ba8625d6d148fa489586efabdfaf2ef20903762 Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Wed, 16 Jun 2010 14:14:05 +0100
+Subject: [PATCH 10/11] Rewrite qemu-img backing store format handling
+
+When creating qcow2 files with a backing store, it is important
+to set an explicit format to prevent QEMU probing. The storage
+backend was only doing this if it found a 'kvm-img' binary. This
+is wrong because plenty of kvm-img binaries don't support an
+explicit format, and plenty of 'qemu-img' binaries do support
+a format. The result was that most qcow2 files were not getting
+a backing store format.
+
+This patch runs 'qemu-img -h' to check for the two support
+argument formats
+
+  '-o backing_format=raw'
+  '-F raw'
+
+and use whichever option it finds
+
+* src/storage/storage_backend.c: Query binary to determine
+  how to set the backing store format
+---
+ src/storage/storage_backend.c |  214 +++++++++++++++++++++++++++++------------
+ 1 files changed, 152 insertions(+), 62 deletions(-)
+
+diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
+index aba8937..c185693 100644
+--- a/src/storage/storage_backend.c
++++ b/src/storage/storage_backend.c
+@@ -561,6 +561,69 @@ static int virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
+     return 0;
+ }
+ 
++enum {
++    QEMU_IMG_BACKING_FORMAT_NONE = 0,
++    QEMU_IMG_BACKING_FORMAT_FLAG,
++    QEMU_IMG_BACKING_FORMAT_OPTIONS,
++};
++
++static int virStorageBackendQEMUImgBackingFormat(const char *qemuimg)
++{
++    const char *const qemuarg[] = { qemuimg, "-h", NULL };
++    const char *const qemuenv[] = { "LC_ALL=C", NULL };
++    pid_t child = 0;
++    int status;
++    int newstdout = -1;
++    char *help = NULL;
++    enum { MAX_HELP_OUTPUT_SIZE = 1024*8 };
++    int len;
++    char *start;
++    char *end;
++    char *tmp;
++    int ret = -1;
++
++    if (virExec(qemuarg, qemuenv, NULL,
++                &child, -1, &newstdout, NULL, VIR_EXEC_CLEAR_CAPS) < 0)
++        goto cleanup;
++
++    if ((len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help)) < 0) {
++        virReportSystemError(errno,
++                             _("Unable to read '%s -h' output"),
++                             qemuimg);
++        goto cleanup;
++    }
++
++    start = strstr(help, " create ");
++    end = strstr(start, "\n");
++    if ((tmp = strstr(start, "-F fmt")) && tmp < end)
++        ret = QEMU_IMG_BACKING_FORMAT_FLAG;
++    else if ((tmp = strstr(start, "[-o options]")) && tmp < end)
++        ret = QEMU_IMG_BACKING_FORMAT_OPTIONS;
++    else
++        ret = QEMU_IMG_BACKING_FORMAT_NONE;
++
++cleanup:
++    VIR_FREE(help);
++    close(newstdout);
++rewait:
++    if (child) {
++        if (waitpid(child, &status, 0) != child) {
++            if (errno == EINTR)
++                goto rewait;
++
++            VIR_ERROR(_("Unexpected exit status from qemu %d pid %lu"),
++                      WEXITSTATUS(status), (unsigned long)child);
++        }
++        if (WEXITSTATUS(status) != 0) {
++            VIR_WARN("Unexpected exit status '%d', qemu probably failed",
++                     WEXITSTATUS(status));
++        }
++    }
++
++    return ret;
++}
++
++
+ static int
+ virStorageBackendCreateQemuImg(virConnectPtr conn,
+                                virStoragePoolObjPtr pool,
+@@ -568,10 +631,9 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
+                                virStorageVolDefPtr inputvol,
+                                unsigned int flags ATTRIBUTE_UNUSED)
+ {
+-    int ret;
++    int ret = -1;
+     char size[100];
+     char *create_tool;
+-    short use_kvmimg;
+ 
+     const char *type = virStorageFileFormatTypeToString(vol->target.format);
+     const char *backingType = vol->backingStore.path ?
+@@ -582,41 +644,10 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
+     const char *inputPath = inputvol ? inputvol->target.path : NULL;
+     /* Treat input block devices as 'raw' format */
+     const char *inputType = inputPath ?
+-                            virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_FILE_RAW : inputvol->target.format) :
+-                            NULL;
+-
+-    const char **imgargv;
+-    /* The extra NULL field is for indicating encryption (-e). */
+-    const char *imgargvnormal[] = {
+-        NULL, "create",
+-        "-f", type,
+-        vol->target.path,
+-        size,
+-        NULL,
+-        NULL
+-    };
+-    /* Extra NULL fields are for including "backingType" when using
+-     * kvm-img (-F backingType), and for indicating encryption (-e).
+-     */
+-    const char *imgargvbacking[] = {
+-        NULL, "create",
+-        "-f", type,
+-        "-b", vol->backingStore.path,
+-        vol->target.path,
+-        size,
+-        NULL,
+-        NULL,
+-        NULL,
+-        NULL
+-    };
+-    const char *convargv[] = {
+-        NULL, "convert",
+-        "-f", inputType,
+-        "-O", type,
+-        inputPath,
+-        vol->target.path,
+-        NULL,
+-    };
++        virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ?
++                                         VIR_STORAGE_FILE_RAW :
++                                         inputvol->target.format) :
++        NULL;
+ 
+     if (type == NULL) {
+         virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+@@ -690,44 +721,103 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
+         }
+     }
+ 
+-    if ((create_tool = virFindFileInPath("kvm-img")) != NULL)
+-        use_kvmimg = 1;
+-    else if ((create_tool = virFindFileInPath("qemu-img")) != NULL)
+-        use_kvmimg = 0;
+-    else {
++    /* Size in KB */
++    snprintf(size, sizeof(size), "%lluK", vol->capacity/1024);
++
++    /* KVM is usually ahead of qemu on features, so try that first */
++    create_tool = virFindFileInPath("kvm-img");
++    if (!create_tool)
++        create_tool = virFindFileInPath("qemu-img");
++
++    if (!create_tool) {
+         virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+                               "%s", _("unable to find kvm-img or qemu-img"));
+         return -1;
+     }
+ 
+     if (inputvol) {
+-        convargv[0] = create_tool;
+-        imgargv = convargv;
++        const char *imgargv[] = {
++            create_tool,
++            "convert",
++            "-f", inputType,
++            "-O", type,
++            inputPath,
++            vol->target.path,
++            NULL,
++        };
++
++        ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
+     } else if (vol->backingStore.path) {
+-        imgargvbacking[0] = create_tool;
+-        if (use_kvmimg) {
+-            imgargvbacking[6] = "-F";
+-            imgargvbacking[7] = backingType;
+-            imgargvbacking[8] = vol->target.path;
+-            imgargvbacking[9] = size;
++        const char *imgargv[] = {
++            create_tool,
++            "create",
++            "-f", type,
++            "-b", vol->backingStore.path,
++            NULL,
++            NULL,
++            NULL,
++            NULL,
++            NULL,
++            NULL
++        };
++        int imgformat = virStorageBackendQEMUImgBackingFormat(create_tool);
++        char *optflag = NULL;
++        if (imgformat < 0)
++            goto cleanup;
++
++        switch (imgformat) {
++        case QEMU_IMG_BACKING_FORMAT_FLAG:
++            imgargv[6] = "-F";
++            imgargv[7] = backingType;
++            imgargv[8] = vol->target.path;
++            imgargv[9] = size;
++            if (vol->target.encryption != NULL)
++                imgargv[10] = "-e";
++            break;
++
++        case QEMU_IMG_BACKING_FORMAT_OPTIONS:
++            if (virAsprintf(&optflag, "backing_fmt=%s", backingType) < 0) {
++                virReportOOMError();
++                goto cleanup;
++            }
++            imgargv[6] = "-o";
++            imgargv[7] = optflag;
++            imgargv[8] = vol->target.path;
++            imgargv[9] = size;
+             if (vol->target.encryption != NULL)
+-                imgargvbacking[10] = "-e";
+-        } else if (vol->target.encryption != NULL)
+-            imgargvbacking[8] = "-e";
+-        imgargv = imgargvbacking;
++                imgargv[10] = "-e";
++            break;
++
++        default:
++            VIR_INFO("Unable to set backing store format for %s with %s",
++                     vol->target.path, create_tool);
++            imgargv[6] = vol->target.path;
++            imgargv[7] = size;
++            if (vol->target.encryption != NULL)
++                imgargv[8] = "-e";
++        }
++
++        ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
++        VIR_FREE(optflag);
+     } else {
+-        imgargvnormal[0] = create_tool;
+-        imgargv = imgargvnormal;
++        /* The extra NULL field is for indicating encryption (-e). */
++        const char *imgargv[] = {
++            create_tool,
++            "create",
++            "-f", type,
++            vol->target.path,
++            size,
++            NULL,
++            NULL
++        };
+         if (vol->target.encryption != NULL)
+             imgargv[6] = "-e";
+-    }
+ 
++        ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
++    }
+ 
+-    /* Size in KB */
+-    snprintf(size, sizeof(size), "%lluK", vol->capacity/1024);
+-
+-    ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
+-    VIR_FREE(imgargv[0]);
++    cleanup:
++    VIR_FREE(create_tool);
+ 
+     return ret;
+ }
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-11-storage-vol-backing.patch b/libvirt-0.8.2-11-storage-vol-backing.patch
new file mode 100644
index 0000000..7ffcc57
--- /dev/null
+++ b/libvirt-0.8.2-11-storage-vol-backing.patch
@@ -0,0 +1,165 @@
+From d33f44c2e74de28c89b64cdc2c0a6564662e075c Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Fri, 9 Jul 2010 11:28:40 +0100
+Subject: [PATCH 11/11] Use the extract backing store format in storage volume lookup
+
+The storage volume lookup code was probing for the backing store
+format, instead of using the format extracted from the file
+itself. This meant it could report in accurate information. If
+a format is included in the file, then use that in preference,
+with probing as a fallback.
+
+* src/storage/storage_backend_fs.c: Use extracted backing store
+  format
+---
+ src/storage/storage_backend_fs.c |   80 +++++++++++++++++---------------------
+ 1 files changed, 36 insertions(+), 44 deletions(-)
+
+diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
+index d3ac0fe..ffb0071 100644
+--- a/src/storage/storage_backend_fs.c
++++ b/src/storage/storage_backend_fs.c
+@@ -51,6 +51,7 @@
+ static int
+ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
+                              char **backingStore,
++                             int *backingStoreFormat,
+                              unsigned long long *allocation,
+                              unsigned long long *capacity,
+                              virStorageEncryptionPtr *encryption)
+@@ -58,6 +59,10 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
+     int fd, ret;
+     virStorageFileMetadata meta;
+ 
++    if (backingStore)
++        *backingStore = NULL;
++    if (backingStoreFormat)
++        *backingStoreFormat = VIR_STORAGE_FILE_AUTO;
+     if (encryption)
+         *encryption = NULL;
+ 
+@@ -89,22 +94,30 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
+ 
+     close(fd);
+ 
+-    if (backingStore) {
+-        *backingStore = meta.backingStore;
+-        meta.backingStore = NULL;
++    if (meta.backingStore) {
++        if (backingStore) {
++            *backingStore = meta.backingStore;
++            meta.backingStore = NULL;
++            if (meta.backingStoreFormat == VIR_STORAGE_FILE_AUTO) {
++                if ((*backingStoreFormat = virStorageFileProbeFormat(*backingStore)) < 0) {
++                    close(fd);
++                    goto cleanup;
++                }
++            } else {
++                *backingStoreFormat = meta.backingStoreFormat;
++            }
++        } else {
++            VIR_FREE(meta.backingStore);
++        }
+     }
+ 
+-    VIR_FREE(meta.backingStore);
+-
+     if (capacity && meta.capacity)
+         *capacity = meta.capacity;
+ 
+     if (encryption != NULL && meta.encrypted) {
+         if (VIR_ALLOC(*encryption) < 0) {
+             virReportOOMError();
+-            if (backingStore)
+-                VIR_FREE(*backingStore);
+-            return -1;
++            goto cleanup;
+         }
+ 
+         switch (target->format) {
+@@ -124,6 +137,11 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
+     }
+ 
+     return 0;
++
++cleanup:
++    if (backingStore)
++        VIR_FREE(*backingStore);
++    return -1;
+ }
+ 
+ #if WITH_STORAGE_FS
+@@ -585,6 +603,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
+     while ((ent = readdir(dir)) != NULL) {
+         int ret;
+         char *backingStore;
++        int backingStoreFormat;
+ 
+         if (VIR_ALLOC(vol) < 0)
+             goto no_memory;
+@@ -604,6 +623,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
+ 
+         if ((ret = virStorageBackendProbeTarget(&vol->target,
+                                                 &backingStore,
++                                                &backingStoreFormat,
+                                                 &vol->allocation,
+                                                 &vol->capacity,
+                                                 &vol->target.encryption)) < 0) {
+@@ -619,46 +639,18 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
+         }
+ 
+         if (backingStore != NULL) {
+-            if (vol->target.format == VIR_STORAGE_FILE_QCOW2 &&
+-                STRPREFIX("fmt:", backingStore)) {
+-                char *fmtstr = backingStore + 4;
+-                char *path = strchr(fmtstr, ':');
+-                if (!path) {
+-                    VIR_FREE(backingStore);
+-                } else {
+-                    *path = '\0';
+-                    if ((vol->backingStore.format =
+-                         virStorageFileFormatTypeFromString(fmtstr)) < 0) {
+-                        VIR_FREE(backingStore);
+-                    } else {
+-                        memmove(backingStore, path, strlen(path) + 1);
+-                        vol->backingStore.path = backingStore;
+-
+-                        if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
+-                                                                 NULL,
+-                                                                 NULL) < 0)
+-                            VIR_FREE(vol->backingStore);
+-                    }
+-                }
+-            } else {
+-                vol->backingStore.path = backingStore;
+-
+-                if ((ret = virStorageBackendProbeTarget(&vol->backingStore,
+-                                                        NULL, NULL, NULL,
+-                                                        NULL)) < 0) {
+-                    if (ret == -1)
+-                        goto cleanup;
+-                    else {
+-                        /* Silently ignore non-regular files,
+-                         * eg '.' '..', 'lost+found' */
+-                        VIR_FREE(vol->backingStore);
+-                    }
+-                }
++            vol->backingStore.path = backingStore;
++            vol->backingStore.format = backingStoreFormat;
++
++            if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
++                                                     NULL,
++                                                     NULL) < 0) {
++                VIR_FREE(vol->backingStore.path);
++                goto cleanup;
+             }
+         }
+ 
+ 
+-
+         if (VIR_REALLOC_N(pool->volumes.objs,
+                           pool->volumes.count+1) < 0)
+             goto no_memory;
+-- 
+1.7.1.1
+
diff --git a/libvirt-0.8.2-apply-iptables-sport-mapping.patch b/libvirt-0.8.2-apply-iptables-sport-mapping.patch
new file mode 100644
index 0000000..d929a34
--- /dev/null
+++ b/libvirt-0.8.2-apply-iptables-sport-mapping.patch
@@ -0,0 +1,265 @@
+From 112a309bc7839e95c558b535143f855ce89cca8c Mon Sep 17 00:00:00 2001
+From: Daniel P. Berrange <berrange@redhat.com>
+Date: Thu, 10 Jun 2010 12:50:38 -0400
+Subject: [PATCH] CVE-2010-2242 Apply a source port mapping to virtual network masquerading
+
+IPtables will seek to preserve the source port unchanged when
+doing masquerading, if possible. NFS has a pseudo-security
+option where it checks for the source port <= 1023 before
+allowing a mount request. If an admin has used this to make the
+host OS trusted for mounts, the default iptables behaviour will
+potentially allow NAT'd guests access too. This needs to be
+stopped.
+
+With this change, the iptables -t nat -L -n -v rules for the
+default network will be
+
+Chain POSTROUTING (policy ACCEPT 95 packets, 9163 bytes)
+ pkts bytes target     prot opt in     out     source               destination
+   14   840 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24    masq ports: 1024-65535
+   75  5752 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24    masq ports: 1024-65535
+    0     0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24
+
+* src/network/bridge_driver.c: Add masquerade rules for TCP
+  and UDP protocols
+* src/util/iptables.c, src/util/iptables.c: Add source port
+  mappings for TCP & UDP protocols when masquerading.
+---
+ src/network/bridge_driver.c |   73 ++++++++++++++++++++++++++++++++++++++++--
+ src/util/iptables.c         |   70 +++++++++++++++++++++++++++++------------
+ src/util/iptables.h         |    6 ++-
+ 3 files changed, 122 insertions(+), 27 deletions(-)
+
+diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
+index 72255c1..80ed57a 100644
+--- a/src/network/bridge_driver.c
++++ b/src/network/bridge_driver.c
+@@ -638,18 +638,74 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
+         goto masqerr2;
+     }
+ 
+-    /* enable masquerading */
++    /*
++     * Enable masquerading.
++     *
++     * We need to end up with 3 rules in the table in this order
++     *
++     *  1. protocol=tcp with sport mapping restricton
++     *  2. protocol=udp with sport mapping restricton
++     *  3. generic any protocol
++     *
++     * The sport mappings are required, because default IPtables
++     * MASQUERADE is maintain port number unchanged where possible.
++     *
++     * NFS can be configured to only "trust" port numbers < 1023.
++     *
++     * Guests using NAT thus need to be prevented from having port
++     * numbers < 1023, otherwise they can bypass the NFS "security"
++     * check on the source port number.
++     *
++     * Since we use '--insert' to add rules to the header of the
++     * chain, we actually need to add them in the reverse of the
++     * order just mentioned !
++     */
++
++    /* First the generic masquerade rule for other protocols */
+     if ((err = iptablesAddForwardMasquerade(driver->iptables,
+                                             network->def->network,
+-                                            network->def->forwardDev))) {
++                                            network->def->forwardDev,
++                                            NULL))) {
+         virReportSystemError(err,
+                              _("failed to add iptables rule to enable masquerading to '%s'"),
+                              network->def->forwardDev ? network->def->forwardDev : NULL);
+         goto masqerr3;
+     }
+ 
++    /* UDP with a source port restriction */
++    if ((err = iptablesAddForwardMasquerade(driver->iptables,
++                                            network->def->network,
++                                            network->def->forwardDev,
++                                            "udp"))) {
++        virReportSystemError(err,
++                             _("failed to add iptables rule to enable UDP masquerading to '%s'"),
++                             network->def->forwardDev ? network->def->forwardDev : NULL);
++        goto masqerr4;
++    }
++
++    /* TCP with a source port restriction */
++    if ((err = iptablesAddForwardMasquerade(driver->iptables,
++                                            network->def->network,
++                                            network->def->forwardDev,
++                                            "tcp"))) {
++        virReportSystemError(err,
++                             _("failed to add iptables rule to enable TCP masquerading to '%s'"),
++                             network->def->forwardDev ? network->def->forwardDev : NULL);
++        goto masqerr5;
++    }
++
+     return 1;
+ 
++ masqerr5:
++    iptablesRemoveForwardMasquerade(driver->iptables,
++                                    network->def->network,
++                                    network->def->forwardDev,
++                                    "udp");
++ masqerr4:
++    iptablesRemoveForwardMasquerade(driver->iptables,
++                                    network->def->network,
++                                    network->def->forwardDev,
++                                    NULL);
+  masqerr3:
+     iptablesRemoveForwardAllowRelatedIn(driver->iptables,
+                                  network->def->network,
+@@ -814,8 +870,17 @@ networkRemoveIptablesRules(struct network_driver *driver,
+     if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
+         if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) {
+             iptablesRemoveForwardMasquerade(driver->iptables,
+-                                                network->def->network,
+-                                                network->def->forwardDev);
++                                            network->def->network,
++                                            network->def->forwardDev,
++                                            "tcp");
++            iptablesRemoveForwardMasquerade(driver->iptables,
++                                            network->def->network,
++                                            network->def->forwardDev,
++                                            "udp");
++            iptablesRemoveForwardMasquerade(driver->iptables,
++                                            network->def->network,
++                                            network->def->forwardDev,
++                                            NULL);
+             iptablesRemoveForwardAllowRelatedIn(driver->iptables,
+                                                 network->def->network,
+                                                 network->def->bridge,
+diff --git a/src/util/iptables.c b/src/util/iptables.c
+index d06b857..f63e8c6 100644
+--- a/src/util/iptables.c
++++ b/src/util/iptables.c
+@@ -692,25 +692,49 @@ iptablesRemoveForwardRejectIn(iptablesContext *ctx,
+  */
+ static int
+ iptablesForwardMasquerade(iptablesContext *ctx,
+-                       const char *network,
+-                       const char *physdev,
+-                       int action)
++                          const char *network,
++                          const char *physdev,
++                          const char *protocol,
++                          int action)
+ {
+-    if (physdev && physdev[0]) {
+-        return iptablesAddRemoveRule(ctx->nat_postrouting,
+-                                     action,
+-                                     "--source", network,
+-                                     "!", "--destination", network,
+-                                     "--out-interface", physdev,
+-                                     "--jump", "MASQUERADE",
+-                                     NULL);
++    if (protocol && protocol[0]) {
++        if (physdev && physdev[0]) {
++            return iptablesAddRemoveRule(ctx->nat_postrouting,
++                                         action,
++                                         "--source", network,
++                                         "-p", protocol,
++                                         "!", "--destination", network,
++                                         "--out-interface", physdev,
++                                         "--jump", "MASQUERADE",
++                                         "--to-ports", "1024-65535",
++                                         NULL);
++        } else {
++            return iptablesAddRemoveRule(ctx->nat_postrouting,
++                                         action,
++                                         "--source", network,
++                                         "-p", protocol,
++                                         "!", "--destination", network,
++                                         "--jump", "MASQUERADE",
++                                         "--to-ports", "1024-65535",
++                                         NULL);
++        }
+     } else {
+-        return iptablesAddRemoveRule(ctx->nat_postrouting,
+-                                     action,
+-                                     "--source", network,
+-                                     "!", "--destination", network,
+-                                     "--jump", "MASQUERADE",
+-                                     NULL);
++        if (physdev && physdev[0]) {
++            return iptablesAddRemoveRule(ctx->nat_postrouting,
++                                         action,
++                                         "--source", network,
++                                         "!", "--destination", network,
++                                         "--out-interface", physdev,
++                                         "--jump", "MASQUERADE",
++                                         NULL);
++        } else {
++            return iptablesAddRemoveRule(ctx->nat_postrouting,
++                                         action,
++                                         "--source", network,
++                                         "!", "--destination", network,
++                                         "--jump", "MASQUERADE",
++                                         NULL);
++        }
+     }
+ }
+ 
+@@ -719,6 +743,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
+  * @ctx: pointer to the IP table context
+  * @network: the source network name
+  * @physdev: the physical input device or NULL
++ * @protocol: the network protocol or NULL
+  *
+  * Add rules to the IP table context to allow masquerading
+  * network @network on @physdev. This allow the bridge to
+@@ -729,9 +754,10 @@ iptablesForwardMasquerade(iptablesContext *ctx,
+ int
+ iptablesAddForwardMasquerade(iptablesContext *ctx,
+                              const char *network,
+-                             const char *physdev)
++                             const char *physdev,
++                             const char *protocol)
+ {
+-    return iptablesForwardMasquerade(ctx, network, physdev, ADD);
++    return iptablesForwardMasquerade(ctx, network, physdev, protocol, ADD);
+ }
+ 
+ /**
+@@ -739,6 +765,7 @@ iptablesAddForwardMasquerade(iptablesContext *ctx,
+  * @ctx: pointer to the IP table context
+  * @network: the source network name
+  * @physdev: the physical input device or NULL
++ * @protocol: the network protocol or NULL
+  *
+  * Remove rules from the IP table context to stop masquerading
+  * network @network on @physdev. This stops the bridge from
+@@ -749,7 +776,8 @@ iptablesAddForwardMasquerade(iptablesContext *ctx,
+ int
+ iptablesRemoveForwardMasquerade(iptablesContext *ctx,
+                                 const char *network,
+-                                const char *physdev)
++                                const char *physdev,
++                                const char *protocol)
+ {
+-    return iptablesForwardMasquerade(ctx, network, physdev, REMOVE);
++    return iptablesForwardMasquerade(ctx, network, physdev, protocol, REMOVE);
+ }
+diff --git a/src/util/iptables.h b/src/util/iptables.h
+index 7d55a6d..b47d854 100644
+--- a/src/util/iptables.h
++++ b/src/util/iptables.h
+@@ -85,9 +85,11 @@ int              iptablesRemoveForwardRejectIn   (iptablesContext *ctx,
+ 
+ int              iptablesAddForwardMasquerade    (iptablesContext *ctx,
+                                                   const char *network,
+-                                                  const char *physdev);
++                                                  const char *physdev,
++                                                  const char *protocol);
+ int              iptablesRemoveForwardMasquerade (iptablesContext *ctx,
+                                                   const char *network,
+-                                                  const char *physdev);
++                                                  const char *physdev,
++                                                  const char *protocol);
+ 
+ #endif /* __QEMUD_IPTABLES_H__ */
+-- 
+1.6.6.1
+
diff --git a/libvirt.spec b/libvirt.spec
index 9d25e18..9756199 100644
--- a/libvirt.spec
+++ b/libvirt.spec
@@ -159,6 +159,8 @@
 
 %if %{with_macvtap}
 %define with_libnl 1
+%else
+%define with_libnl 0
 %endif
 
 # Force QEMU to run as non-root
@@ -183,10 +185,24 @@
 Summary: Library providing a simple API virtualization
 Name: libvirt
 Version: 0.8.2
-Release: 1%{?dist}%{?extra_release}
+Release: 2%{?dist}%{?extra_release}
 License: LGPLv2+
 Group: Development/Libraries
 Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz
+# Patches 1-> 11  CVE-2010-2237, 2238, 2239
+Patch1: libvirt-0.8.2-01-extract-backing-store-format.patch
+Patch2: libvirt-0.8.2-02-remove-type-field.patch
+Patch3: libvirt-0.8.2-03-refactor-metadata-extract.patch
+Patch4: libvirt-0.8.2-04-require-storage-format.patch
+Patch5: libvirt-0.8.2-05-disk-path-iterator.patch
+Patch6: libvirt-0.8.2-06-use-disk-iterator.patch
+Patch7: libvirt-0.8.2-07-secdriver-params.patch
+Patch8: libvirt-0.8.2-08-disable-disk-probing.patch
+Patch9: libvirt-0.8.2-09-set-default-driver.patch
+Patch10: libvirt-0.8.2-10-qemu-img-format-handling.patch
+Patch11: libvirt-0.8.2-11-storage-vol-backing.patch
+# CVE-2010-2242
+Patch12: libvirt-0.8.2-apply-iptables-sport-mapping.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 URL: http://libvirt.org/
 BuildRequires: python-devel
@@ -422,6 +438,18 @@ of recent versions of Linux (and other OSes).
 
 %prep
 %setup -q
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
 
 %build
 %if ! %{with_xen}
@@ -661,6 +689,12 @@ do
   printf "#!/bin/sh\nexit 0\n" > $i
   chmod +x $i
 done
+# Temp hack till we figure out why its broken on ppc
+%ifarch ppc
+rm -f nwfilterxml2xmltest
+printf "#!/bin/sh\nexit 0\n" > nwfilterxml2xmltest
+chmod +x nwfilterxml2xmltest
+%endif
 make check
 
 %pre
@@ -903,6 +937,14 @@ fi
 %endif
 
 %changelog
+* Mon Jul 12 2010 Daniel P. Berrange <berrange@redhat.com> - 0.8.2-2
+- CVE-2010-2237 ignoring defined main disk format when looking up disk backing stores
+- CVE-2010-2238 ignoring defined disk backing store format when recursing into disk
+  image backing stores
+- CVE-2010-2239 not setting user defined backing store format when creating new image
+- CVE-2010-2242 libvirt: improperly mapped source privileged ports may allow for
+  obtaining privileged resources on the host
+
 * Mon Jul  5 2010 Daniel Veillard <veillard@redhat.com> - 0.8.2-1
 - Upstream release 0.8.2
 - phyp: adding support for IVM