diff --git a/SOURCES/libvirt-Add-invariant-TSC-cpu-flag.patch b/SOURCES/libvirt-Add-invariant-TSC-cpu-flag.patch
new file mode 100644
index 0000000..dfc59fd
--- /dev/null
+++ b/SOURCES/libvirt-Add-invariant-TSC-cpu-flag.patch
@@ -0,0 +1,108 @@
+From 65d750dec286074fc48fdaa64eb3f5029626506f Mon Sep 17 00:00:00 2001
+Message-Id: <65d750dec286074fc48fdaa64eb3f5029626506f@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 6 May 2014 13:55:44 +0200
+Subject: [PATCH] Add invariant TSC cpu flag
+
+Add suport for invariant TSC flag (CPUID 0x80000007, bit 8 of EDX).
+If this flag is enabled, the TSC ticks at a constant rate across
+all ACPI P-, C- and T-states.
+
+This can be enabled by adding:
+<feature name='invtsc'/>
+to the <cpu> element.
+
+Migration and saving the domain does not work with this flag.
+
+QEMU support: http://git.qemu.org/?p=qemu.git;a=commitdiff;h=303752a
+
+The feature name "invtsc" differs from the name "" used by the linux kernel:
+https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/powerflags.c?id=30321c7b#n18
+
+(cherry picked from commit fba6bc47cbcabbe08d42279691efb0dff3b9c997)
+https://bugzilla.redhat.com/show_bug.cgi?id=1185458
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu/cpu_map.xml       |  5 +++++
+ src/qemu/qemu_migration.c | 15 +++++++++++++++
+ src/qemu/qemu_process.c   | 15 +++++++++++++++
+ 3 files changed, 35 insertions(+)
+
+diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
+index 6d51283..aa10019 100644
+--- a/src/cpu/cpu_map.xml
++++ b/src/cpu/cpu_map.xml
+@@ -327,6 +327,11 @@
+       <cpuid function='0x00000007' ebx='0x00100000'/>
+     </feature>
+ 
++    <!-- Advanced Power Management edx features -->
++    <feature name='invtsc'>
++      <cpuid function='0x80000007' edx='0x00000100'/>
++    </feature>
++
+     <!-- models -->
+     <model name='486'>
+       <feature name='fpu'/>
+diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
+index deacb66..d979d50 100644
+--- a/src/qemu/qemu_migration.c
++++ b/src/qemu/qemu_migration.c
+@@ -1506,6 +1506,21 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm,
+         return false;
+     }
+ 
++    for (i = 0; i < def->cpu->nfeatures; i++) {
++        virCPUFeatureDefPtr feature = &def->cpu->features[i];
++
++        if (feature->policy != VIR_CPU_FEATURE_REQUIRE)
++            continue;
++
++        /* QEMU blocks migration and save with invariant TSC enabled */
++        if (STREQ(feature->name, "invtsc")) {
++            virReportError(VIR_ERR_OPERATION_INVALID,
++                           _("domain has CPU feature: %s"),
++                           feature->name);
++            return false;
++        }
++    }
++
+     return true;
+ }
+ 
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 3eda15b..8c07397 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3520,6 +3520,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm)
+     virCPUDataPtr guestcpu = NULL;
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     bool ret = false;
++    size_t i;
+ 
+     switch (arch) {
+     case VIR_ARCH_I686:
+@@ -3538,6 +3539,20 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm)
+                 goto cleanup;
+             }
+         }
++
++        for (i = 0; i < def->cpu->nfeatures; i++) {
++            virCPUFeatureDefPtr feature = &def->cpu->features[i];
++
++            if (feature->policy != VIR_CPU_FEATURE_REQUIRE)
++                continue;
++
++            if (STREQ(feature->name, "invtsc") &&
++                !cpuHasFeature(guestcpu, feature->name)) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                               _("host doesn't support invariant TSC"));
++                goto cleanup;
++            }
++        }
+         break;
+ 
+     default:
+-- 
+2.2.2
+
diff --git a/SOURCES/libvirt-Also-filter-out-non-migratable-features-out-of-host-passthrough.patch b/SOURCES/libvirt-Also-filter-out-non-migratable-features-out-of-host-passthrough.patch
new file mode 100644
index 0000000..a46e51c
--- /dev/null
+++ b/SOURCES/libvirt-Also-filter-out-non-migratable-features-out-of-host-passthrough.patch
@@ -0,0 +1,78 @@
+From b2c63abced4d6e2f263125ab903917549fcd3abd Mon Sep 17 00:00:00 2001
+Message-Id: <b2c63abced4d6e2f263125ab903917549fcd3abd@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Mon, 29 Sep 2014 12:44:43 +0200
+Subject: [PATCH] Also filter out non-migratable features out of
+ host-passthrough
+
+Commit de0aeaf filtered them out from the host-model features,
+to allow host-model to be migratable by default.
+
+Even though they are not passed to QEMU for host-passthrough,
+(and not enabled by default) filter them out too
+so the user does not think the domain has them.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1147584
+(cherry picked from commit f53bb1af90737205fdbfd26dc99865c02457d8c9)
+https://bugzilla.redhat.com/show_bug.cgi?id=1185458
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+
+Conflicts:
+	src/cpu/cpu_x86.c -- context; const virCPUDefPtr vs. const
+        virCPUDef * (changed by d694ae0c)
+---
+ src/cpu/cpu_x86.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
+index 341a7f5..dffa488 100644
+--- a/src/cpu/cpu_x86.c
++++ b/src/cpu/cpu_x86.c
+@@ -1984,7 +1984,8 @@ cleanup:
+ 
+ static int
+ x86UpdateHostModel(virCPUDefPtr guest,
+-                   const virCPUDefPtr host)
++                   const virCPUDefPtr host,
++                   bool passthrough)
+ {
+     virCPUDefPtr oldguest = NULL;
+     const struct x86_map *map;
+@@ -1992,8 +1993,6 @@ x86UpdateHostModel(virCPUDefPtr guest,
+     size_t i;
+     int ret = -1;
+ 
+-    guest->match = VIR_CPU_MATCH_EXACT;
+-
+     if (!(map = virCPUx86GetMap()))
+         goto cleanup;
+ 
+@@ -2016,8 +2015,7 @@ x86UpdateHostModel(virCPUDefPtr guest,
+             }
+         }
+     }
+-
+-    for (i = 0; i < oldguest->nfeatures; i++) {
++    for (i = 0; !passthrough && i < oldguest->nfeatures; i++) {
+         if (virCPUDefUpdateFeature(guest,
+                                    oldguest->features[i].name,
+                                    oldguest->features[i].policy) < 0)
+@@ -2041,12 +2039,12 @@ x86Update(virCPUDefPtr guest,
+         return x86UpdateCustom(guest, host);
+ 
+     case VIR_CPU_MODE_HOST_MODEL:
+-        return x86UpdateHostModel(guest, host);
++        guest->match = VIR_CPU_MATCH_EXACT;
++        return x86UpdateHostModel(guest, host, false);
+ 
+     case VIR_CPU_MODE_HOST_PASSTHROUGH:
+         guest->match = VIR_CPU_MATCH_MINIMUM;
+-        virCPUDefFreeModel(guest);
+-        return virCPUDefCopyModel(guest, host, true);
++        return x86UpdateHostModel(guest, host, true);
+ 
+     case VIR_CPU_MODE_LAST:
+         break;
+-- 
+2.2.2
+
diff --git a/SOURCES/libvirt-Don-t-include-non-migratable-features-in-host-model.patch b/SOURCES/libvirt-Don-t-include-non-migratable-features-in-host-model.patch
new file mode 100644
index 0000000..9248460
--- /dev/null
+++ b/SOURCES/libvirt-Don-t-include-non-migratable-features-in-host-model.patch
@@ -0,0 +1,261 @@
+From 10be3da4947fc7923732e2056516a41514bd1695 Mon Sep 17 00:00:00 2001
+Message-Id: <10be3da4947fc7923732e2056516a41514bd1695@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 5 Sep 2014 09:50:36 +0200
+Subject: [PATCH] Don't include non-migratable features in host-model
+
+Commit fba6bc4 introduced support for the 'invtsc' feature,
+which blocks migration. We should not include it in the
+host-model CPU by default, because it's intended to be used
+with migration.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1138221
+(cherry picked from commit de0aeafe9ce3eb414c8b5d3aa8995d776a2952de)
+https://bugzilla.redhat.com/show_bug.cgi?id=1185458
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+
+Conflicts:
+	src/cpu/cpu_x86.c - context -- missing {} (fixed by ff78ff7c)
+---
+ src/cpu/cpu_map.xml                              |  2 +-
+ src/cpu/cpu_x86.c                                | 65 ++++++++++++++++++++++--
+ tests/cputest.c                                  |  1 +
+ tests/cputestdata/x86-host-invtsc+host-model.xml | 22 ++++++++
+ tests/cputestdata/x86-host-invtsc.xml            | 27 ++++++++++
+ 5 files changed, 111 insertions(+), 6 deletions(-)
+ create mode 100644 tests/cputestdata/x86-host-invtsc+host-model.xml
+ create mode 100644 tests/cputestdata/x86-host-invtsc.xml
+
+diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
+index aa10019..28bc5ec 100644
+--- a/src/cpu/cpu_map.xml
++++ b/src/cpu/cpu_map.xml
+@@ -328,7 +328,7 @@
+     </feature>
+ 
+     <!-- Advanced Power Management edx features -->
+-    <feature name='invtsc'>
++    <feature name='invtsc' migratable='no'>
+       <cpuid function='0x80000007' edx='0x00000100'/>
+     </feature>
+ 
+diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
+index 4e77550..8ced69d 100644
+--- a/src/cpu/cpu_x86.c
++++ b/src/cpu/cpu_x86.c
+@@ -87,6 +87,7 @@ struct x86_map {
+     struct x86_vendor *vendors;
+     struct x86_feature *features;
+     struct x86_model *models;
++    struct x86_feature *migrate_blockers;
+ };
+ 
+ static struct x86_map* virCPUx86Map = NULL;
+@@ -590,6 +591,28 @@ x86FeatureFree(struct x86_feature *feature)
+ 
+ 
+ static struct x86_feature *
++x86FeatureCopy(const struct x86_feature *src)
++{
++    struct x86_feature *feature;
++
++    if (VIR_ALLOC(feature) < 0)
++        return NULL;
++
++    if (VIR_STRDUP(feature->name, src->name) < 0)
++        goto error;
++
++    if ((feature->data = x86DataCopy(src->data)) == NULL)
++        goto error;
++
++    return feature;
++
++ error:
++    x86FeatureFree(feature);
++    return NULL;
++}
++
++
++static struct x86_feature *
+ x86FeatureFind(const struct x86_map *map,
+                const char *name)
+ {
+@@ -675,6 +698,9 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
+     int ret = 0;
+     size_t i;
+     int n;
++    char *str = NULL;
++    bool migratable = true;
++    struct x86_feature *migrate_blocker = NULL;
+ 
+     if (!(feature = x86FeatureNew()))
+         goto error;
+@@ -692,6 +718,10 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
+         goto ignore;
+     }
+ 
++    str = virXPathString("string(@migratable)", ctxt);
++    if (STREQ_NULLABLE(str, "no"))
++        migratable = false;
++
+     n = virXPathNodeSet("./cpuid", ctxt, &nodes);
+     if (n < 0)
+         goto ignore;
+@@ -708,6 +738,14 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
+             goto error;
+     }
+ 
++    if (!migratable) {
++        if ((migrate_blocker = x86FeatureCopy(feature)) == NULL)
++            goto error;
++
++        migrate_blocker->next = map->migrate_blockers;
++        map->migrate_blockers = migrate_blocker;
++    }
++
+     if (map->features == NULL)
+         map->features = feature;
+     else {
+@@ -718,6 +756,7 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
+ out:
+     ctxt->node = ctxt_node;
+     VIR_FREE(nodes);
++    VIR_FREE(str);
+ 
+     return ret;
+ 
+@@ -726,6 +765,7 @@ error:
+ 
+ ignore:
+     x86FeatureFree(feature);
++    x86FeatureFree(migrate_blocker);
+     goto out;
+ }
+ 
+@@ -1061,6 +1101,12 @@ x86MapFree(struct x86_map *map)
+         x86VendorFree(vendor);
+     }
+ 
++    while (map->migrate_blockers != NULL) {
++        struct x86_feature *migrate_blocker = map->migrate_blockers;
++        map->migrate_blockers = migrate_blocker->next;
++        x86FeatureFree(migrate_blocker);
++    }
++
+     VIR_FREE(map);
+ }
+ 
+@@ -1941,16 +1987,15 @@ x86UpdateHostModel(virCPUDefPtr guest,
+                    const virCPUDefPtr host)
+ {
+     virCPUDefPtr oldguest = NULL;
++    const struct x86_map *map;
++    const struct x86_feature *feat;
+     size_t i;
+     int ret = -1;
+ 
+     guest->match = VIR_CPU_MATCH_EXACT;
+ 
+-    /* no updates are required */
+-    if (guest->nfeatures == 0) {
+-        virCPUDefFreeModel(guest);
+-        return virCPUDefCopyModel(guest, host, true);
+-    }
++    if (!(map = virCPUx86GetMap()))
++        goto cleanup;
+ 
+     /* update the host model according to the desired configuration */
+     if (!(oldguest = virCPUDefCopy(guest)))
+@@ -1960,6 +2005,16 @@ x86UpdateHostModel(virCPUDefPtr guest,
+     if (virCPUDefCopyModel(guest, host, true) < 0)
+         goto cleanup;
+ 
++    /* Remove non-migratable features by default
++     * Note: this only works as long as no CPU model contains non-migratable
++     * features directly */
++    for (i = 0; i < guest->nfeatures; i++) {
++        for (feat = map->migrate_blockers; feat; feat = feat->next) {
++            if (STREQ(feat->name, guest->features[i].name))
++                VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures);
++        }
++    }
++
+     for (i = 0; i < oldguest->nfeatures; i++) {
+         if (virCPUDefUpdateFeature(guest,
+                                    oldguest->features[i].name,
+diff --git a/tests/cputest.c b/tests/cputest.c
+index 6a1cfeb..153556a 100644
+--- a/tests/cputest.c
++++ b/tests/cputest.c
+@@ -591,6 +591,7 @@ mymain(void)
+     DO_TEST_UPDATE("x86", "host", "host-model", VIR_CPU_COMPARE_IDENTICAL);
+     DO_TEST_UPDATE("x86", "host", "host-model-nofallback", VIR_CPU_COMPARE_IDENTICAL);
+     DO_TEST_UPDATE("x86", "host", "host-passthrough", VIR_CPU_COMPARE_IDENTICAL);
++    DO_TEST_UPDATE("x86", "host-invtsc", "host-model", VIR_CPU_COMPARE_SUPERSET);
+ 
+     /* computing baseline CPUs */
+     DO_TEST_BASELINE("x86", "incompatible-vendors", -1);
+diff --git a/tests/cputestdata/x86-host-invtsc+host-model.xml b/tests/cputestdata/x86-host-invtsc+host-model.xml
+new file mode 100644
+index 0000000..ad1bbf8
+--- /dev/null
++++ b/tests/cputestdata/x86-host-invtsc+host-model.xml
+@@ -0,0 +1,22 @@
++<cpu mode='host-model' match='exact'>
++  <model fallback='allow'>SandyBridge</model>
++  <vendor>Intel</vendor>
++  <feature policy='require' name='osxsave'/>
++  <feature policy='require' name='pcid'/>
++  <feature policy='require' name='pdcm'/>
++  <feature policy='require' name='xtpr'/>
++  <feature policy='require' name='tm2'/>
++  <feature policy='require' name='est'/>
++  <feature policy='require' name='smx'/>
++  <feature policy='require' name='vmx'/>
++  <feature policy='require' name='ds_cpl'/>
++  <feature policy='require' name='monitor'/>
++  <feature policy='require' name='dtes64'/>
++  <feature policy='require' name='pbe'/>
++  <feature policy='require' name='tm'/>
++  <feature policy='require' name='ht'/>
++  <feature policy='require' name='ss'/>
++  <feature policy='require' name='acpi'/>
++  <feature policy='require' name='ds'/>
++  <feature policy='require' name='vme'/>
++</cpu>
+diff --git a/tests/cputestdata/x86-host-invtsc.xml b/tests/cputestdata/x86-host-invtsc.xml
+new file mode 100644
+index 0000000..f558399
+--- /dev/null
++++ b/tests/cputestdata/x86-host-invtsc.xml
+@@ -0,0 +1,27 @@
++<cpu>
++  <arch>x86_64</arch>
++  <model>SandyBridge</model>
++  <vendor>Intel</vendor>
++  <topology sockets='1' cores='2' threads='2'/>
++  <feature name='invtsc'/>
++  <feature name='osxsave'/>
++  <feature name='pcid'/>
++  <feature name='pdcm'/>
++  <feature name='xtpr'/>
++  <feature name='tm2'/>
++  <feature name='est'/>
++  <feature name='smx'/>
++  <feature name='vmx'/>
++  <feature name='ds_cpl'/>
++  <feature name='monitor'/>
++  <feature name='dtes64'/>
++  <feature name='pbe'/>
++  <feature name='tm'/>
++  <feature name='ht'/>
++  <feature name='ss'/>
++  <feature name='acpi'/>
++  <feature name='ds'/>
++  <feature name='vme'/>
++  <pages unit='KiB' size='4'/>
++  <pages unit='KiB' size='2048'/>
++</cpu>
+-- 
+2.2.2
+
diff --git a/SOURCES/libvirt-Fix-leak-in-x86UpdateHostModel.patch b/SOURCES/libvirt-Fix-leak-in-x86UpdateHostModel.patch
new file mode 100644
index 0000000..d24d94e
--- /dev/null
+++ b/SOURCES/libvirt-Fix-leak-in-x86UpdateHostModel.patch
@@ -0,0 +1,34 @@
+From 310634521378f3ae84f0f73293a591681f24648f Mon Sep 17 00:00:00 2001
+Message-Id: <310634521378f3ae84f0f73293a591681f24648f@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Thu, 18 Sep 2014 11:55:52 +0200
+Subject: [PATCH] Fix leak in x86UpdateHostModel
+
+Commit de0aeaf introduced a memory leak.
+
+(cherry picked from commit 5b5631dedf59e540661bfeac774e543d8d38531b)
+https://bugzilla.redhat.com/show_bug.cgi?id=1185458
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu/cpu_x86.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
+index 8ced69d..341a7f5 100644
+--- a/src/cpu/cpu_x86.c
++++ b/src/cpu/cpu_x86.c
+@@ -2010,8 +2010,10 @@ x86UpdateHostModel(virCPUDefPtr guest,
+      * features directly */
+     for (i = 0; i < guest->nfeatures; i++) {
+         for (feat = map->migrate_blockers; feat; feat = feat->next) {
+-            if (STREQ(feat->name, guest->features[i].name))
++            if (STREQ(feat->name, guest->features[i].name)) {
++                VIR_FREE(guest->features[i].name);
+                 VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures);
++            }
+         }
+     }
+ 
+-- 
+2.2.2
+
diff --git a/SOURCES/libvirt-Fix-libvirtd-crash-when-removing-metadata.patch b/SOURCES/libvirt-Fix-libvirtd-crash-when-removing-metadata.patch
new file mode 100644
index 0000000..339b932
--- /dev/null
+++ b/SOURCES/libvirt-Fix-libvirtd-crash-when-removing-metadata.patch
@@ -0,0 +1,37 @@
+From 04e1195be4e5e52da19050e2fadae95e9525ef3b Mon Sep 17 00:00:00 2001
+Message-Id: <04e1195be4e5e52da19050e2fadae95e9525ef3b@dist-git>
+From: Erik Skultety <eskultet@redhat.com>
+Date: Thu, 22 Jan 2015 16:25:16 +0100
+Subject: [PATCH] Fix libvirtd crash when removing metadata
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+When trying to remove nonexistent metadata from XML, libvirt daemon
+crashes due to dereferencing NULL pointer.
+
+Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1143955
+
+(cherry picked from commit 288c47406cffa7a6eb9e9c29764850b0cdeb5508)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virxml.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/util/virxml.c b/src/util/virxml.c
+index 88c1fcc..6cee8e1 100644
+--- a/src/util/virxml.c
++++ b/src/util/virxml.c
+@@ -979,6 +979,9 @@ virXMLFindChildNodeByNs(xmlNodePtr root,
+ {
+     xmlNodePtr next;
+ 
++    if (!root)
++        return NULL;
++
+     for (next = root->children; next; next = next->next) {
+         if (next->ns &&
+             STREQ_NULLABLE((const char *) next->ns->href, uri))
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-Fix-possible-memory-leak-in-util-virxml.c.patch b/SOURCES/libvirt-Fix-possible-memory-leak-in-util-virxml.c.patch
new file mode 100644
index 0000000..557effe
--- /dev/null
+++ b/SOURCES/libvirt-Fix-possible-memory-leak-in-util-virxml.c.patch
@@ -0,0 +1,37 @@
+From a26ded37a2e5d1deaa34fcc83d8cc6c4067ad040 Mon Sep 17 00:00:00 2001
+Message-Id: <a26ded37a2e5d1deaa34fcc83d8cc6c4067ad040@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:56 +0100
+Subject: [PATCH] Fix possible memory leak in util/virxml.c
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+A "xmlstr" string may not be assigned into a "doc" pointer and it
+could cause memory leak. To fix it if the "doc" pointer is NULL and
+the "xmlstr" string is not assigned we should free it.
+
+This has been found by coverity.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit 67fbf129fc8727c98f7c4123c12a48938ccdf3fa)
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virxml.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/util/virxml.c b/src/util/virxml.c
+index de1e1e0..88a1196 100644
+--- a/src/util/virxml.c
++++ b/src/util/virxml.c
+@@ -1047,6 +1047,8 @@ virXMLExtractNamespaceXML(xmlNodePtr root,
+ cleanup:
+     if (doc)
+         *doc = xmlstr;
++    else
++        VIR_FREE(xmlstr);
+     xmlFreeNode(nodeCopy);
+     return ret;
+ }
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-Fix-segfault-when-starting-a-domain-with-no-cpu-definition.patch b/SOURCES/libvirt-Fix-segfault-when-starting-a-domain-with-no-cpu-definition.patch
new file mode 100644
index 0000000..9ad371f
--- /dev/null
+++ b/SOURCES/libvirt-Fix-segfault-when-starting-a-domain-with-no-cpu-definition.patch
@@ -0,0 +1,46 @@
+From d0a2e30fb26302eaaa5efa0f2d1d1fbe7853934a Mon Sep 17 00:00:00 2001
+Message-Id: <d0a2e30fb26302eaaa5efa0f2d1d1fbe7853934a@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 2 Jul 2014 10:35:31 +0200
+Subject: [PATCH] Fix segfault when starting a domain with no cpu definition
+
+My commit fba6bc4 iterated over the features in cpu definition
+without checking if there is one.
+
+(cherry picked from commit 1cd8f500ee133653ecb9d1b7f72b2b2e9870a1c3)
+https://bugzilla.redhat.com/show_bug.cgi?id=1185458
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_migration.c | 2 +-
+ src/qemu/qemu_process.c   | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
+index d979d50..2e495a8 100644
+--- a/src/qemu/qemu_migration.c
++++ b/src/qemu/qemu_migration.c
+@@ -1506,7 +1506,7 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm,
+         return false;
+     }
+ 
+-    for (i = 0; i < def->cpu->nfeatures; i++) {
++    for (i = 0; def->cpu && i < def->cpu->nfeatures; i++) {
+         virCPUFeatureDefPtr feature = &def->cpu->features[i];
+ 
+         if (feature->policy != VIR_CPU_FEATURE_REQUIRE)
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 8c07397..11d5af5 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3540,7 +3540,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm)
+             }
+         }
+ 
+-        for (i = 0; i < def->cpu->nfeatures; i++) {
++        for (i = 0; def->cpu && i < def->cpu->nfeatures; i++) {
+             virCPUFeatureDefPtr feature = &def->cpu->features[i];
+ 
+             if (feature->policy != VIR_CPU_FEATURE_REQUIRE)
+-- 
+2.2.2
+
diff --git a/SOURCES/libvirt-conf-Add-support-for-requesting-of-XML-metadata-via-the-API.patch b/SOURCES/libvirt-conf-Add-support-for-requesting-of-XML-metadata-via-the-API.patch
new file mode 100644
index 0000000..4c63a12
--- /dev/null
+++ b/SOURCES/libvirt-conf-Add-support-for-requesting-of-XML-metadata-via-the-API.patch
@@ -0,0 +1,236 @@
+From 25d339a412b1a3d3436d3ff3c9ed63139c8f2428 Mon Sep 17 00:00:00 2001
+Message-Id: <25d339a412b1a3d3436d3ff3c9ed63139c8f2428@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:45 +0100
+Subject: [PATCH] conf: Add support for requesting of XML metadata via the API
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+The virDomainGetMetadata function was designed to support also retrieval
+of app specific metadata from the <metadata> element. This functionality
+was never implemented originally.
+
+(cherry picked from commit ac38bff077642daa17f9a82480062ebef4c11a7b)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c   |  19 ++++----
+ src/libvirt_private.syms |   1 +
+ src/util/virxml.c        | 122 +++++++++++++++++++++++++++++++++++++++++++++++
+ src/util/virxml.h        |   7 +++
+ 4 files changed, 140 insertions(+), 9 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 6817e0e..c104218 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -18987,7 +18987,6 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
+                         unsigned int flags)
+ {
+     virDomainDefPtr def;
+-    char *field = NULL;
+     char *ret = NULL;
+ 
+     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+@@ -19002,17 +19001,21 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
+ 
+     switch ((virDomainMetadataType) type) {
+     case VIR_DOMAIN_METADATA_DESCRIPTION:
+-        field = def->description;
++        if (VIR_STRDUP(ret, def->description) < 0)
++            goto cleanup;
+         break;
+ 
+     case VIR_DOMAIN_METADATA_TITLE:
+-        field = def->title;
++        if (VIR_STRDUP(ret, def->title) < 0)
++            goto cleanup;
+         break;
+ 
+     case VIR_DOMAIN_METADATA_ELEMENT:
+-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+-                       _("<metadata> element is not yet supported"));
+-        goto cleanup;
++        if (!def->metadata)
++            break;
++
++        if (virXMLExtractNamespaceXML(def->metadata, uri, &ret) < 0)
++            goto cleanup;
+         break;
+ 
+     default:
+@@ -19022,12 +19025,10 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
+         break;
+     }
+ 
+-    if (!field)
++    if (!ret)
+         virReportError(VIR_ERR_NO_DOMAIN_METADATA, "%s",
+                        _("Requested metadata element is not present"));
+ 
+-    ignore_value(VIR_STRDUP(ret, field));
+-
+ cleanup:
+     return ret;
+ }
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 3df4379..1fbee18 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2140,6 +2140,7 @@ virUUIDParse;
+ 
+ # util/virxml.h
+ virXMLChildElementCount;
++virXMLExtractNamespaceXML;
+ virXMLNodeToString;
+ virXMLParseHelper;
+ virXMLPickShellSafeComment;
+diff --git a/src/util/virxml.c b/src/util/virxml.c
+index 9bb8bf0..9048d78 100644
+--- a/src/util/virxml.c
++++ b/src/util/virxml.c
+@@ -928,3 +928,125 @@ cleanup:
+ 
+      return ret;
+ }
++
++typedef int (*virXMLForeachCallback)(xmlNodePtr node,
++                                     void *opaque);
++
++static int
++virXMLForeachNode(xmlNodePtr root,
++                  virXMLForeachCallback cb,
++                  void *opaque);
++
++static int
++virXMLForeachNode(xmlNodePtr root,
++                  virXMLForeachCallback cb,
++                  void *opaque)
++{
++    xmlNodePtr next;
++    int ret;
++
++    for (next = root; next; next = next->next) {
++        if ((ret = cb(next, opaque)) != 0)
++            return ret;
++
++        /* recurse into children */
++        if (next->children) {
++            if ((ret = virXMLForeachNode(next->children, cb, opaque)) != 0)
++                return ret;
++        }
++    }
++
++    return 0;
++}
++
++
++static int
++virXMLRemoveElementNamespace(xmlNodePtr node,
++                             void *opaque)
++{
++    const char *uri = opaque;
++
++    if (node->ns &&
++        STREQ_NULLABLE((const char *)node->ns->href, uri))
++        xmlSetNs(node, NULL);
++    return 0;
++}
++
++
++xmlNodePtr
++virXMLFindChildNodeByNs(xmlNodePtr root,
++                        const char *uri)
++{
++    xmlNodePtr next;
++
++    for (next = root->children; next; next = next->next) {
++        if (next->ns &&
++            STREQ_NULLABLE((const char *) next->ns->href, uri))
++            return next;
++    }
++
++    return NULL;
++}
++
++
++/**
++ * virXMLExtractNamespaceXML: extract a sub-namespace of XML as string
++ */
++int
++virXMLExtractNamespaceXML(xmlNodePtr root,
++                          const char *uri,
++                          char **doc)
++{
++    xmlNodePtr node;
++    xmlNodePtr nodeCopy = NULL;
++    xmlNsPtr actualNs;
++    xmlNsPtr prevNs = NULL;
++    char *xmlstr = NULL;
++    int ret = -1;
++
++    if (!(node = virXMLFindChildNodeByNs(root, uri))) {
++        /* node not found */
++        ret = 1;
++        goto cleanup;
++    }
++
++    /* copy the node so that we can modify the namespace */
++    if (!(nodeCopy = xmlCopyNode(node, 1))) {
++        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                       _("Failed to copy XML node"));
++        goto cleanup;
++    }
++
++    virXMLForeachNode(nodeCopy, virXMLRemoveElementNamespace,
++                      (void *)uri);
++
++    /* remove the namespace declaration
++     *  - it's only a single linked list ... doh */
++    for (actualNs = nodeCopy->nsDef; actualNs; actualNs = actualNs->next) {
++        if (STREQ_NULLABLE((const char *)actualNs->href, uri)) {
++
++            /* unlink */
++            if (prevNs)
++                prevNs->next = actualNs->next;
++            else
++                nodeCopy->nsDef = actualNs->next;
++
++            /* discard */
++            xmlFreeNs(actualNs);
++            break;
++        }
++
++        prevNs = actualNs;
++    }
++
++    if (!(xmlstr = virXMLNodeToString(nodeCopy->doc, nodeCopy)))
++        goto cleanup;
++
++    ret = 0;
++
++cleanup:
++    if (doc)
++        *doc = xmlstr;
++    xmlFreeNode(nodeCopy);
++    return ret;
++}
+diff --git a/src/util/virxml.h b/src/util/virxml.h
+index bb34069..7dc6c9d 100644
+--- a/src/util/virxml.h
++++ b/src/util/virxml.h
+@@ -165,4 +165,11 @@ int virXMLSaveFile(const char *path,
+ 
+ char *virXMLNodeToString(xmlDocPtr doc, xmlNodePtr node);
+ 
++xmlNodePtr virXMLFindChildNodeByNs(xmlNodePtr root,
++                                   const char *uri);
++
++int virXMLExtractNamespaceXML(xmlNodePtr root,
++                              const char *uri,
++                              char **doc);
++
+ #endif                          /* __VIR_XML_H__ */
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-conf-Avoid-false-positive-of-uninitialized-variable-use.patch b/SOURCES/libvirt-conf-Avoid-false-positive-of-uninitialized-variable-use.patch
new file mode 100644
index 0000000..5fe8bd7
--- /dev/null
+++ b/SOURCES/libvirt-conf-Avoid-false-positive-of-uninitialized-variable-use.patch
@@ -0,0 +1,57 @@
+From bb5ed814786f3148d1e54e26e9be10ea332c3058 Mon Sep 17 00:00:00 2001
+Message-Id: <bb5ed814786f3148d1e54e26e9be10ea332c3058@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:52 +0100
+Subject: [PATCH] conf: Avoid false positive of uninitialized variable use
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+GCC 4.8.0+ whines about variable "new" being uninitialized since
+commit 73bfac0e7182a3abd. This is a false positive as the
+xmlFreeNode(new) statement can be only reached if new was actually
+allocated successfully.
+
+  CC       conf/libvirt_conf_la-domain_conf.lo
+  conf/domain_conf.c: In function 'virDomainDefSetMetadata':
+  conf/domain_conf.c:18650:24: error: 'new' may be used uninitialized in this function [-Werror=maybe-uninitialized]
+               xmlFreeNode(new);
+
+Reported independently by John Ferlan and Michal Privoznik.
+
+(cherry picked from commit 0d4f469c871fb5997bb24f192924163263445980)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index c4829ff..a2c0d6c 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19043,7 +19043,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
+ {
+     xmlDocPtr doc = NULL;
+     xmlNodePtr old;
+-    xmlNodePtr new;
++    xmlNodePtr new = NULL;
+     char *tmp;
+     int ret = -1;
+ 
+@@ -19092,11 +19092,8 @@ virDomainDefSetMetadata(virDomainDefPtr def,
+             xmlFreeNode(old);
+         }
+ 
+-        /* just delete the metadata */
+-        if (!metadata)
+-            break;
+-
+-        if (!(xmlAddChild(def->metadata, new))) {
++        if (new &&
++            !(xmlAddChild(def->metadata, new))) {
+             xmlFreeNode(new);
+             virReportOOMError();
+             goto cleanup;
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-conf-Don-t-corrupt-metadata-on-OOM.patch b/SOURCES/libvirt-conf-Don-t-corrupt-metadata-on-OOM.patch
new file mode 100644
index 0000000..db72519
--- /dev/null
+++ b/SOURCES/libvirt-conf-Don-t-corrupt-metadata-on-OOM.patch
@@ -0,0 +1,55 @@
+From 550637214e4df0cd44d64e83a0e57fc37f470bdb Mon Sep 17 00:00:00 2001
+Message-Id: <550637214e4df0cd44d64e83a0e57fc37f470bdb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:51 +0100
+Subject: [PATCH] conf: Don't corrupt metadata on OOM
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+Eric Blake suggested that we could do a little better in case copying of
+the metadata to be set fails. With this patch, the old metadata is
+discarded after the new string is copied successfuly.
+
+(cherry picked from commit 7655ed0802eecc3d8486a0360d2326ecd052e477)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 4dbe3fc..c4829ff 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19044,19 +19044,24 @@ virDomainDefSetMetadata(virDomainDefPtr def,
+     xmlDocPtr doc = NULL;
+     xmlNodePtr old;
+     xmlNodePtr new;
++    char *tmp;
+     int ret = -1;
+ 
+     switch ((virDomainMetadataType) type) {
+     case VIR_DOMAIN_METADATA_DESCRIPTION:
++        if (VIR_STRDUP(tmp, metadata) < 0)
++            goto cleanup;
++
+         VIR_FREE(def->description);
+-        if (VIR_STRDUP(def->description, metadata) < 0)
+-            goto cleanup;
++        def->description = tmp;
+         break;
+ 
+     case VIR_DOMAIN_METADATA_TITLE:
++        if (VIR_STRDUP(tmp, metadata) < 0)
++            goto cleanup;
++
+         VIR_FREE(def->title);
+-        if (VIR_STRDUP(def->title, metadata) < 0)
+-            goto cleanup;
++        def->title = tmp;
+         break;
+ 
+     case VIR_DOMAIN_METADATA_ELEMENT:
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-conf-Factor-out-setting-of-metadata-to-simplify-code.patch b/SOURCES/libvirt-conf-Factor-out-setting-of-metadata-to-simplify-code.patch
new file mode 100644
index 0000000..36269dc
--- /dev/null
+++ b/SOURCES/libvirt-conf-Factor-out-setting-of-metadata-to-simplify-code.patch
@@ -0,0 +1,167 @@
+From a1871d142620750d21fed3c06053fad60ca3f7c5 Mon Sep 17 00:00:00 2001
+Message-Id: <a1871d142620750d21fed3c06053fad60ca3f7c5@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:41 +0100
+Subject: [PATCH] conf: Factor out setting of metadata to simplify code
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+The code to set the metadata in a domain definition is common to live
+and inactive domains. Factor it out into a common func.
+
+(cherry picked from commit e9cb66f14e19935db16938ebdf1e407103b4de1e)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c | 115 +++++++++++++++++++++++--------------------------
+ 1 file changed, 54 insertions(+), 61 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 7bfb602..6817e0e 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19032,87 +19032,80 @@ cleanup:
+     return ret;
+ }
+ 
+-int
+-virDomainObjSetMetadata(virDomainObjPtr vm,
++
++static int
++virDomainDefSetMetadata(virDomainDefPtr def,
+                         int type,
+                         const char *metadata,
+                         const char *key ATTRIBUTE_UNUSED,
+-                        const char *uri ATTRIBUTE_UNUSED,
++                        const char *uri ATTRIBUTE_UNUSED)
++{
++    int ret = -1;
++
++    switch ((virDomainMetadataType) type) {
++    case VIR_DOMAIN_METADATA_DESCRIPTION:
++        VIR_FREE(def->description);
++        if (VIR_STRDUP(def->description, metadata) < 0)
++            goto cleanup;
++        break;
++
++    case VIR_DOMAIN_METADATA_TITLE:
++        VIR_FREE(def->title);
++        if (VIR_STRDUP(def->title, metadata) < 0)
++            goto cleanup;
++        break;
++
++    case VIR_DOMAIN_METADATA_ELEMENT:
++        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
++                       _("<metadata> element is not supported"));
++        goto cleanup;
++        break;
++
++    default:
++        virReportError(VIR_ERR_INVALID_ARG, "%s",
++                       _("unknown metadata type"));
++        goto cleanup;
++        break;
++    }
++
++    ret = 0;
++
++cleanup:
++    return ret;
++}
++
++
++int
++virDomainObjSetMetadata(virDomainObjPtr vm,
++                        int type,
++                        const char *metadata,
++                        const char *key,
++                        const char *uri,
+                         virCapsPtr caps,
+                         virDomainXMLOptionPtr xmlopt,
+                         const char *configDir,
+                         unsigned int flags)
+ {
+     virDomainDefPtr persistentDef;
+-    int ret = -1;
+ 
+     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+ 
+     if (virDomainLiveConfigHelperMethod(caps, xmlopt, vm, &flags,
+                                         &persistentDef) < 0)
+-        goto cleanup;
++        return -1;
+ 
+-    if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+-        switch ((virDomainMetadataType) type) {
+-        case VIR_DOMAIN_METADATA_DESCRIPTION:
+-            VIR_FREE(vm->def->description);
+-            if (VIR_STRDUP(vm->def->description, metadata) < 0)
+-                goto cleanup;
+-            break;
+-
+-        case VIR_DOMAIN_METADATA_TITLE:
+-            VIR_FREE(vm->def->title);
+-            if (VIR_STRDUP(vm->def->title, metadata) < 0)
+-                goto cleanup;
+-            break;
+-
+-        case VIR_DOMAIN_METADATA_ELEMENT:
+-            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+-                           _("<metadata> element is not supported"));
+-            goto cleanup;
+-            break;
+-
+-        default:
+-            virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                           _("unknown metadata type"));
+-            goto cleanup;
+-            break;
+-        }
+-    }
++    if (flags & VIR_DOMAIN_AFFECT_LIVE)
++        if (virDomainDefSetMetadata(vm->def, type, metadata, key, uri) < 0)
++            return -1;
+ 
+     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+-        switch ((virDomainMetadataType) type) {
+-        case VIR_DOMAIN_METADATA_DESCRIPTION:
+-            VIR_FREE(persistentDef->description);
+-            if (VIR_STRDUP(persistentDef->description, metadata) < 0)
+-                goto cleanup;
+-            break;
+-
+-        case VIR_DOMAIN_METADATA_TITLE:
+-            VIR_FREE(persistentDef->title);
+-            if (VIR_STRDUP(persistentDef->title, metadata) < 0)
+-                goto cleanup;
+-            break;
+-
+-        case VIR_DOMAIN_METADATA_ELEMENT:
+-            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+-                           _("<metadata> element is not supported"));
+-            goto cleanup;
+-
+-         default:
+-            virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                           _("unknown metadata type"));
+-            goto cleanup;
+-            break;
+-        }
++        if (virDomainDefSetMetadata(persistentDef, type, metadata, key, uri) < 0)
++            return -1;
+ 
+         if (virDomainSaveConfig(configDir, persistentDef) < 0)
+-            goto cleanup;
++            return -1;
+     }
+ 
+-    ret = 0;
+-
+-cleanup:
+-    return ret;
++    return 0;
+ }
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-conf-Format-interface-s-driver-more-frequently.patch b/SOURCES/libvirt-conf-Format-interface-s-driver-more-frequently.patch
new file mode 100644
index 0000000..507ffbf
--- /dev/null
+++ b/SOURCES/libvirt-conf-Format-interface-s-driver-more-frequently.patch
@@ -0,0 +1,119 @@
+From 4b31aeaaa431a2a0a85bedf205358c2499a8f35d Mon Sep 17 00:00:00 2001
+Message-Id: <4b31aeaaa431a2a0a85bedf205358c2499a8f35d@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Mon, 19 Jan 2015 12:43:42 +0100
+Subject: [PATCH] conf: Format interface's driver more frequently
+
+RHEL-7.0.z: https://bugzilla.redhat.com/show_bug.cgi?id=1183447
+RHEL-7.1:   https://bugzilla.redhat.com/show_bug.cgi?id=1128751
+
+There's this <driver/> element under <interface/> which can have
+several attributes. However, the driver element is currently formated
+only if the driver's name or txmode has been specified. This makes
+only a little sense as we parse even partial <driver/>, for instance:
+
+    <interface type='user'>
+      <mac address='52:54:00:e5:48:58'/>
+      <model type='virtio'/>
+      <driver ioeventfd='on' event_idx='on' queues='5'/>
+    </interface>
+
+But such XML would never get formatted back.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 3085702b5461d3b0b057c37cf5fbff432244f529)
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c                             |  4 +-
+ .../qemuxml2argv-interface-driver.xml              | 51 ++++++++++++++++++++++
+ tests/qemuxml2xmltest.c                            |  1 +
+ 3 files changed, 55 insertions(+), 1 deletion(-)
+ create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index bb2e7ef..922c5e6 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -15387,7 +15387,9 @@ virDomainNetDefFormat(virBufferPtr buf,
+         virBufferEscapeString(buf, "<model type='%s'/>\n",
+                               def->model);
+         if (STREQ(def->model, "virtio") &&
+-            (def->driver.virtio.name || def->driver.virtio.txmode)) {
++            (def->driver.virtio.name || def->driver.virtio.txmode ||
++             def->driver.virtio.ioeventfd || def->driver.virtio.event_idx ||
++             def->driver.virtio.queues)) {
+             virBufferAddLit(buf, "<driver");
+             if (def->driver.virtio.name) {
+                 virBufferAsprintf(buf, " name='%s'",
+diff --git a/tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml b/tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml
+new file mode 100644
+index 0000000..ec5ab61
+--- /dev/null
++++ b/tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml
+@@ -0,0 +1,51 @@
++<domain type='qemu'>
++  <name>test</name>
++  <uuid>15d091de-0181-456b-9554-e4382dc1f1ab</uuid>
++  <memory unit='KiB'>1048576</memory>
++  <currentMemory unit='KiB'>1048576</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc-0.13'>hvm</type>
++    <boot dev='cdrom'/>
++    <boot dev='hd'/>
++    <bootmenu enable='yes'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>restart</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu</emulator>
++    <disk type='file' device='disk'>
++      <driver name='qemu' type='qcow2' event_idx='on'/>
++      <source file='/var/lib/libvirt/images/f14.img'/>
++      <target dev='vda' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
++    </disk>
++    <disk type='file' device='cdrom'>
++      <driver name='qemu' type='raw'/>
++      <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/>
++      <target dev='hdc' bus='ide'/>
++      <readonly/>
++      <address type='drive' controller='0' bus='1' target='0' unit='0'/>
++    </disk>
++    <controller type='usb' index='0'/>
++    <controller type='virtio-serial' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
++    </controller>
++    <controller type='ide' index='0'/>
++    <controller type='pci' index='0' model='pci-root'/>
++    <interface type='user'>
++      <mac address='52:54:00:e5:48:58'/>
++      <model type='virtio'/>
++      <driver ioeventfd='on' event_idx='on' queues='5'/>
++    </interface>
++    <serial type='pty'>
++      <target port='0'/>
++    </serial>
++    <console type='pty'>
++      <target type='serial' port='0'/>
++    </console>
++    <memballoon model='virtio'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index d16fdc3..11ac108 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -255,6 +255,7 @@ mymain(void)
+     DO_TEST("lease");
+     DO_TEST("event_idx");
+     DO_TEST("vhost_queues");
++    DO_TEST("interface-driver");
+     DO_TEST("virtio-lun");
+ 
+     DO_TEST("usb-redir");
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-conf-Improve-metadata-type-verification.patch b/SOURCES/libvirt-conf-Improve-metadata-type-verification.patch
new file mode 100644
index 0000000..1e32669
--- /dev/null
+++ b/SOURCES/libvirt-conf-Improve-metadata-type-verification.patch
@@ -0,0 +1,78 @@
+From be61ac8742d24a170a83340b576dbb39635133f6 Mon Sep 17 00:00:00 2001
+Message-Id: <be61ac8742d24a170a83340b576dbb39635133f6@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:55 +0100
+Subject: [PATCH] conf: Improve metadata type verification
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+Split out checking of invalid metadata type from the switch statement so
+that we can use the typecasted enum value to allow tracking addition of
+new items by the compliler.
+
+Also avoids two dead-code break statements.
+
+(cherry picked from commit 3738166603b2ab11ae30061381f378679b767758)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 36b9ba7..47942ff 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -18995,6 +18995,12 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
+     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+                   VIR_DOMAIN_AFFECT_CONFIG, NULL);
+ 
++    if (type >= VIR_DOMAIN_METADATA_LAST) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("unknown metadata type '%d'"), type);
++        goto cleanup;
++    }
++
+     if (virDomainLiveConfigHelperMethod(caps, xmlopt, vm, &flags, &def) < 0)
+         goto cleanup;
+ 
+@@ -19021,10 +19027,7 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
+             goto cleanup;
+         break;
+ 
+-    default:
+-        virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                       _("unknown metadata type"));
+-        goto cleanup;
++    case VIR_DOMAIN_METADATA_LAST:
+         break;
+     }
+ 
+@@ -19050,6 +19053,12 @@ virDomainDefSetMetadata(virDomainDefPtr def,
+     char *tmp;
+     int ret = -1;
+ 
++    if (type >= VIR_DOMAIN_METADATA_LAST) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("unknown metadata type '%d'"), type);
++        goto cleanup;
++    }
++
+     switch ((virDomainMetadataType) type) {
+     case VIR_DOMAIN_METADATA_DESCRIPTION:
+         if (VIR_STRDUP(tmp, metadata) < 0)
+@@ -19103,10 +19112,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
+         }
+         break;
+ 
+-    default:
+-        virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                       _("unknown metadata type"));
+-        goto cleanup;
++    case VIR_DOMAIN_METADATA_LAST:
+         break;
+     }
+ 
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-conf-allow-to-add-XML-metadata-using-the-virDomainSetMetadata-api.patch b/SOURCES/libvirt-conf-allow-to-add-XML-metadata-using-the-virDomainSetMetadata-api.patch
new file mode 100644
index 0000000..34ae64a
--- /dev/null
+++ b/SOURCES/libvirt-conf-allow-to-add-XML-metadata-using-the-virDomainSetMetadata-api.patch
@@ -0,0 +1,150 @@
+From febb8d0b48c7a7bf7b587bc43d7e423318f49369 Mon Sep 17 00:00:00 2001
+Message-Id: <febb8d0b48c7a7bf7b587bc43d7e423318f49369@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:46 +0100
+Subject: [PATCH] conf: allow to add XML metadata using the
+ virDomainSetMetadata api
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+The functionality wasn't originally implemented. This patch adds the
+ability to modify domain's XML metadata using the API.
+
+(cherry picked from commit 73bfac0e7182a3abde02304fd2f17845715a9a2e)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
+ src/util/virxml.c      | 32 ++++++++++++++++++++++++++++++++
+ src/util/virxml.h      |  4 ++++
+ 3 files changed, 78 insertions(+), 5 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index c104218..4dbe3fc 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19038,9 +19038,12 @@ static int
+ virDomainDefSetMetadata(virDomainDefPtr def,
+                         int type,
+                         const char *metadata,
+-                        const char *key ATTRIBUTE_UNUSED,
+-                        const char *uri ATTRIBUTE_UNUSED)
++                        const char *key,
++                        const char *uri)
+ {
++    xmlDocPtr doc = NULL;
++    xmlNodePtr old;
++    xmlNodePtr new;
+     int ret = -1;
+ 
+     switch ((virDomainMetadataType) type) {
+@@ -19057,9 +19060,42 @@ virDomainDefSetMetadata(virDomainDefPtr def,
+         break;
+ 
+     case VIR_DOMAIN_METADATA_ELEMENT:
+-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+-                       _("<metadata> element is not supported"));
+-        goto cleanup;
++        if (metadata) {
++            /* parse and modify the xml from the user */
++            if (!(doc = virXMLParseString(metadata, _("(metadata_xml)"))))
++                goto cleanup;
++
++            if (virXMLInjectNamespace(doc->children, uri, key) < 0)
++                goto cleanup;
++
++            /* create the root node if needed */
++            if (!def->metadata &&
++                !(def->metadata = xmlNewNode(NULL, (unsigned char *)"metadata"))) {
++                virReportOOMError();
++                goto cleanup;
++            }
++
++            if (!(new = xmlCopyNode(doc->children, 1))) {
++                virReportOOMError();
++                goto cleanup;
++            }
++        }
++
++        /* remove possible other nodes sharing the namespace */
++        while ((old = virXMLFindChildNodeByNs(def->metadata, uri))) {
++            xmlUnlinkNode(old);
++            xmlFreeNode(old);
++        }
++
++        /* just delete the metadata */
++        if (!metadata)
++            break;
++
++        if (!(xmlAddChild(def->metadata, new))) {
++            xmlFreeNode(new);
++            virReportOOMError();
++            goto cleanup;
++        }
+         break;
+ 
+     default:
+@@ -19072,6 +19108,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
+     ret = 0;
+ 
+ cleanup:
++    xmlFreeDoc(doc);
+     return ret;
+ }
+ 
+diff --git a/src/util/virxml.c b/src/util/virxml.c
+index 9048d78..de1e1e0 100644
+--- a/src/util/virxml.c
++++ b/src/util/virxml.c
+@@ -1050,3 +1050,35 @@ cleanup:
+     xmlFreeNode(nodeCopy);
+     return ret;
+ }
++
++
++static int
++virXMLAddElementNamespace(xmlNodePtr node,
++                          void *opaque)
++{
++    xmlNsPtr ns = opaque;
++
++    if (!node->ns)
++        xmlSetNs(node, ns);
++
++    return 0;
++}
++
++
++int
++virXMLInjectNamespace(xmlNodePtr node,
++                      const char *uri,
++                      const char *key)
++{
++    xmlNsPtr ns;
++
++    if (!(ns = xmlNewNs(node, (const unsigned char *)uri, (const unsigned char *)key))) {
++        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                       _("failed to create a new XML namespace"));
++        return -1;
++    }
++
++    virXMLForeachNode(node, virXMLAddElementNamespace, ns);
++
++    return 0;
++}
+diff --git a/src/util/virxml.h b/src/util/virxml.h
+index 7dc6c9d..d967a2e 100644
+--- a/src/util/virxml.h
++++ b/src/util/virxml.h
+@@ -172,4 +172,8 @@ int virXMLExtractNamespaceXML(xmlNodePtr root,
+                               const char *uri,
+                               char **doc);
+ 
++int virXMLInjectNamespace(xmlNodePtr node,
++                          const char *uri,
++                          const char *key);
++
+ #endif                          /* __VIR_XML_H__ */
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-cpu_x86-Resolve-Coverity-RESOURCE_LEAK.patch b/SOURCES/libvirt-cpu_x86-Resolve-Coverity-RESOURCE_LEAK.patch
new file mode 100644
index 0000000..954d8af
--- /dev/null
+++ b/SOURCES/libvirt-cpu_x86-Resolve-Coverity-RESOURCE_LEAK.patch
@@ -0,0 +1,63 @@
+From 495bf507eaf0eab638d3cf89a8854d23824b319e Mon Sep 17 00:00:00 2001
+Message-Id: <495bf507eaf0eab638d3cf89a8854d23824b319e@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Wed, 27 Aug 2014 14:27:07 -0400
+Subject: [PATCH] cpu_x86: Resolve Coverity RESOURCE_LEAK
+
+Coverity determined that the copied 'oldguest' would be leaked for
+both error and success paths.
+
+(cherry picked from commit be7b82a283bc789da6cf9edc413ea399636b97b8)
+https://bugzilla.redhat.com/show_bug.cgi?id=1185458
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu/cpu_x86.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
+index 7bd8acb..4e77550 100644
+--- a/src/cpu/cpu_x86.c
++++ b/src/cpu/cpu_x86.c
+@@ -1940,8 +1940,9 @@ static int
+ x86UpdateHostModel(virCPUDefPtr guest,
+                    const virCPUDefPtr host)
+ {
+-    virCPUDefPtr oldguest;
++    virCPUDefPtr oldguest = NULL;
+     size_t i;
++    int ret = -1;
+ 
+     guest->match = VIR_CPU_MATCH_EXACT;
+ 
+@@ -1953,20 +1954,24 @@ x86UpdateHostModel(virCPUDefPtr guest,
+ 
+     /* update the host model according to the desired configuration */
+     if (!(oldguest = virCPUDefCopy(guest)))
+-        return -1;
++        goto cleanup;
+ 
+     virCPUDefFreeModel(guest);
+     if (virCPUDefCopyModel(guest, host, true) < 0)
+-        return -1;
++        goto cleanup;
+ 
+     for (i = 0; i < oldguest->nfeatures; i++) {
+         if (virCPUDefUpdateFeature(guest,
+                                    oldguest->features[i].name,
+                                    oldguest->features[i].policy) < 0)
+-            return -1;
++            goto cleanup;
+     }
+ 
+-    return 0;
++    ret = 0;
++
++ cleanup:
++    virCPUDefFree(oldguest);
++    return ret;
+ }
+ 
+ 
+-- 
+2.2.2
+
diff --git a/SOURCES/libvirt-lib-Don-t-force-the-key-argument-when-deleting-metadata.patch b/SOURCES/libvirt-lib-Don-t-force-the-key-argument-when-deleting-metadata.patch
new file mode 100644
index 0000000..b09e714
--- /dev/null
+++ b/SOURCES/libvirt-lib-Don-t-force-the-key-argument-when-deleting-metadata.patch
@@ -0,0 +1,38 @@
+From b0a82f4abc9f4de3db965c84b926322846588278 Mon Sep 17 00:00:00 2001
+Message-Id: <b0a82f4abc9f4de3db965c84b926322846588278@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:47 +0100
+Subject: [PATCH] lib: Don't force the key argument when deleting metadata
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+virDomainSetMetadata when operating on the metadata element was
+requesting the @key argument to be passed even if @metadata was NULL
+used to delete the corresponding metadata element. This is not needed as
+the key is only used when adding the element and matching is done via
+the XML namespace.
+
+(cherry picked from commit 3b6784d119074e3be8861cc4c30630f299bde121)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/libvirt.c b/src/libvirt.c
+index cbcc24b..874304f 100644
+--- a/src/libvirt.c
++++ b/src/libvirt.c
+@@ -10812,7 +10812,8 @@ virDomainSetMetadata(virDomainPtr domain,
+         break;
+     case VIR_DOMAIN_METADATA_ELEMENT:
+         virCheckNonNullArgGoto(uri, error);
+-        virCheckNonNullArgGoto(key, error);
++        if (metadata)
++            virCheckNonNullArgGoto(key, error);
+         break;
+     default:
+         /* For future expansion */
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-lxc-Add-metadata-modification-APIs.patch b/SOURCES/libvirt-lxc-Add-metadata-modification-APIs.patch
new file mode 100644
index 0000000..5e90396
--- /dev/null
+++ b/SOURCES/libvirt-lxc-Add-metadata-modification-APIs.patch
@@ -0,0 +1,106 @@
+From 9c171ebceeed9cf28f0e86e0de604805e3669bdf Mon Sep 17 00:00:00 2001
+Message-Id: <9c171ebceeed9cf28f0e86e0de604805e3669bdf@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:48 +0100
+Subject: [PATCH] lxc: Add metadata modification APIs
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+(cherry picked from commit f9c7b32e5de3fb0ccf2e0858716886bdb35a9913)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/lxc/lxc_driver.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 70 insertions(+)
+
+diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
+index 1aaa6e7..e9f2f51 100644
+--- a/src/lxc/lxc_driver.c
++++ b/src/lxc/lxc_driver.c
+@@ -4702,6 +4702,74 @@ lxcNodeSuspendForDuration(virConnectPtr conn,
+ }
+ 
+ 
++static int
++lxcDomainSetMetadata(virDomainPtr dom,
++                      int type,
++                      const char *metadata,
++                      const char *key,
++                      const char *uri,
++                      unsigned int flags)
++{
++    virLXCDriverPtr driver = dom->conn->privateData;
++    virDomainObjPtr vm;
++    virLXCDriverConfigPtr cfg = NULL;
++    virCapsPtr caps = NULL;
++    int ret = -1;
++
++    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
++                  VIR_DOMAIN_AFFECT_CONFIG, -1);
++
++    if (!(vm = lxcDomObjFromDomain(dom)))
++        return -1;
++
++    cfg = virLXCDriverGetConfig(driver);
++
++    if (virDomainSetMetadataEnsureACL(dom->conn, vm->def, flags) < 0)
++        goto cleanup;
++
++    if (!(caps = virLXCDriverGetCapabilities(driver, false)))
++        goto cleanup;
++
++    ret = virDomainObjSetMetadata(vm, type, metadata, key, uri, caps,
++                                  driver->xmlopt, cfg->configDir, flags);
++
++cleanup:
++    virObjectUnlock(vm);
++    virObjectUnref(caps);
++    virObjectUnref(cfg);
++    return ret;
++}
++
++
++static char *
++lxcDomainGetMetadata(virDomainPtr dom,
++                      int type,
++                      const char *uri,
++                      unsigned int flags)
++{
++    virLXCDriverPtr driver = dom->conn->privateData;
++    virCapsPtr caps = NULL;
++    virDomainObjPtr vm;
++    char *ret = NULL;
++
++    if (!(vm = lxcDomObjFromDomain(dom)))
++        return NULL;
++
++    if (virDomainGetMetadataEnsureACL(dom->conn, vm->def) < 0)
++        goto cleanup;
++
++    if (!(caps = virLXCDriverGetCapabilities(driver, false)))
++        goto cleanup;
++
++    ret = virDomainObjGetMetadata(vm, type, uri, caps, driver->xmlopt, flags);
++
++cleanup:
++    virObjectUnlock(vm);
++    virObjectUnref(caps);
++    return ret;
++}
++
++
+ /* Function Tables */
+ static virDriver lxcDriver = {
+     .no = VIR_DRV_LXC,
+@@ -4776,6 +4844,8 @@ static virDriver lxcDriver = {
+     .domainOpenConsole = lxcDomainOpenConsole, /* 0.8.6 */
+     .connectIsAlive = lxcConnectIsAlive, /* 0.9.8 */
+     .nodeSuspendForDuration = lxcNodeSuspendForDuration, /* 0.9.8 */
++    .domainSetMetadata = lxcDomainSetMetadata, /* 1.1.3 */
++    .domainGetMetadata = lxcDomainGetMetadata, /* 1.1.3 */
+     .nodeGetMemoryParameters = lxcNodeGetMemoryParameters, /* 0.10.2 */
+     .nodeSetMemoryParameters = lxcNodeSetMemoryParameters, /* 0.10.2 */
+     .domainSendProcessSignal = lxcDomainSendProcessSignal, /* 1.0.1 */
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-man-virsh-Add-man-page-for-virsh-metadata.patch b/SOURCES/libvirt-man-virsh-Add-man-page-for-virsh-metadata.patch
new file mode 100644
index 0000000..ac833d1
--- /dev/null
+++ b/SOURCES/libvirt-man-virsh-Add-man-page-for-virsh-metadata.patch
@@ -0,0 +1,62 @@
+From 715a29642aaedc6b19b451677cb02658d5924b7f Mon Sep 17 00:00:00 2001
+Message-Id: <715a29642aaedc6b19b451677cb02658d5924b7f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 28 Jan 2015 10:33:39 +0100
+Subject: [PATCH] man: virsh: Add man page for "virsh metadata"
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+Patch adding the command forgot to add the man page entry.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1130379
+(cherry picked from commit 992318cbee83dc381c44acfdfdecfb2607279e25)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tools/virsh.pod | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/tools/virsh.pod b/tools/virsh.pod
+index f1b09d9..c3ae204 100644
+--- a/tools/virsh.pod
++++ b/tools/virsh.pod
+@@ -1073,6 +1073,36 @@ I<--total> for only the total stats, I<start> for only the per-cpu
+ stats of the CPUs from I<start>, I<count> for only I<count> CPUs'
+ stats.
+ 
++=item B<metadata> I<domain> [[I<--live>] [I<--config>] | [I<--current>]]
++[I<--edit>] [I<uri>] [I<key>] [I<set>] [I<--remove>]
++
++Show or modify custom XML metadata of a domain. The metadata is a user
++defined XML that allows to store arbitrary XML data in the domain definition.
++Multiple separate custom metadata pieces can be stored in the domain XML.
++The pieces are identified by a private XML namespace provided via the
++I<uri> argument.
++
++Flags I<--live> or I<--config> select whether this command works on live
++or persistent definitions of the domain. If both I<--live> and I<--config>
++are specified, the I<--config> option takes precedence on getting the current
++description and both live configuration and config are updated while setting
++the description. I<--current> is exclusive and implied if none of these was
++specified.
++
++Flag I<--remove> specifies that the metadata element specified by the I<uri>
++argument should be removed rather than updated.
++
++Flag I<--edit> specifies that an editor with the metadata identified by the
++I<uri> argument should be opened and the contents saved back afterwards.
++Otherwise the new contents can be provided via the I<set> argument.
++
++When setting metadata via I<--edit> or I<set> the I<key> argument must be
++specified and is used to prefix the custom elements to bind them
++to the private namespace.
++
++If neither of I<--edit> and I<set> are specified the XML metadata corresponding
++to the I<uri> namespace is displayed instead of being modified.
++
+ =item B<migrate> [I<--live>] [I<--offline>] [I<--direct>] [I<--p2p> [I<--tunnelled>]]
+ [I<--persistent>] [I<--undefinesource>] [I<--suspend>] [I<--copy-storage-all>]
+ [I<--copy-storage-inc>] [I<--change-protection>] [I<--unsafe>] [I<--verbose>]
+-- 
+2.2.2
+
diff --git a/SOURCES/libvirt-metadata-track-title-edits-across-libvirtd-restart.patch b/SOURCES/libvirt-metadata-track-title-edits-across-libvirtd-restart.patch
new file mode 100644
index 0000000..bcb0f33
--- /dev/null
+++ b/SOURCES/libvirt-metadata-track-title-edits-across-libvirtd-restart.patch
@@ -0,0 +1,135 @@
+From d60a5ab6fd5ba1ef21687eb995c7c2c2ffbd892c Mon Sep 17 00:00:00 2001
+Message-Id: <d60a5ab6fd5ba1ef21687eb995c7c2c2ffbd892c@dist-git>
+From: Eric Blake <eblake@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:54 +0100
+Subject: [PATCH] metadata: track title edits across libvirtd restart
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+https://bugzilla.redhat.com/show_bug.cgi?id=1122205
+
+Although the edits were changing in-memory XML, it was not flushed
+to disk; so unless some other action changes XML, a libvirtd restart
+would lose the changed information.
+
+* src/conf/domain_conf.c (virDomainObjSetMetadata): Add parameter,
+to save live status across restarts.
+(virDomainSaveXML): Allow for test driver.
+* src/conf/domain_conf.h (virDomainObjSetMetadata): Adjust
+signature.
+* src/bhyve/bhyve_driver.c (bhyveDomainSetMetadata): Adjust caller.
+* src/lxc/lxc_driver.c (lxcDomainSetMetadata): Likewise.
+* src/qemu/qemu_driver.c (qemuDomainSetMetadata): Likewise.
+* src/test/test_driver.c (testDomainSetMetadata): Likewise.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 60e49440598b4aeb4a32bf23bfa5ed85672cbd6a)
+
+Conflicts:
+	src/bhyve/bhyve_driver.c - bhyve driver is missing
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c | 13 +++++++++++--
+ src/conf/domain_conf.h |  1 +
+ src/lxc/lxc_driver.c   |  3 ++-
+ src/qemu/qemu_driver.c |  3 ++-
+ src/test/test_driver.c |  2 +-
+ 5 files changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index a2c0d6c..36b9ba7 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -17491,6 +17491,9 @@ virDomainSaveXML(const char *configDir,
+     char *configFile = NULL;
+     int ret = -1;
+ 
++    if (!configDir)
++        return 0;
++
+     if ((configFile = virDomainConfigFile(configDir, def->name)) == NULL)
+         goto cleanup;
+ 
+@@ -19123,6 +19126,7 @@ virDomainObjSetMetadata(virDomainObjPtr vm,
+                         const char *uri,
+                         virCapsPtr caps,
+                         virDomainXMLOptionPtr xmlopt,
++                        const char *stateDir,
+                         const char *configDir,
+                         unsigned int flags)
+ {
+@@ -19135,12 +19139,17 @@ virDomainObjSetMetadata(virDomainObjPtr vm,
+                                         &persistentDef) < 0)
+         return -1;
+ 
+-    if (flags & VIR_DOMAIN_AFFECT_LIVE)
++    if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+         if (virDomainDefSetMetadata(vm->def, type, metadata, key, uri) < 0)
+             return -1;
+ 
++        if (virDomainSaveStatus(xmlopt, stateDir, vm) < 0)
++            return -1;
++    }
++
+     if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+-        if (virDomainDefSetMetadata(persistentDef, type, metadata, key, uri) < 0)
++        if (virDomainDefSetMetadata(persistentDef, type, metadata, key,
++                                    uri) < 0)
+             return -1;
+ 
+         if (virDomainSaveConfig(configDir, persistentDef) < 0)
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index eaeea03..ef64d88 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -2785,6 +2785,7 @@ int virDomainObjSetMetadata(virDomainObjPtr vm,
+                             const char *uri,
+                             virCapsPtr caps,
+                             virDomainXMLOptionPtr xmlopt,
++                            const char *stateDir,
+                             const char *configDir,
+                             unsigned int flags);
+ 
+diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
+index e9f2f51..c47a206 100644
+--- a/src/lxc/lxc_driver.c
++++ b/src/lxc/lxc_driver.c
+@@ -4731,7 +4731,8 @@ lxcDomainSetMetadata(virDomainPtr dom,
+         goto cleanup;
+ 
+     ret = virDomainObjSetMetadata(vm, type, metadata, key, uri, caps,
+-                                  driver->xmlopt, cfg->configDir, flags);
++                                  driver->xmlopt, cfg->stateDir,
++                                  cfg->configDir, flags);
+ 
+ cleanup:
+     virObjectUnlock(vm);
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 57583e8..2ee3582 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15887,7 +15887,8 @@ qemuDomainSetMetadata(virDomainPtr dom,
+         goto cleanup;
+ 
+     ret = virDomainObjSetMetadata(vm, type, metadata, key, uri, caps,
+-                                  driver->xmlopt, cfg->configDir, flags);
++                                  driver->xmlopt, cfg->stateDir,
++                                  cfg->configDir, flags);
+ 
+ cleanup:
+     virObjectUnlock(vm);
+diff --git a/src/test/test_driver.c b/src/test/test_driver.c
+index 4d23738..e398130 100644
+--- a/src/test/test_driver.c
++++ b/src/test/test_driver.c
+@@ -2585,7 +2585,7 @@ static int testDomainSetMetadata(virDomainPtr dom,
+ 
+     ret = virDomainObjSetMetadata(privdom, type, metadata, key, uri,
+                                   privconn->caps, privconn->xmlopt,
+-                                  NULL, flags);
++                                  NULL, NULL, flags);
+ 
+ cleanup:
+     if (privdom)
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-qemu-Factor-out-body-of-qemuDomainGetMetadata-for-universal-use.patch b/SOURCES/libvirt-qemu-Factor-out-body-of-qemuDomainGetMetadata-for-universal-use.patch
new file mode 100644
index 0000000..8d58e49
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Factor-out-body-of-qemuDomainGetMetadata-for-universal-use.patch
@@ -0,0 +1,196 @@
+From 135eeb60e3d7b1cda9f48bdd38542bb3c06e2638 Mon Sep 17 00:00:00 2001
+Message-Id: <135eeb60e3d7b1cda9f48bdd38542bb3c06e2638@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:39 +0100
+Subject: [PATCH] qemu: Factor out body of qemuDomainGetMetadata for universal
+ use
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+The function implemented common behavior that can be reused for other
+hypervisor drivers that use the virDomainObj data structures. Factor out
+the core into a separate helper func.
+
+(cherry picked from commit 99c51af2ee42de980c258ecb52cf20f96c69ff83)
+
+Conflicts:
+	src/conf/domain_conf.h - context
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c   | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/conf/domain_conf.h   |  7 ++++++
+ src/libvirt_private.syms |  1 +
+ src/qemu/qemu_driver.c   | 49 +++++-------------------------------------
+ 4 files changed, 68 insertions(+), 44 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 922c5e6..b052924 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -18976,3 +18976,58 @@ virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def)
+     }
+     return false;
+ }
++
++
++char *
++virDomainObjGetMetadata(virDomainObjPtr vm,
++                        int type,
++                        const char *uri ATTRIBUTE_UNUSED,
++                        virCapsPtr caps,
++                        virDomainXMLOptionPtr xmlopt,
++                        unsigned int flags)
++{
++    virDomainDefPtr def;
++    char *field = NULL;
++    char *ret = NULL;
++
++    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
++                  VIR_DOMAIN_AFFECT_CONFIG, NULL);
++
++    if (virDomainLiveConfigHelperMethod(caps, xmlopt, vm, &flags, &def) < 0)
++        goto cleanup;
++
++    /* use correct domain definition according to flags */
++    if (flags & VIR_DOMAIN_AFFECT_LIVE)
++        def = vm->def;
++
++    switch ((virDomainMetadataType) type) {
++    case VIR_DOMAIN_METADATA_DESCRIPTION:
++        field = def->description;
++        break;
++
++    case VIR_DOMAIN_METADATA_TITLE:
++        field = def->title;
++        break;
++
++    case VIR_DOMAIN_METADATA_ELEMENT:
++        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
++                       _("<metadata> element is not yet supported"));
++        goto cleanup;
++        break;
++
++    default:
++        virReportError(VIR_ERR_INVALID_ARG, "%s",
++                       _("unknown metadata type"));
++        goto cleanup;
++        break;
++    }
++
++    if (!field)
++        virReportError(VIR_ERR_NO_DOMAIN_METADATA, "%s",
++                       _("Requested metadata element is not present"));
++
++    ignore_value(VIR_STRDUP(ret, field));
++
++cleanup:
++    return ret;
++}
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 00e66ae..08c677f 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -2771,4 +2771,11 @@ int virDomainDefFindDevice(virDomainDefPtr def,
+ bool virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def)
+     ATTRIBUTE_NONNULL(1);
+ 
++char *virDomainObjGetMetadata(virDomainObjPtr vm,
++                              int type,
++                              const char *uri,
++                              virCapsPtr caps,
++                              virDomainXMLOptionPtr xmlopt,
++                              unsigned int flags);
++
+ #endif /* __DOMAIN_CONF_H */
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 5cf7039..40007e1 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -313,6 +313,7 @@ virDomainNostateReasonTypeFromString;
+ virDomainNostateReasonTypeToString;
+ virDomainObjAssignDef;
+ virDomainObjCopyPersistentDef;
++virDomainObjGetMetadata;
+ virDomainObjGetPersistentDef;
+ virDomainObjGetState;
+ virDomainObjListAdd;
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index b0d4f33..3beed9a 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15958,21 +15958,16 @@ cleanup:
+ static char *
+ qemuDomainGetMetadata(virDomainPtr dom,
+                       int type,
+-                      const char *uri ATTRIBUTE_UNUSED,
++                      const char *uri,
+                       unsigned int flags)
+ {
+     virQEMUDriverPtr driver = dom->conn->privateData;
++    virCapsPtr caps = NULL;
+     virDomainObjPtr vm;
+-    virDomainDefPtr def;
+     char *ret = NULL;
+-    char *field = NULL;
+-    virCapsPtr caps = NULL;
+-
+-    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+-                  VIR_DOMAIN_AFFECT_CONFIG, NULL);
+ 
+     if (!(vm = qemuDomObjFromDomain(dom)))
+-        goto cleanup;
++        return NULL;
+ 
+     if (virDomainGetMetadataEnsureACL(dom->conn, vm->def) < 0)
+         goto cleanup;
+@@ -15980,44 +15975,10 @@ qemuDomainGetMetadata(virDomainPtr dom,
+     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+         goto cleanup;
+ 
+-    if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt, vm, &flags, &def) < 0)
+-        goto cleanup;
+-
+-    /* use correct domain definition according to flags */
+-    if (flags & VIR_DOMAIN_AFFECT_LIVE)
+-        def = vm->def;
+-
+-    switch ((virDomainMetadataType) type) {
+-    case VIR_DOMAIN_METADATA_DESCRIPTION:
+-        field = def->description;
+-        break;
+-    case VIR_DOMAIN_METADATA_TITLE:
+-        field = def->title;
+-        break;
+-    case VIR_DOMAIN_METADATA_ELEMENT:
+-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+-                       _("QEMU driver does not support "
+-                         "<metadata> element"));
+-        goto cleanup;
+-        break;
+-    default:
+-        virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                       _("unknown metadata type"));
+-        goto cleanup;
+-        break;
+-    }
+-
+-    if (!field) {
+-        virReportError(VIR_ERR_NO_DOMAIN_METADATA, "%s",
+-                       _("Requested metadata element is not present"));
+-        goto cleanup;
+-    }
+-
+-    ignore_value(VIR_STRDUP(ret, field));
++    ret = virDomainObjGetMetadata(vm, type, uri, caps, driver->xmlopt, flags);
+ 
+ cleanup:
+-    if (vm)
+-        virObjectUnlock(vm);
++    virObjectUnlock(vm);
+     virObjectUnref(caps);
+     return ret;
+ }
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-qemu-Factor-out-body-of-qemuDomainSetMetadata-for-universal-use.patch b/SOURCES/libvirt-qemu-Factor-out-body-of-qemuDomainSetMetadata-for-universal-use.patch
new file mode 100644
index 0000000..90df9d5
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Factor-out-body-of-qemuDomainSetMetadata-for-universal-use.patch
@@ -0,0 +1,254 @@
+From eff5466a6e7ca4c5b324e091c2be00e8fa71a338 Mon Sep 17 00:00:00 2001
+Message-Id: <eff5466a6e7ca4c5b324e091c2be00e8fa71a338@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:40 +0100
+Subject: [PATCH] qemu: Factor out body of qemuDomainSetMetadata for universal
+ use
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+The function implemented common behavior that can be reused for other
+hypervisor drivers that use the virDomainObj data structures. Factor out
+the core into a separate helper func.
+
+(cherry picked from commit f87a7c67de946f941fddde44d5959baaac6c7de4)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c   | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/conf/domain_conf.h   | 10 ++++++
+ src/libvirt_private.syms |  1 +
+ src/qemu/qemu_driver.c   | 73 ++++-------------------------------------
+ 4 files changed, 103 insertions(+), 66 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index b052924..7bfb602 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -19031,3 +19031,88 @@ virDomainObjGetMetadata(virDomainObjPtr vm,
+ cleanup:
+     return ret;
+ }
++
++int
++virDomainObjSetMetadata(virDomainObjPtr vm,
++                        int type,
++                        const char *metadata,
++                        const char *key ATTRIBUTE_UNUSED,
++                        const char *uri ATTRIBUTE_UNUSED,
++                        virCapsPtr caps,
++                        virDomainXMLOptionPtr xmlopt,
++                        const char *configDir,
++                        unsigned int flags)
++{
++    virDomainDefPtr persistentDef;
++    int ret = -1;
++
++    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
++                  VIR_DOMAIN_AFFECT_CONFIG, -1);
++
++    if (virDomainLiveConfigHelperMethod(caps, xmlopt, vm, &flags,
++                                        &persistentDef) < 0)
++        goto cleanup;
++
++    if (flags & VIR_DOMAIN_AFFECT_LIVE) {
++        switch ((virDomainMetadataType) type) {
++        case VIR_DOMAIN_METADATA_DESCRIPTION:
++            VIR_FREE(vm->def->description);
++            if (VIR_STRDUP(vm->def->description, metadata) < 0)
++                goto cleanup;
++            break;
++
++        case VIR_DOMAIN_METADATA_TITLE:
++            VIR_FREE(vm->def->title);
++            if (VIR_STRDUP(vm->def->title, metadata) < 0)
++                goto cleanup;
++            break;
++
++        case VIR_DOMAIN_METADATA_ELEMENT:
++            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
++                           _("<metadata> element is not supported"));
++            goto cleanup;
++            break;
++
++        default:
++            virReportError(VIR_ERR_INVALID_ARG, "%s",
++                           _("unknown metadata type"));
++            goto cleanup;
++            break;
++        }
++    }
++
++    if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
++        switch ((virDomainMetadataType) type) {
++        case VIR_DOMAIN_METADATA_DESCRIPTION:
++            VIR_FREE(persistentDef->description);
++            if (VIR_STRDUP(persistentDef->description, metadata) < 0)
++                goto cleanup;
++            break;
++
++        case VIR_DOMAIN_METADATA_TITLE:
++            VIR_FREE(persistentDef->title);
++            if (VIR_STRDUP(persistentDef->title, metadata) < 0)
++                goto cleanup;
++            break;
++
++        case VIR_DOMAIN_METADATA_ELEMENT:
++            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
++                           _("<metadata> element is not supported"));
++            goto cleanup;
++
++         default:
++            virReportError(VIR_ERR_INVALID_ARG, "%s",
++                           _("unknown metadata type"));
++            goto cleanup;
++            break;
++        }
++
++        if (virDomainSaveConfig(configDir, persistentDef) < 0)
++            goto cleanup;
++    }
++
++    ret = 0;
++
++cleanup:
++    return ret;
++}
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 08c677f..eaeea03 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -2778,4 +2778,14 @@ char *virDomainObjGetMetadata(virDomainObjPtr vm,
+                               virDomainXMLOptionPtr xmlopt,
+                               unsigned int flags);
+ 
++int virDomainObjSetMetadata(virDomainObjPtr vm,
++                            int type,
++                            const char *metadata,
++                            const char *key,
++                            const char *uri,
++                            virCapsPtr caps,
++                            virDomainXMLOptionPtr xmlopt,
++                            const char *configDir,
++                            unsigned int flags);
++
+ #endif /* __DOMAIN_CONF_H */
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 40007e1..61d8d26 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -331,6 +331,7 @@ virDomainObjListRemove;
+ virDomainObjListRemoveLocked;
+ virDomainObjNew;
+ virDomainObjSetDefTransient;
++virDomainObjSetMetadata;
+ virDomainObjSetState;
+ virDomainObjTaint;
+ virDomainPausedReasonTypeFromString;
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 3beed9a..57583e8 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15862,22 +15862,21 @@ static int
+ qemuDomainSetMetadata(virDomainPtr dom,
+                       int type,
+                       const char *metadata,
+-                      const char *key ATTRIBUTE_UNUSED,
+-                      const char *uri ATTRIBUTE_UNUSED,
++                      const char *key,
++                      const char *uri,
+                       unsigned int flags)
+ {
+     virQEMUDriverPtr driver = dom->conn->privateData;
+     virDomainObjPtr vm;
+-    virDomainDefPtr persistentDef;
+-    int ret = -1;
+     virQEMUDriverConfigPtr cfg = NULL;
+     virCapsPtr caps = NULL;
++    int ret = -1;
+ 
+     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+ 
+     if (!(vm = qemuDomObjFromDomain(dom)))
+-        goto cleanup;
++        return -1;
+ 
+     cfg = virQEMUDriverGetConfig(driver);
+ 
+@@ -15887,69 +15886,11 @@ qemuDomainSetMetadata(virDomainPtr dom,
+     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+         goto cleanup;
+ 
+-    if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt, vm, &flags,
+-                                        &persistentDef) < 0)
+-        goto cleanup;
+-
+-    if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+-        switch ((virDomainMetadataType) type) {
+-        case VIR_DOMAIN_METADATA_DESCRIPTION:
+-            VIR_FREE(vm->def->description);
+-            if (VIR_STRDUP(vm->def->description, metadata) < 0)
+-                goto cleanup;
+-            break;
+-        case VIR_DOMAIN_METADATA_TITLE:
+-            VIR_FREE(vm->def->title);
+-            if (VIR_STRDUP(vm->def->title, metadata) < 0)
+-                goto cleanup;
+-            break;
+-        case VIR_DOMAIN_METADATA_ELEMENT:
+-            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+-                           _("QEmu driver does not support modifying "
+-                             "<metadata> element"));
+-            goto cleanup;
+-            break;
+-        default:
+-            virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                           _("unknown metadata type"));
+-            goto cleanup;
+-            break;
+-        }
+-    }
+-
+-    if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+-        switch ((virDomainMetadataType) type) {
+-        case VIR_DOMAIN_METADATA_DESCRIPTION:
+-            VIR_FREE(persistentDef->description);
+-            if (VIR_STRDUP(persistentDef->description, metadata) < 0)
+-                goto cleanup;
+-            break;
+-        case VIR_DOMAIN_METADATA_TITLE:
+-            VIR_FREE(persistentDef->title);
+-            if (VIR_STRDUP(persistentDef->title, metadata) < 0)
+-                goto cleanup;
+-            break;
+-        case VIR_DOMAIN_METADATA_ELEMENT:
+-            virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+-                           _("QEMU driver does not support "
+-                             "<metadata> element"));
+-            goto cleanup;
+-         default:
+-            virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                           _("unknown metadata type"));
+-            goto cleanup;
+-            break;
+-        }
+-
+-        if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
+-            goto cleanup;
+-    }
+-
+-    ret = 0;
++    ret = virDomainObjSetMetadata(vm, type, metadata, key, uri, caps,
++                                  driver->xmlopt, cfg->configDir, flags);
+ 
+ cleanup:
+-    if (vm)
+-        virObjectUnlock(vm);
++    virObjectUnlock(vm);
+     virObjectUnref(caps);
+     virObjectUnref(cfg);
+     return ret;
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-test-Add-metadata-support-into-the-test-driver.patch b/SOURCES/libvirt-test-Add-metadata-support-into-the-test-driver.patch
new file mode 100644
index 0000000..2ee314a
--- /dev/null
+++ b/SOURCES/libvirt-test-Add-metadata-support-into-the-test-driver.patch
@@ -0,0 +1,104 @@
+From 5b8a0bcaacd16703b069ba1cf70e8259534eaf69 Mon Sep 17 00:00:00 2001
+Message-Id: <5b8a0bcaacd16703b069ba1cf70e8259534eaf69@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:49 +0100
+Subject: [PATCH] test: Add <metadata> support into the test driver
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+(cherry picked from commit f616fbf2a4a31a2f944aae0b75d6e2ab3bef3573)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/test/test_driver.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+
+diff --git a/src/test/test_driver.c b/src/test/test_driver.c
+index f7eaf06..4d23738 100644
+--- a/src/test/test_driver.c
++++ b/src/test/test_driver.c
+@@ -2528,6 +2528,72 @@ cleanup:
+     return ret;
+ }
+ 
++static char *testDomainGetMetadata(virDomainPtr dom,
++                                   int type,
++                                   const char *uri,
++                                   unsigned int flags)
++{
++    testConnPtr privconn = dom->conn->privateData;
++    virDomainObjPtr privdom;
++    char *ret = NULL;
++
++    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
++                  VIR_DOMAIN_AFFECT_CONFIG, NULL);
++
++    testDriverLock(privconn);
++    privdom = virDomainObjListFindByName(privconn->domains,
++                                         dom->name);
++    testDriverUnlock(privconn);
++
++    if (privdom == NULL) {
++        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
++        goto cleanup;
++    }
++
++    ret = virDomainObjGetMetadata(privdom, type, uri, privconn->caps,
++                                  privconn->xmlopt, flags);
++
++cleanup:
++    if (privdom)
++        virObjectUnlock(privdom);
++    return ret;
++}
++
++static int testDomainSetMetadata(virDomainPtr dom,
++                                 int type,
++                                 const char *metadata,
++                                 const char *key,
++                                 const char *uri,
++                                 unsigned int flags)
++{
++    testConnPtr privconn = dom->conn->privateData;
++    virDomainObjPtr privdom;
++    int ret = -1;
++
++    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
++                  VIR_DOMAIN_AFFECT_CONFIG, -1);
++
++    testDriverLock(privconn);
++    privdom = virDomainObjListFindByName(privconn->domains,
++                                         dom->name);
++    testDriverUnlock(privconn);
++
++    if (privdom == NULL) {
++        virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
++        goto cleanup;
++    }
++
++    ret = virDomainObjSetMetadata(privdom, type, metadata, key, uri,
++                                  privconn->caps, privconn->xmlopt,
++                                  NULL, flags);
++
++cleanup:
++    if (privdom)
++        virObjectUnlock(privdom);
++    return ret;
++}
++
++
+ static int testNodeGetCellsFreeMemory(virConnectPtr conn,
+                                       unsigned long long *freemems,
+                                       int startCell, int maxCells) {
+@@ -5815,6 +5881,8 @@ static virDriver testDriver = {
+     .connectIsAlive = testConnectIsAlive, /* 0.9.8 */
+     .nodeGetCPUMap = testNodeGetCPUMap, /* 1.0.0 */
+     .domainScreenshot = testDomainScreenshot, /* 1.0.5 */
++    .domainGetMetadata = testDomainGetMetadata, /* 1.1.3 */
++    .domainSetMetadata = testDomainSetMetadata, /* 1.1.3 */
+ };
+ 
+ static virNetworkDriver testNetworkDriver = {
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-tests-Add-metadata-tests.patch b/SOURCES/libvirt-tests-Add-metadata-tests.patch
new file mode 100644
index 0000000..8383adc
--- /dev/null
+++ b/SOURCES/libvirt-tests-Add-metadata-tests.patch
@@ -0,0 +1,299 @@
+From 7cef1905e04cef0996df582bf196902a410b4308 Mon Sep 17 00:00:00 2001
+Message-Id: <7cef1905e04cef0996df582bf196902a410b4308@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:50 +0100
+Subject: [PATCH] tests: Add metadata tests
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+This test exercises the virDomain[Get|Set]Metadata API and tests it for
+regressions
+
+(cherry picked from commit 2e23c77b0061c5f1b2fd5eeca79e3d6e963e7a2f)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tests/Makefile.am    |   7 ++
+ tests/metadatatest.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 252 insertions(+)
+ create mode 100644 tests/metadatatest.c
+
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index e49eadc..ac816fe 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -225,6 +225,8 @@ test_programs += interfacexml2xmltest
+ 
+ test_programs += cputest
+ 
++test_programs += metadatatest
++
+ test_scripts = \
+ 	capabilityschematest \
+ 	interfaceschematest \
+@@ -567,6 +569,11 @@ cputest_SOURCES = \
+ 	testutils.c testutils.h
+ cputest_LDADD = $(LDADDS)
+ 
++metadatatest_SOURCES = \
++	metadatatest.c \
++	testutils.c testutils.h
++metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS)
++
+ virshtest_SOURCES = \
+ 	virshtest.c \
+ 	testutils.c testutils.h
+diff --git a/tests/metadatatest.c b/tests/metadatatest.c
+new file mode 100644
+index 0000000..6bcf335
+--- /dev/null
++++ b/tests/metadatatest.c
+@@ -0,0 +1,245 @@
++/*
++ * Copyright (C) 2013 Red Hat, Inc.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library;  If not, see
++ * <http://www.gnu.org/licenses/>.
++ *
++ * Author: Peter Krempa <pkrempa@redhat.com>
++ */
++
++#include <config.h>
++
++#include "testutils.h"
++
++#include "virerror.h"
++#include "virxml.h"
++
++#define VIR_FROM_THIS VIR_FROM_NONE
++
++static const char metadata1[] =
++"<derp xmlns:foobar='http://foo.bar/'>\n"
++"  <bar>foobar</bar>\n"
++"  <foo fooish='blurb'>foofoo</foo>\n"
++"  <foobar:baz>zomg</foobar:baz>\n"
++"</derp>";
++
++
++static const char metadata1_ns[] =
++"<herp:derp xmlns:foobar='http://foo.bar/' xmlns:herp='http://herp.derp/'>\n"
++"  <herp:bar>foobar</herp:bar>\n"
++"  <herp:foo fooish='blurb'>foofoo</herp:foo>\n"
++"  <foobar:baz>zomg</foobar:baz>\n"
++"</herp:derp>";
++
++
++static const char metadata2[] =
++"<foo>\n"
++"  <bar>baz</bar>\n"
++"</foo>";
++
++
++static const char metadata2_ns[] =
++"<blurb:foo xmlns:blurb='http://herp.derp/'>\n"
++"  <blurb:bar>baz</blurb:bar>\n"
++"</blurb:foo>";
++
++
++static char *
++getMetadataFromXML(virDomainPtr dom)
++{
++    xmlDocPtr doc = NULL;
++    xmlXPathContextPtr ctxt = NULL;
++    xmlNodePtr node;
++
++    char *xml = NULL;
++    char *ret = NULL;
++
++    if (!(xml = virDomainGetXMLDesc(dom, 0)))
++        goto cleanup;
++
++    if (!(doc = virXMLParseStringCtxt(xml, "(domain_definition)", &ctxt)))
++        goto cleanup;
++
++    if (!(node = virXPathNode("//metadata/*", ctxt)))
++        goto cleanup;
++
++    ret = virXMLNodeToString(node->doc, node);
++
++cleanup:
++    VIR_FREE(xml);
++    xmlFreeDoc(doc);
++    xmlXPathFreeContext(ctxt);
++
++    return ret;
++}
++
++
++static void
++metadataXMLConvertApostrophe(char *str)
++{
++    do {
++        if (*str == '\"')
++            *str = '\'';
++    } while ((*++str) != '\0');
++}
++
++
++static bool
++verifyMetadata(virDomainPtr dom,
++               const char *expectXML,
++               const char *expectAPI,
++               const char *uri)
++{
++    bool ret = false;
++    char *metadataXML = NULL;
++    char *metadataAPI = NULL;
++
++    if (!expectAPI) {
++        if ((metadataAPI = virDomainGetMetadata(dom,
++                                                VIR_DOMAIN_METADATA_ELEMENT,
++                                                uri, 0))) {
++            virReportError(VIR_ERR_INTERNAL_ERROR,
++                           "expected no metadata in API, but got:\n[%s]",
++                           metadataAPI);
++            goto cleanup;
++        }
++    } else {
++        if (!(metadataAPI = virDomainGetMetadata(dom,
++                                                 VIR_DOMAIN_METADATA_ELEMENT,
++                                                 uri, 0)))
++            goto cleanup;
++
++        metadataXMLConvertApostrophe(metadataAPI);
++
++        if (STRNEQ(metadataAPI, expectAPI)) {
++            virReportError(VIR_ERR_INTERNAL_ERROR,
++                           "XML metadata in API doesn't match expected metadata: "
++                           "expected:\n[%s]\ngot:\n[%s]",
++                           expectAPI, metadataAPI);
++            goto cleanup;
++        }
++
++    }
++
++    if (!expectXML) {
++        if ((metadataXML = getMetadataFromXML(dom))) {
++            virReportError(VIR_ERR_INTERNAL_ERROR,
++                           "expected no metadata in XML, but got:\n[%s]",
++                           metadataXML);
++            goto cleanup;
++        }
++    } else {
++        if (!(metadataXML = getMetadataFromXML(dom)))
++            goto cleanup;
++
++        metadataXMLConvertApostrophe(metadataXML);
++
++        if (STRNEQ(metadataXML, expectXML)) {
++            virReportError(VIR_ERR_INTERNAL_ERROR,
++                           "XML in dump doesn't match expected metadata: "
++                           "expected:\n[%s]\ngot:\n[%s]",
++                           expectXML, metadataXML);
++            goto cleanup;
++        }
++    }
++
++    ret = true;
++
++cleanup:
++    VIR_FREE(metadataXML);
++    VIR_FREE(metadataAPI);
++
++    return ret;
++}
++
++
++struct metadataTest {
++    virConnectPtr conn;
++    virDomainPtr dom;
++};
++
++
++static int
++testAssignMetadata(const void *data)
++{
++    const struct metadataTest *test = data;
++
++    if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
++                             metadata1, "herp", "http://herp.derp/", 0) < 0)
++        return -1;
++
++    if (!verifyMetadata(test->dom, metadata1_ns, metadata1, "http://herp.derp/"))
++        return -1;
++
++    return 0;
++}
++
++static int
++testRewriteMetadata(const void *data)
++{
++    const struct metadataTest *test = data;
++
++    if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
++                             metadata2, "blurb", "http://herp.derp/", 0) < 0)
++        return -1;
++
++    if (!verifyMetadata(test->dom, metadata2_ns, metadata2, "http://herp.derp/"))
++        return -1;
++
++    return 0;
++}
++
++static int
++testEraseMetadata(const void *data)
++{
++    const struct metadataTest *test = data;
++
++    if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
++                             NULL, NULL, "http://herp.derp/", 0) < 0)
++        return -1;
++
++    if (!verifyMetadata(test->dom, NULL, NULL, "http://herp.derp/"))
++        return -1;
++
++    return 0;
++}
++
++static int
++mymain(void)
++{
++    struct metadataTest test;
++    int ret = EXIT_SUCCESS;
++
++    if (!(test.conn = virConnectOpen("test:///default")))
++        return EXIT_FAILURE;
++
++    if (!(test.dom = virDomainLookupByName(test.conn, "test"))) {
++        virConnectClose(test.conn);
++        return EXIT_FAILURE;
++    }
++
++    if (virtTestRun("Assign metadata ", 1, testAssignMetadata, &test) < 0)
++        ret = EXIT_FAILURE;
++    if (virtTestRun("Rewrite Metadata ", 1, testRewriteMetadata, &test) < 0)
++        ret = EXIT_FAILURE;
++    if (virtTestRun("Erase metadata ", 1, testEraseMetadata, &test) < 0)
++        ret = EXIT_FAILURE;
++
++    virDomainFree(test.dom);
++    virConnectClose(test.conn);
++
++    return ret;
++}
++
++VIRT_TEST_MAIN(mymain)
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-util-Add-helper-to-convert-libxml2-nodes-to-a-string.patch b/SOURCES/libvirt-util-Add-helper-to-convert-libxml2-nodes-to-a-string.patch
new file mode 100644
index 0000000..93d7ceb
--- /dev/null
+++ b/SOURCES/libvirt-util-Add-helper-to-convert-libxml2-nodes-to-a-string.patch
@@ -0,0 +1,84 @@
+From 2e65f52bf904f8ff5587dc42b7c37d94f9dab451 Mon Sep 17 00:00:00 2001
+Message-Id: <2e65f52bf904f8ff5587dc42b7c37d94f9dab451@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:42 +0100
+Subject: [PATCH] util: Add helper to convert libxml2 nodes to a string
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+(cherry picked from commit be0f0c2292e3f171a031086f4d0a39b205c756a3)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/util/virxml.c        | 33 +++++++++++++++++++++++++++++++++
+ src/util/virxml.h        |  2 ++
+ 3 files changed, 36 insertions(+)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 61d8d26..3df4379 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2140,6 +2140,7 @@ virUUIDParse;
+ 
+ # util/virxml.h
+ virXMLChildElementCount;
++virXMLNodeToString;
+ virXMLParseHelper;
+ virXMLPickShellSafeComment;
+ virXMLPropString;
+diff --git a/src/util/virxml.c b/src/util/virxml.c
+index 4769569..9bb8bf0 100644
+--- a/src/util/virxml.c
++++ b/src/util/virxml.c
+@@ -895,3 +895,36 @@ virXMLChildElementCount(xmlNodePtr node)
+     }
+     return ret;
+ }
++
++
++/**
++ * virXMLNodeToString: convert an XML node ptr to an XML string
++ *
++ * Returns the XML string of the document or NULL on error.
++ * The caller has to free the string.
++ */
++char *
++virXMLNodeToString(xmlDocPtr doc,
++                   xmlNodePtr node)
++{
++     xmlBufferPtr xmlbuf = NULL;
++     char *ret = NULL;
++
++     if (!(xmlbuf = xmlBufferCreate())) {
++         virReportOOMError();
++         return NULL;
++     }
++
++     if (xmlNodeDump(xmlbuf, doc, node, 0, 1) == 0) {
++         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                        _("failed to convert the XML node tree"));
++         goto cleanup;
++     }
++
++     ignore_value(VIR_STRDUP(ret, (const char *)xmlBufferContent(xmlbuf)));
++
++cleanup:
++     xmlBufferFree(xmlbuf);
++
++     return ret;
++}
+diff --git a/src/util/virxml.h b/src/util/virxml.h
+index 364288d..bb34069 100644
+--- a/src/util/virxml.h
++++ b/src/util/virxml.h
+@@ -163,4 +163,6 @@ int virXMLSaveFile(const char *path,
+                    const char *warnCommand,
+                    const char *xml);
+ 
++char *virXMLNodeToString(xmlDocPtr doc, xmlNodePtr node);
++
+ #endif                          /* __VIR_XML_H__ */
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-util-check-for-an-illegal-character-in-a-XML-namespace-prefix.patch b/SOURCES/libvirt-util-check-for-an-illegal-character-in-a-XML-namespace-prefix.patch
new file mode 100644
index 0000000..b896edc
--- /dev/null
+++ b/SOURCES/libvirt-util-check-for-an-illegal-character-in-a-XML-namespace-prefix.patch
@@ -0,0 +1,44 @@
+From 28894754f079527609645607bb44fb268259bf2c Mon Sep 17 00:00:00 2001
+Message-Id: <28894754f079527609645607bb44fb268259bf2c@dist-git>
+From: Erik Skultety <eskultet@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:57 +0100
+Subject: [PATCH] util: check for an illegal character in a XML namespace
+ prefix
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+When user tries to insert element metadata providing a namespace
+declaration as well, currently we insert the element without any validation
+check for XML prefix (if provided). The next VM start would then
+fail with parse error. This patch fixes this issue by adding a call to
+xmlValidateNCName function to check for illegal characters in the
+prefix.
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1143921
+
+(cherry picked from commit 2c22954f99a70ed654e4116a18f433afa24d41c5)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virxml.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/util/virxml.c b/src/util/virxml.c
+index 88a1196..88c1fcc 100644
+--- a/src/util/virxml.c
++++ b/src/util/virxml.c
+@@ -1074,6 +1074,12 @@ virXMLInjectNamespace(xmlNodePtr node,
+ {
+     xmlNsPtr ns;
+ 
++    if (xmlValidateNCName((const unsigned char *)key, 1) != 0) {
++        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                       _("failed to validate prefix for a new XML namespace"));
++        return -1;
++    }
++
+     if (!(ns = xmlNewNs(node, (const unsigned char *)uri, (const unsigned char *)key))) {
+         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("failed to create a new XML namespace"));
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-virsh-Don-t-shadow-global-variable-remove-in-cmdMetadata.patch b/SOURCES/libvirt-virsh-Don-t-shadow-global-variable-remove-in-cmdMetadata.patch
new file mode 100644
index 0000000..614b760
--- /dev/null
+++ b/SOURCES/libvirt-virsh-Don-t-shadow-global-variable-remove-in-cmdMetadata.patch
@@ -0,0 +1,52 @@
+From 63f44f163b462a7dffefa927df771fcc88ab603f Mon Sep 17 00:00:00 2001
+Message-Id: <63f44f163b462a7dffefa927df771fcc88ab603f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:53 +0100
+Subject: [PATCH] virsh: Don't shadow global variable "remove" in cmdMetadata
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+Some systems apparently have a global variable/function called remove
+and thus break compilation of virsh-domain.c. Rename the variable to
+avoid this.
+
+Reported by GuanQiang.
+
+(cherry picked from commit 6bf4c779841f858872003ffe6a97df395b2940e6)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tools/virsh-domain.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
+index a2796e5..dd697f9 100644
+--- a/tools/virsh-domain.c
++++ b/tools/virsh-domain.c
+@@ -6894,7 +6894,7 @@ cmdMetadata(vshControl *ctl, const vshCmd *cmd)
+     bool live = vshCommandOptBool(cmd, "live");
+     bool current = vshCommandOptBool(cmd, "current");
+     bool edit = vshCommandOptBool(cmd, "edit");
+-    bool remove = vshCommandOptBool(cmd, "remove");
++    bool rem = vshCommandOptBool(cmd, "remove");
+     const char *set = NULL;
+     const char *uri = NULL;
+     const char *key = NULL;
+@@ -6926,12 +6926,12 @@ cmdMetadata(vshControl *ctl, const vshCmd *cmd)
+         goto cleanup;
+     }
+ 
+-    if (set || remove) {
++    if (set || rem) {
+         if (virDomainSetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT,
+                                  set, key, uri, flags))
+             goto cleanup;
+ 
+-        if (remove)
++        if (rem)
+             vshPrint("%s\n", _("Metadata removed"));
+         else
+             vshPrint("%s\n", _("Metadata modified"));
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-virsh-domain-Add-command-to-allow-modifications-of-XML-metadata.patch b/SOURCES/libvirt-virsh-domain-Add-command-to-allow-modifications-of-XML-metadata.patch
new file mode 100644
index 0000000..53b1f65
--- /dev/null
+++ b/SOURCES/libvirt-virsh-domain-Add-command-to-allow-modifications-of-XML-metadata.patch
@@ -0,0 +1,201 @@
+From 7aa95972f21eb0b39c06909360bcf8b51171b263 Mon Sep 17 00:00:00 2001
+Message-Id: <7aa95972f21eb0b39c06909360bcf8b51171b263@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:44 +0100
+Subject: [PATCH] virsh-domain: Add command to allow modifications of XML
+ metadata
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+The metadata modification functions will support modification of the XML
+metadata. Add a virsh command to allow using this approach.
+
+(cherry picked from commit 01b03f59e76865feed3097cbe6dc0a809caccc14)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tools/virsh-domain.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 161 insertions(+)
+
+diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
+index 6076e8d..a2796e5 100644
+--- a/tools/virsh-domain.c
++++ b/tools/virsh-domain.c
+@@ -6813,6 +6813,161 @@ cleanup:
+     return ret;
+ }
+ 
++
++static const vshCmdInfo info_metadata[] = {
++    {.name = "help",
++     .data = N_("show or set domain's custom XML metadata")
++    },
++    {.name = "desc",
++     .data = N_("Shows or modifies the XML metadata of a domain.")
++    },
++    {.name = NULL}
++};
++
++static const vshCmdOptDef opts_metadata[] = {
++    {.name = "domain",
++     .type = VSH_OT_DATA,
++     .flags = VSH_OFLAG_REQ,
++     .help = N_("domain name, id or uuid")
++    },
++    {.name = "live",
++     .type = VSH_OT_BOOL,
++     .help = N_("modify/get running state")
++    },
++    {.name = "config",
++     .type = VSH_OT_BOOL,
++     .help = N_("modify/get persistent configuration")
++    },
++    {.name = "current",
++     .type = VSH_OT_BOOL,
++     .help = N_("modify/get current state configuration")
++    },
++    {.name = "edit",
++     .type = VSH_OT_BOOL,
++     .help = N_("use an editor to change the metadata")
++    },
++    {.name = "uri",
++     .type = VSH_OT_DATA,
++     .flags = VSH_OFLAG_REQ,
++     .help = N_("URI of the namespace")
++    },
++    {.name = "key",
++     .type = VSH_OT_DATA,
++     .help = N_("key to be used as a namespace identifier"),
++    },
++    {.name = "set",
++     .type = VSH_OT_DATA,
++     .help = N_("new metadata to set"),
++    },
++    {.name = "remove",
++     .type = VSH_OT_BOOL,
++     .help = N_("remove the metadata corresponding to an uri")
++    },
++    {.name = NULL}
++};
++
++
++/* helper to add new metadata using the --edit option */
++static char *
++vshDomainGetEditMetadata(vshControl *ctl,
++                         virDomainPtr dom,
++                         const char *uri,
++                         unsigned int flags)
++{
++    char *ret;
++
++    if (!(ret = virDomainGetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT,
++                                     uri, flags))) {
++        vshResetLibvirtError();
++        ret = vshStrdup(ctl, "\n");
++    }
++
++    return ret;
++}
++
++
++static bool
++cmdMetadata(vshControl *ctl, const vshCmd *cmd)
++{
++    virDomainPtr dom;
++    bool config = vshCommandOptBool(cmd, "config");
++    bool live = vshCommandOptBool(cmd, "live");
++    bool current = vshCommandOptBool(cmd, "current");
++    bool edit = vshCommandOptBool(cmd, "edit");
++    bool remove = vshCommandOptBool(cmd, "remove");
++    const char *set = NULL;
++    const char *uri = NULL;
++    const char *key = NULL;
++    unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
++    bool ret = false;
++
++    VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
++    VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
++    VSH_EXCLUSIVE_OPTIONS("edit", "set");
++    VSH_EXCLUSIVE_OPTIONS("remove", "set");
++    VSH_EXCLUSIVE_OPTIONS("remove", "edit");
++
++    if (config)
++        flags |= VIR_DOMAIN_AFFECT_CONFIG;
++    if (live)
++        flags |= VIR_DOMAIN_AFFECT_LIVE;
++
++    if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
++        return false;
++
++    if (vshCommandOptStringReq(ctl, cmd, "uri", &uri) < 0 ||
++        vshCommandOptStringReq(ctl, cmd, "key", &key) < 0 ||
++        vshCommandOptStringReq(ctl, cmd, "set", &set) < 0)
++        goto cleanup;
++
++    if ((set || edit) && !key) {
++        vshError(ctl, "%s",
++                 _("namespace key is required when modifying metadata"));
++        goto cleanup;
++    }
++
++    if (set || remove) {
++        if (virDomainSetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT,
++                                 set, key, uri, flags))
++            goto cleanup;
++
++        if (remove)
++            vshPrint("%s\n", _("Metadata removed"));
++        else
++            vshPrint("%s\n", _("Metadata modified"));
++    } else if (edit) {
++#define EDIT_GET_XML \
++        vshDomainGetEditMetadata(ctl, dom, uri, flags)
++#define EDIT_NOT_CHANGED                                    \
++        vshPrint(ctl, "%s", _("Metadata not changed"));     \
++        ret = true;                                         \
++        goto edit_cleanup;
++#define EDIT_DEFINE                                                         \
++        (virDomainSetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT, doc_edited, \
++                              key, uri, flags) == 0)
++#define EDIT_FREE /* nothing */
++#include "virsh-edit.c"
++
++        vshPrint("%s\n", _("Metadata modified"));
++    } else {
++        char *data;
++        /* get */
++        if (!(data = virDomainGetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT,
++                                          uri, flags)))
++            goto cleanup;
++
++        vshPrint(ctl, "%s\n", data);
++        VIR_FREE(data);
++    }
++
++    ret = true;
++
++cleanup:
++    virDomainFree(dom);
++    return ret;
++}
++
++
+ /*
+  * "inject-nmi" command
+  */
+@@ -10603,6 +10758,12 @@ const vshCmdDef domManagementCmds[] = {
+      .info = info_memtune,
+      .flags = 0
+     },
++    {.name = "metadata",
++     .handler = cmdMetadata,
++     .opts = opts_metadata,
++     .info = info_metadata,
++     .flags = 0
++    },
+     {.name = "migrate",
+      .handler = cmdMigrate,
+      .opts = opts_migrate,
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-virsh-domain-use-virXMLNodeToString-instead-of-xmlNodeDump.patch b/SOURCES/libvirt-virsh-domain-use-virXMLNodeToString-instead-of-xmlNodeDump.patch
new file mode 100644
index 0000000..4c0d45b
--- /dev/null
+++ b/SOURCES/libvirt-virsh-domain-use-virXMLNodeToString-instead-of-xmlNodeDump.patch
@@ -0,0 +1,292 @@
+From 502cf493c7832a3ea5a4cd20dea289d291c7c56b Mon Sep 17 00:00:00 2001
+Message-Id: <502cf493c7832a3ea5a4cd20dea289d291c7c56b@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 22 Jan 2015 15:53:43 +0100
+Subject: [PATCH] virsh-domain: use virXMLNodeToString instead of xmlNodeDump
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+(cherry picked from commit 3df33d7ad52d27bf9a41ab07e2c0ab631364ae04)
+
+Conflicts:
+	tools/virsh-domain.c - context
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tools/virsh-domain.c | 113 +++++++++++++--------------------------------------
+ 1 file changed, 29 insertions(+), 84 deletions(-)
+
+diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
+index 03f96fb..6076e8d 100644
+--- a/tools/virsh-domain.c
++++ b/tools/virsh-domain.c
+@@ -2356,7 +2356,7 @@ cmdDomIfSetLink(vshControl *ctl, const vshCmd *cmd)
+     xmlXPathContextPtr ctxt = NULL;
+     xmlXPathObjectPtr obj = NULL;
+     xmlNodePtr cur = NULL;
+-    xmlBufferPtr xml_buf = NULL;
++    char *xml_buf = NULL;
+ 
+     if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+         return false;
+@@ -2461,18 +2461,13 @@ hit:
+             goto cleanup;
+     }
+ 
+-    xml_buf = xmlBufferCreate();
+-    if (!xml_buf) {
+-        vshError(ctl, _("Failed to allocate memory"));
+-        goto cleanup;
+-    }
+-
+-    if (xmlNodeDump(xml_buf, xml, obj->nodesetval->nodeTab[i], 0, 0) < 0) {
++    if (!(xml_buf = virXMLNodeToString(xml, obj->nodesetval->nodeTab[i]))) {
++        vshSaveLibvirtError();
+         vshError(ctl, _("Failed to create XML"));
+         goto cleanup;
+     }
+ 
+-    if (virDomainUpdateDeviceFlags(dom, (char *)xmlBufferContent(xml_buf), flags) < 0) {
++    if (virDomainUpdateDeviceFlags(dom, xml_buf, flags) < 0) {
+         vshError(ctl, _("Failed to update interface link state"));
+         goto cleanup;
+     } else {
+@@ -2484,10 +2479,8 @@ cleanup:
+     xmlXPathFreeObject(obj);
+     xmlXPathFreeContext(ctxt);
+     xmlFreeDoc(xml);
+-    xmlBufferFree(xml_buf);
+-
+-    if (dom)
+-        virDomainFree(dom);
++    VIR_FREE(xml_buf);
++    virDomainFree(dom);
+ 
+     return ret;
+ }
+@@ -6092,11 +6085,10 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
+     bool ret = false;
+     char *buffer;
+     int result;
+-    const char *snippet;
++    char *snippet = NULL;
+ 
+     xmlDocPtr xml = NULL;
+     xmlXPathContextPtr ctxt = NULL;
+-    xmlBufferPtr xml_buf = NULL;
+     xmlNodePtr node;
+ 
+     if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
+@@ -6112,17 +6104,10 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
+     if ((node = virXPathNode("/cpu|"
+                              "/domain/cpu|"
+                               "/capabilities/host/cpu", ctxt))) {
+-        if (!(xml_buf = xmlBufferCreate())) {
+-            vshError(ctl, _("Can't create XML buffer to extract CPU element."));
++        if (!(snippet = virXMLNodeToString(xml, node))) {
++            vshSaveLibvirtError();
+             goto cleanup;
+         }
+-
+-        if (xmlNodeDump(xml_buf, xml, node, 0, 0) < 0) {
+-            vshError(ctl, _("Failed to extract CPU element snippet from domain XML."));
+-            goto cleanup;
+-        }
+-
+-        snippet = (const char *) xmlBufferContent(xml_buf);
+     } else {
+         vshError(ctl, _("File '%s' does not contain a <cpu> element or is not "
+                         "a valid domain or capabilities XML"), from);
+@@ -6158,7 +6143,7 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
+ 
+ cleanup:
+     VIR_FREE(buffer);
+-    xmlBufferFree(xml_buf);
++    VIR_FREE(snippet);
+     xmlXPathFreeContext(ctxt);
+     xmlFreeDoc(xml);
+ 
+@@ -6200,7 +6185,6 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
+     xmlDocPtr xml = NULL;
+     xmlNodePtr *node_list = NULL;
+     xmlXPathContextPtr ctxt = NULL;
+-    xmlBufferPtr xml_buf = NULL;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     size_t i;
+ 
+@@ -6233,18 +6217,11 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
+ 
+     list = vshCalloc(ctl, count, sizeof(const char *));
+ 
+-    if (!(xml_buf = xmlBufferCreate()))
+-        goto no_memory;
+-
+     for (i = 0; i < count; i++) {
+-        xmlBufferEmpty(xml_buf);
+-
+-        if (xmlNodeDump(xml_buf, xml,  node_list[i], 0, 0) < 0) {
+-            vshError(ctl, _("Failed to extract <cpu> element"));
++        if (!(list[i] = virXMLNodeToString(xml, node_list[i]))) {
++            vshSaveLibvirtError();
+             goto cleanup;
+         }
+-
+-        list[i] = vshStrdup(ctl, (const char *)xmlBufferContent(xml_buf));
+     }
+ 
+     result = virConnectBaselineCPU(ctl->conn, list, count, 0);
+@@ -6257,7 +6234,6 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
+ cleanup:
+     xmlXPathFreeContext(ctxt);
+     xmlFreeDoc(xml);
+-    xmlBufferFree(xml_buf);
+     VIR_FREE(result);
+     if (list != NULL && count > 0) {
+         for (i = 0; i < count; i++)
+@@ -9633,7 +9609,7 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
+     xmlXPathObjectPtr obj=NULL;
+     xmlXPathContextPtr ctxt = NULL;
+     xmlNodePtr cur = NULL, matchNode = NULL;
+-    xmlBufferPtr xml_buf = NULL;
++    char *detach_xml = NULL;
+     const char *mac =NULL, *type = NULL;
+     char *doc = NULL;
+     char buf[64];
+@@ -9726,25 +9702,16 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
+         goto cleanup;
+     }
+ 
+- hit:
+-    xml_buf = xmlBufferCreate();
+-    if (!xml_buf) {
+-        vshError(ctl, "%s", _("Failed to allocate memory"));
++hit:
++    if (!(detach_xml = virXMLNodeToString(xml, matchNode))) {
++        vshSaveLibvirtError();
+         goto cleanup;
+     }
+ 
+-    if (xmlNodeDump(xml_buf, xml, matchNode, 0, 0) < 0) {
+-        vshError(ctl, "%s", _("Failed to create XML"));
+-        goto cleanup;
+-    }
+-
+-    if (flags != 0 || current) {
+-        ret = virDomainDetachDeviceFlags(dom,
+-                                         (char *)xmlBufferContent(xml_buf),
+-                                         flags);
+-    } else {
+-        ret = virDomainDetachDevice(dom, (char *)xmlBufferContent(xml_buf));
+-    }
++    if (flags != 0)
++        ret = virDomainDetachDeviceFlags(dom, detach_xml, flags);
++    else
++        ret = virDomainDetachDevice(dom, detach_xml);
+ 
+     if (ret != 0) {
+         vshError(ctl, "%s", _("Failed to detach interface"));
+@@ -9753,13 +9720,13 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
+         functionReturn = true;
+     }
+ 
+- cleanup:
++cleanup:
+     VIR_FREE(doc);
++    VIR_FREE(detach_xml);
+     virDomainFree(dom);
+     xmlXPathFreeObject(obj);
+     xmlXPathFreeContext(ctxt);
+     xmlFreeDoc(xml);
+-    xmlBufferFree(xml_buf);
+     return functionReturn;
+ }
+ 
+@@ -9877,7 +9844,6 @@ vshPrepareDiskXML(xmlNodePtr disk_node,
+                   int type)
+ {
+     xmlNodePtr cur = NULL;
+-    xmlBufferPtr xml_buf = NULL;
+     const char *disk_type = NULL;
+     const char *device_type = NULL;
+     xmlNodePtr new_node = NULL;
+@@ -9886,12 +9852,6 @@ vshPrepareDiskXML(xmlNodePtr disk_node,
+     if (!disk_node)
+         return NULL;
+ 
+-    xml_buf = xmlBufferCreate();
+-    if (!xml_buf) {
+-        vshError(NULL, "%s", _("Failed to allocate memory"));
+-        return NULL;
+-    }
+-
+     device_type = virXMLPropString(disk_node, "device");
+ 
+     if (STREQ_NULLABLE(device_type, "cdrom") ||
+@@ -9913,7 +9873,7 @@ vshPrepareDiskXML(xmlNodePtr disk_node,
+             if (type == VSH_PREPARE_DISK_XML_EJECT) {
+                 vshError(NULL, _("The disk device '%s' doesn't have media"),
+                          path);
+-                goto error;
++                goto cleanup;
+             }
+ 
+             if (source) {
+@@ -9925,10 +9885,10 @@ vshPrepareDiskXML(xmlNodePtr disk_node,
+                 xmlAddChild(disk_node, new_node);
+             } else if (type == VSH_PREPARE_DISK_XML_INSERT) {
+                 vshError(NULL, _("No source is specified for inserting media"));
+-                goto error;
++                goto cleanup;
+             } else if (type == VSH_PREPARE_DISK_XML_UPDATE) {
+                 vshError(NULL, _("No source is specified for updating media"));
+-                goto error;
++                goto cleanup;
+             }
+         }
+ 
+@@ -9936,7 +9896,7 @@ vshPrepareDiskXML(xmlNodePtr disk_node,
+             if (type == VSH_PREPARE_DISK_XML_INSERT) {
+                 vshError(NULL, _("The disk device '%s' already has media"),
+                          path);
+-                goto error;
++                goto cleanup;
+             }
+ 
+             /* Remove the source if it tends to eject/update media. */
+@@ -9952,30 +9912,15 @@ vshPrepareDiskXML(xmlNodePtr disk_node,
+         }
+     }
+ 
+-    if (xmlNodeDump(xml_buf, NULL, disk_node, 0, 0) < 0) {
+-        vshError(NULL, "%s", _("Failed to create XML"));
+-        goto error;
++    if (!(ret = virXMLNodeToString(NULL, disk_node))) {
++        vshSaveLibvirtError();
++        goto cleanup;
+     }
+ 
+-    goto cleanup;
+-
+ cleanup:
+     VIR_FREE(device_type);
+     VIR_FREE(disk_type);
+-    if (xml_buf) {
+-        int len = xmlBufferLength(xml_buf);
+-        if (VIR_ALLOC_N(ret, len + 1) < 0)
+-            return NULL;
+-        memcpy(ret, (char *)xmlBufferContent(xml_buf), len);
+-        ret[len] = '\0';
+-        xmlBufferFree(xml_buf);
+-    }
+     return ret;
+-
+-error:
+-    xmlBufferFree(xml_buf);
+-    xml_buf = NULL;
+-    goto cleanup;
+ }
+ 
+ 
+-- 
+2.2.1
+
diff --git a/SOURCES/libvirt-virsh-man-Crosslink-desc-and-metadata-sections.patch b/SOURCES/libvirt-virsh-man-Crosslink-desc-and-metadata-sections.patch
new file mode 100644
index 0000000..33d7ff9
--- /dev/null
+++ b/SOURCES/libvirt-virsh-man-Crosslink-desc-and-metadata-sections.patch
@@ -0,0 +1,42 @@
+From 913b0f1385085b9a0a17f835fa56b1ccd2ad65c6 Mon Sep 17 00:00:00 2001
+Message-Id: <913b0f1385085b9a0a17f835fa56b1ccd2ad65c6@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 28 Jan 2015 10:33:40 +0100
+Subject: [PATCH] virsh: man: Crosslink "desc" and "metadata" sections
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1184929
+
+Those two commands work with a single API so cross-link them.
+
+(cherry picked from commit c68ae7f61155891651081e523c5576e719f932eb)
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tools/virsh.pod | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/virsh.pod b/tools/virsh.pod
+index c3ae204..d0dbbca 100644
+--- a/tools/virsh.pod
++++ b/tools/virsh.pod
+@@ -581,6 +581,7 @@ effect on the next boot.
+ Show or modify description and title of a domain. These values are user
+ fields that allow to store arbitrary textual data to allow easy
+ identification of domains. Title should be short, although it's not enforced.
++(See also B<metadata> that works with XML based domain metadata.)
+ 
+ Flags I<--live> or I<--config> select whether this command works on live
+ or persistent definitions of the domain. If both I<--live> and I<--config>
+@@ -1080,7 +1081,8 @@ Show or modify custom XML metadata of a domain. The metadata is a user
+ defined XML that allows to store arbitrary XML data in the domain definition.
+ Multiple separate custom metadata pieces can be stored in the domain XML.
+ The pieces are identified by a private XML namespace provided via the
+-I<uri> argument.
++I<uri> argument. (See also B<desc> that works with textual metadata of
++a domain.)
+ 
+ Flags I<--live> or I<--config> select whether this command works on live
+ or persistent definitions of the domain. If both I<--live> and I<--config>
+-- 
+2.2.2
+
diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec
index d8dc72e..61c1952 100644
--- a/SPECS/libvirt.spec
+++ b/SPECS/libvirt.spec
@@ -379,7 +379,7 @@
 Summary: Library providing a simple virtualization API
 Name: libvirt
 Version: 1.1.1
-Release: 29%{?dist}.4%{?extra_release}
+Release: 29%{?dist}.7%{?extra_release}
 License: LGPLv2+
 Group: Development/Libraries
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -911,6 +911,35 @@ Patch518: libvirt-qemu-copy-Accept-format-parameter-when-copying-to-a-non-existi
 Patch519: libvirt-qemu-reject-rather-than-hang-on-blockcommit-of-active-layer.patch
 Patch520: libvirt-CVE-2014-7823-dumpxml-security-hole-with-migratable-flag.patch
 Patch521: libvirt-Fix-crash-when-saving-a-domain-with-type-none-dac-label.patch
+Patch522: libvirt-conf-Format-interface-s-driver-more-frequently.patch
+Patch523: libvirt-qemu-Factor-out-body-of-qemuDomainGetMetadata-for-universal-use.patch
+Patch524: libvirt-qemu-Factor-out-body-of-qemuDomainSetMetadata-for-universal-use.patch
+Patch525: libvirt-conf-Factor-out-setting-of-metadata-to-simplify-code.patch
+Patch526: libvirt-util-Add-helper-to-convert-libxml2-nodes-to-a-string.patch
+Patch527: libvirt-virsh-domain-use-virXMLNodeToString-instead-of-xmlNodeDump.patch
+Patch528: libvirt-virsh-domain-Add-command-to-allow-modifications-of-XML-metadata.patch
+Patch529: libvirt-conf-Add-support-for-requesting-of-XML-metadata-via-the-API.patch
+Patch530: libvirt-conf-allow-to-add-XML-metadata-using-the-virDomainSetMetadata-api.patch
+Patch531: libvirt-lib-Don-t-force-the-key-argument-when-deleting-metadata.patch
+Patch532: libvirt-lxc-Add-metadata-modification-APIs.patch
+Patch533: libvirt-test-Add-metadata-support-into-the-test-driver.patch
+Patch534: libvirt-tests-Add-metadata-tests.patch
+Patch535: libvirt-conf-Don-t-corrupt-metadata-on-OOM.patch
+Patch536: libvirt-conf-Avoid-false-positive-of-uninitialized-variable-use.patch
+Patch537: libvirt-virsh-Don-t-shadow-global-variable-remove-in-cmdMetadata.patch
+Patch538: libvirt-metadata-track-title-edits-across-libvirtd-restart.patch
+Patch539: libvirt-conf-Improve-metadata-type-verification.patch
+Patch540: libvirt-Fix-possible-memory-leak-in-util-virxml.c.patch
+Patch541: libvirt-util-check-for-an-illegal-character-in-a-XML-namespace-prefix.patch
+Patch542: libvirt-Fix-libvirtd-crash-when-removing-metadata.patch
+Patch543: libvirt-Add-invariant-TSC-cpu-flag.patch
+Patch544: libvirt-cpu_x86-Resolve-Coverity-RESOURCE_LEAK.patch
+Patch545: libvirt-Don-t-include-non-migratable-features-in-host-model.patch
+Patch546: libvirt-Fix-leak-in-x86UpdateHostModel.patch
+Patch547: libvirt-Also-filter-out-non-migratable-features-out-of-host-passthrough.patch
+Patch548: libvirt-man-virsh-Add-man-page-for-virsh-metadata.patch
+Patch549: libvirt-virsh-man-Crosslink-desc-and-metadata-sections.patch
+Patch550: libvirt-Fix-segfault-when-starting-a-domain-with-no-cpu-definition.patch
 
 
 %if %{with_libvirtd}
@@ -2704,6 +2733,41 @@ exit 0
 %endif
 
 %changelog
+* Thu Jan 29 2015 Jiri Denemark <jdenemar@redhat.com> - 1.1.1-29.el7_0.7
+- Fix segfault when starting a domain with no cpu definition (rhbz#1185458)
+
+* Wed Jan 28 2015 Jiri Denemark <jdenemar@redhat.com> - 1.1.1-29.el7_0.6
+- Add invariant TSC cpu flag (rhbz#1185458)
+- cpu_x86: Resolve Coverity RESOURCE_LEAK (rhbz#1185458)
+- Don't include non-migratable features in host-model (rhbz#1185458)
+- Fix leak in x86UpdateHostModel (rhbz#1185458)
+- Also filter out non-migratable features out of host-passthrough (rhbz#1185458)
+- man: virsh: Add man page for "virsh metadata" (rhbz#1184929)
+- virsh: man: Crosslink "desc" and "metadata" sections (rhbz#1184929)
+
+* Fri Jan 23 2015 Jiri Denemark <jdenemar@redhat.com> - 1.1.1-29.el7_0.5
+- conf: Format interface's driver more frequently (rhbz#1183447)
+- qemu: Factor out body of qemuDomainGetMetadata for universal use (rhbz#1184929)
+- qemu: Factor out body of qemuDomainSetMetadata for universal use (rhbz#1184929)
+- conf: Factor out setting of metadata to simplify code (rhbz#1184929)
+- util: Add helper to convert libxml2 nodes to a string (rhbz#1184929)
+- virsh-domain: use virXMLNodeToString instead of xmlNodeDump (rhbz#1184929)
+- virsh-domain: Add command to allow modifications of XML metadata (rhbz#1184929)
+- conf: Add support for requesting of XML metadata via the API (rhbz#1184929)
+- conf: allow to add XML metadata using the virDomainSetMetadata api (rhbz#1184929)
+- lib: Don't force the key argument when deleting metadata (rhbz#1184929)
+- lxc: Add metadata modification APIs (rhbz#1184929)
+- test: Add <metadata> support into the test driver (rhbz#1184929)
+- tests: Add metadata tests (rhbz#1184929)
+- conf: Don't corrupt metadata on OOM (rhbz#1184929)
+- conf: Avoid false positive of uninitialized variable use (rhbz#1184929)
+- virsh: Don't shadow global variable "remove" in cmdMetadata (rhbz#1184929)
+- metadata: track title edits across libvirtd restart (rhbz#1184929)
+- conf: Improve metadata type verification (rhbz#1184929)
+- Fix possible memory leak in util/virxml.c (rhbz#1184929)
+- util: check for an illegal character in a XML namespace prefix (rhbz#1184929)
+- Fix libvirtd crash when removing metadata (rhbz#1184929)
+
 * Tue Dec  9 2014 Jiri Denemark <jdenemar@redhat.com> - 1.1.1-29.el7_0.4
 - qemu: blockcopy: Don't remove existing disk mirror info (rhbz#1149078)
 - qemu: copy: Accept 'format' parameter when copying to a non-existing img (rhbz#1149078)