diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7677d22
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/libvirt-6.0.0.tar.xz
diff --git a/.libvirt.metadata b/.libvirt.metadata
new file mode 100644
index 0000000..4a2f940
--- /dev/null
+++ b/.libvirt.metadata
@@ -0,0 +1 @@
+9939a559e652d44b27e3404a26bcabe58988e4b4 SOURCES/libvirt-6.0.0.tar.xz
diff --git a/SOURCES/libvirt-RHEL-Add-rhel-machine-types-to-qemuDomainMachineNeedsFDC.patch b/SOURCES/libvirt-RHEL-Add-rhel-machine-types-to-qemuDomainMachineNeedsFDC.patch
new file mode 100644
index 0000000..763b437
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-Add-rhel-machine-types-to-qemuDomainMachineNeedsFDC.patch
@@ -0,0 +1,36 @@
+From a04fcb5b463c90c47705ca0f28e40b73c00b6b72 Mon Sep 17 00:00:00 2001
+Message-Id: <a04fcb5b463c90c47705ca0f28e40b73c00b6b72@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Mon, 22 Feb 2016 12:51:51 +0100
+Subject: [PATCH] RHEL: Add rhel machine types to qemuDomainMachineNeedsFDC
+
+RHEL-only.
+
+pc-q35-rhel7.0.0 and pc-q35-rhel7.1.0 do not need an explicit
+isa-fdc controller.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1227880
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_domain.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index a6dde15bad..0edf316fff 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -12631,6 +12631,10 @@ qemuDomainMachineNeedsFDC(const char *machine,
+         return false;
+     }
+ 
++    if (STRPREFIX(p, "rhel7.0.0") ||
++        STRPREFIX(p, "rhel7.1.0"))
++        return false;
++
+     return true;
+ }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-Fix-virConnectGetMaxVcpus-output.patch b/SOURCES/libvirt-RHEL-Fix-virConnectGetMaxVcpus-output.patch
new file mode 100644
index 0000000..345c0b2
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-Fix-virConnectGetMaxVcpus-output.patch
@@ -0,0 +1,46 @@
+From 3e50b013277c7fa05987ceba440f8c4583b6c634 Mon Sep 17 00:00:00 2001
+Message-Id: <3e50b013277c7fa05987ceba440f8c4583b6c634@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Mon, 27 Aug 2018 13:09:38 +0200
+Subject: [PATCH] RHEL: Fix virConnectGetMaxVcpus output
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1092363
+
+RHEL-only.
+
+Ignore the maximum vcpu limit (KVM_CAP_MAX_VCPUS) on RHEL,
+since RHEL QEMU treats the recommended limit (KVM_CAP_NR_VCPUS)
+as the maximum, see:
+https://bugzilla.redhat.com/show_bug.cgi?id=998708
+
+(cherry picked from commit 7dff909fa34bdd93ad200dbffe70c0c1ee931925)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+
+https: //bugzilla.redhat.com/show_bug.cgi?id=1582222
+Reviewed-by: Andrea Bolognani <abologna@redhat.com>
+---
+ src/util/virhostcpu.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
+index 7f14340f49..256976cce1 100644
+--- a/src/util/virhostcpu.c
++++ b/src/util/virhostcpu.c
+@@ -1169,6 +1169,11 @@ virHostCPUGetKVMMaxVCPUs(void)
+         return -1;
+     }
+ 
++/* Ignore KVM_CAP_MAX_VCPUS on RHEL - the recommended maximum
++ * is treated as a hard limit.
++ */
++# undef KVM_CAP_MAX_VCPUS
++
+ # ifdef KVM_CAP_MAX_VCPUS
+     /* at first try KVM_CAP_MAX_VCPUS to determine the maximum count */
+     if ((ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS)) > 0)
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-Hack-around-changed-Broadwell-Haswell-CPUs.patch b/SOURCES/libvirt-RHEL-Hack-around-changed-Broadwell-Haswell-CPUs.patch
new file mode 100644
index 0000000..12d8958
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-Hack-around-changed-Broadwell-Haswell-CPUs.patch
@@ -0,0 +1,190 @@
+From 0dd015e1aff1a56a4584824d1a97c9eacabf7f03 Mon Sep 17 00:00:00 2001
+Message-Id: <0dd015e1aff1a56a4584824d1a97c9eacabf7f03@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Fri, 27 Mar 2015 12:48:40 +0100
+Subject: [PATCH] RHEL: Hack around changed Broadwell/Haswell CPUs
+
+RHEL-only
+
+Upstream tried to solve the change of Broadwell and Haswell CPUs by
+removing rtm and hle features from the corresponding CPU models for new
+machine types. Then they reverted this and introduced new *-noTSX models
+instead. However, the original fix was backported to RHEL.
+
+This patch makes sure Broadwell and Haswell will always contain rtm and
+hle features regardless on RHEL version or machine type used.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1199446
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_command.c                       | 21 +++++++++++++++++++
+ tests/qemuxml2argvdata/cpu-Haswell.args       |  2 +-
+ .../qemuxml2argvdata/cpu-host-model-cmt.args  |  2 +-
+ .../cpu-translation.x86_64-4.0.0.args         |  4 ++--
+ .../cpu-translation.x86_64-latest.args        |  4 ++--
+ tests/qemuxml2argvdata/cpu-tsc-frequency.args |  4 ++--
+ tests/qemuxml2argvdata/q35-acpi-nouefi.args   |  2 +-
+ tests/qemuxml2argvdata/q35-acpi-uefi.args     |  2 +-
+ tests/qemuxml2argvdata/q35-noacpi-nouefi.args |  2 +-
+ 9 files changed, 32 insertions(+), 11 deletions(-)
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 904d2beab5..e10cc7fc74 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -6469,6 +6469,8 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
+ {
+     size_t i;
+     virCPUDefPtr cpu = def->cpu;
++    bool hle = false;
++    bool rtm = false;
+ 
+     switch ((virCPUMode) cpu->mode) {
+     case VIR_CPU_MODE_HOST_PASSTHROUGH:
+@@ -6524,6 +6526,11 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
+         virBufferAsprintf(buf, ",vendor=%s", cpu->vendor_id);
+ 
+     for (i = 0; i < cpu->nfeatures; i++) {
++        if (STREQ("rtm", cpu->features[i].name))
++            rtm = true;
++        if (STREQ("hle", cpu->features[i].name))
++            hle = true;
++
+         switch ((virCPUFeaturePolicy) cpu->features[i].policy) {
+         case VIR_CPU_FEATURE_FORCE:
+         case VIR_CPU_FEATURE_REQUIRE:
+@@ -6541,6 +6548,20 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
+         }
+     }
+ 
++    /* Some versions of qemu-kvm in RHEL provide Broadwell and Haswell CPU
++     * models which lack rtm and hle features when used with some machine
++     * types. Let's make sure Broadwell and Haswell will always have these
++     * features. But only if the features were not explicitly mentioned in
++     * the guest CPU definition.
++     */
++    if (STREQ_NULLABLE(cpu->model, "Broadwell") ||
++        STREQ_NULLABLE(cpu->model, "Haswell")) {
++        if (!rtm)
++            qemuBuildCpuFeature(qemuCaps, buf, "rtm", true);
++        if (!hle)
++            qemuBuildCpuFeature(qemuCaps, buf, "hle", true);
++    }
++
+     return 0;
+ }
+ 
+diff --git a/tests/qemuxml2argvdata/cpu-Haswell.args b/tests/qemuxml2argvdata/cpu-Haswell.args
+index a33b16f7ce..d35de5ea58 100644
+--- a/tests/qemuxml2argvdata/cpu-Haswell.args
++++ b/tests/qemuxml2argvdata/cpu-Haswell.args
+@@ -11,7 +11,7 @@ QEMU_AUDIO_DRV=none \
+ -name QEMUGuest1 \
+ -S \
+ -machine pc,accel=kvm,usb=off,dump-guest-core=off \
+--cpu Haswell \
++-cpu Haswell,+rtm,+hle \
+ -m 214 \
+ -realtime mlock=off \
+ -smp 6,sockets=6,cores=1,threads=1 \
+diff --git a/tests/qemuxml2argvdata/cpu-host-model-cmt.args b/tests/qemuxml2argvdata/cpu-host-model-cmt.args
+index 42f969fd62..c8795acb3e 100644
+--- a/tests/qemuxml2argvdata/cpu-host-model-cmt.args
++++ b/tests/qemuxml2argvdata/cpu-host-model-cmt.args
+@@ -12,7 +12,7 @@ QEMU_AUDIO_DRV=none \
+ -S \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off \
+ -cpu Haswell,+vme,+ds,+acpi,+ss,+ht,+tm,+pbe,+dtes64,+monitor,+ds_cpl,+vmx,\
+-+smx,+est,+tm2,+xtpr,+pdcm,+f16c,+rdrand,+pdpe1gb,+abm,+lahf_lm \
+++smx,+est,+tm2,+xtpr,+pdcm,+f16c,+rdrand,+pdpe1gb,+abm,+lahf_lm,+rtm,+hle \
+ -m 214 \
+ -realtime mlock=off \
+ -smp 6,sockets=6,cores=1,threads=1 \
+diff --git a/tests/qemuxml2argvdata/cpu-translation.x86_64-4.0.0.args b/tests/qemuxml2argvdata/cpu-translation.x86_64-4.0.0.args
+index f8e19fca24..08c672fd2c 100644
+--- a/tests/qemuxml2argvdata/cpu-translation.x86_64-4.0.0.args
++++ b/tests/qemuxml2argvdata/cpu-translation.x86_64-4.0.0.args
+@@ -14,8 +14,8 @@ QEMU_AUDIO_DRV=none \
+ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc-i440fx-4.0,accel=tcg,usb=off,dump-guest-core=off \
+ -cpu Haswell,pclmuldq=on,ds_cpl=on,tsc_adjust=on,fxsr_opt=on,lahf_lm=on,\
+-cmp_legacy=on,nodeid_msr=on,perfctr_core=on,perfctr_nb=on,kvm_pv_eoi=on,\
+-kvm_pv_unhalt=on \
++cmp_legacy=on,nodeid_msr=on,perfctr_core=on,perfctr_nb=on,rtm=on,hle=on,\
++kvm_pv_eoi=on,kvm_pv_unhalt=on \
+ -m 214 \
+ -overcommit mem-lock=off \
+ -smp 1,sockets=1,cores=1,threads=1 \
+diff --git a/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args b/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args
+index 9322b826f4..1dbfc9553b 100644
+--- a/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args
+@@ -14,8 +14,8 @@ QEMU_AUDIO_DRV=none \
+ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off \
+ -cpu Haswell,pclmulqdq=on,ds-cpl=on,tsc-adjust=on,fxsr-opt=on,lahf-lm=on,\
+-cmp-legacy=on,nodeid-msr=on,perfctr-core=on,perfctr-nb=on,kvm-pv-eoi=on,\
+-kvm-pv-unhalt=on \
++cmp-legacy=on,nodeid-msr=on,perfctr-core=on,perfctr-nb=on,rtm=on,hle=on,\
++kvm-pv-eoi=on,kvm-pv-unhalt=on \
+ -m 214 \
+ -overcommit mem-lock=off \
+ -smp 1,sockets=1,cores=1,threads=1 \
+diff --git a/tests/qemuxml2argvdata/cpu-tsc-frequency.args b/tests/qemuxml2argvdata/cpu-tsc-frequency.args
+index 55b72b4404..45a777d468 100644
+--- a/tests/qemuxml2argvdata/cpu-tsc-frequency.args
++++ b/tests/qemuxml2argvdata/cpu-tsc-frequency.args
+@@ -12,8 +12,8 @@ QEMU_AUDIO_DRV=none \
+ -S \
+ -machine pc,accel=kvm,usb=off,dump-guest-core=off \
+ -cpu Haswell,+vme,+ds,+acpi,+ss,+ht,+tm,+pbe,+dtes64,+monitor,+ds_cpl,+vmx,\
+-+smx,+est,+tm2,+xtpr,+pdcm,+f16c,+rdrand,+pdpe1gb,+abm,+lahf_lm,+invtsc,\
+-tsc-frequency=3504000000 \
+++smx,+est,+tm2,+xtpr,+pdcm,+f16c,+rdrand,+pdpe1gb,+abm,+lahf_lm,+invtsc,+rtm,\
+++hle,tsc-frequency=3504000000 \
+ -m 214 \
+ -realtime mlock=off \
+ -smp 1,sockets=1,cores=1,threads=1 \
+diff --git a/tests/qemuxml2argvdata/q35-acpi-nouefi.args b/tests/qemuxml2argvdata/q35-acpi-nouefi.args
+index 09e06c96ea..aed56fb1fc 100644
+--- a/tests/qemuxml2argvdata/q35-acpi-nouefi.args
++++ b/tests/qemuxml2argvdata/q35-acpi-nouefi.args
+@@ -11,7 +11,7 @@ QEMU_AUDIO_DRV=none \
+ -name guest \
+ -S \
+ -machine q35,accel=tcg,usb=off,dump-guest-core=off \
+--cpu Haswell \
++-cpu Haswell,+rtm,+hle \
+ -m 1024 \
+ -realtime mlock=off \
+ -smp 1,sockets=1,cores=1,threads=1 \
+diff --git a/tests/qemuxml2argvdata/q35-acpi-uefi.args b/tests/qemuxml2argvdata/q35-acpi-uefi.args
+index d00fe5bc1d..1f4bfe7f87 100644
+--- a/tests/qemuxml2argvdata/q35-acpi-uefi.args
++++ b/tests/qemuxml2argvdata/q35-acpi-uefi.args
+@@ -11,7 +11,7 @@ QEMU_AUDIO_DRV=none \
+ -name guest \
+ -S \
+ -machine q35,accel=tcg,usb=off,dump-guest-core=off \
+--cpu Haswell \
++-cpu Haswell,+rtm,+hle \
+ -drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,\
+ readonly=on \
+ -drive file=/var/lib/libvirt/qemu/nvram/guest_VARS.fd,if=pflash,format=raw,\
+diff --git a/tests/qemuxml2argvdata/q35-noacpi-nouefi.args b/tests/qemuxml2argvdata/q35-noacpi-nouefi.args
+index de34dff1cf..ccea7f91f9 100644
+--- a/tests/qemuxml2argvdata/q35-noacpi-nouefi.args
++++ b/tests/qemuxml2argvdata/q35-noacpi-nouefi.args
+@@ -11,7 +11,7 @@ QEMU_AUDIO_DRV=none \
+ -name guest \
+ -S \
+ -machine q35,accel=tcg,usb=off,dump-guest-core=off \
+--cpu Haswell \
++-cpu Haswell,+rtm,+hle \
+ -m 1024 \
+ -realtime mlock=off \
+ -smp 1,sockets=1,cores=1,threads=1 \
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-qemu-Add-ability-to-set-sgio-values-for-hostdev.patch b/SOURCES/libvirt-RHEL-qemu-Add-ability-to-set-sgio-values-for-hostdev.patch
new file mode 100644
index 0000000..95cd351
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemu-Add-ability-to-set-sgio-values-for-hostdev.patch
@@ -0,0 +1,69 @@
+From fce502cf5233d800479c2efcf7721ab895db8998 Mon Sep 17 00:00:00 2001
+Message-Id: <fce502cf5233d800479c2efcf7721ab895db8998@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Mon, 17 Dec 2018 20:42:30 -0500
+Subject: [PATCH] RHEL: qemu: Add ability to set sgio values for hostdev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1582424
+
+RHEL-only
+
+Add necessary checks in order to allow setting sgio values for a scsi
+host device
+
+Signed-off-by: John Ferlan <jferlan@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit f2cf0ae7bc371c75f6c0e79192711f2b1d201b10)
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_conf.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index b62dd1df52..ce7869e6be 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1810,6 +1810,7 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+     virDomainDiskDefPtr disk = NULL;
+     virDomainHostdevDefPtr hostdev = NULL;
+     g_autofree char *sysfs_path = NULL;
++    g_autofree char *hostdev_path = NULL;
+     const char *path = NULL;
+     int val = -1;
+ 
+@@ -1830,14 +1831,10 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+         if (!qemuIsSharedHostdev(hostdev))
+             return 0;
+ 
+-        if (hostdev->source.subsys.u.scsi.sgio) {
+-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                           _("'sgio' is not supported for SCSI "
+-                             "generic device yet "));
++        if (!(hostdev_path = qemuGetHostdevPath(hostdev)))
+             return -1;
+-        }
+ 
+-        return 0;
++        path = hostdev_path;
+     } else {
+         return 0;
+     }
+@@ -1846,7 +1843,11 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+         return -1;
+ 
+     /* By default, filter the SG_IO commands, i.e. set unpriv_sgio to 0.  */
+-    val = (disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED);
++    if (dev->type == VIR_DOMAIN_DEVICE_DISK)
++        val = (disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED);
++    else
++        val = (hostdev->source.subsys.u.scsi.sgio ==
++               VIR_DOMAIN_DEVICE_SGIO_UNFILTERED);
+ 
+     /* Do not do anything if unpriv_sgio is not supported by the kernel and the
+      * whitelist is enabled.  But if requesting unfiltered access, always call
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-qemu-Add-check-for-unpriv-sgio-for-SCSI-generic-host-device.patch b/SOURCES/libvirt-RHEL-qemu-Add-check-for-unpriv-sgio-for-SCSI-generic-host-device.patch
new file mode 100644
index 0000000..5f0af94
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemu-Add-check-for-unpriv-sgio-for-SCSI-generic-host-device.patch
@@ -0,0 +1,67 @@
+From 5a192657ad4e08fc773fef90c6b07df3620fa1c2 Mon Sep 17 00:00:00 2001
+Message-Id: <5a192657ad4e08fc773fef90c6b07df3620fa1c2@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Mon, 17 Dec 2018 20:42:31 -0500
+Subject: [PATCH] RHEL: qemu: Add check for unpriv sgio for SCSI generic host
+ device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1582424
+
+RHEL-only
+
+Check if the hostdev has set the sgio filtered/unfiltered and handle
+appropriately.
+
+This restores functionality removed by upstream commit id 'ce346623'
+to remove sgio support for the SCSI generic host device.
+
+Signed-off-by: John Ferlan <jferlan@redhat.com>
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 712005bcf26190dc6fd1fe56283377987909cc4b)
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_conf.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index ce7869e6be..2a84972fd9 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1717,13 +1717,29 @@ qemuSharedHostdevAddRemoveInternal(virQEMUDriverPtr driver,
+ {
+     g_autofree char *dev_path = NULL;
+     g_autofree char *key = NULL;
++    virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
++    virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
+     int ret = -1;
+ 
+     if (!qemuIsSharedHostdev(hostdev))
+         return 0;
+ 
+-    if (!(dev_path = qemuGetHostdevPath(hostdev)) ||
+-        !(key = qemuGetSharedDeviceKey(dev_path)))
++    if (!(dev_path = qemuGetHostdevPath(hostdev)))
++        return -1;
++
++    if ((ret = qemuCheckUnprivSGIO(driver->sharedDevices, dev_path,
++                                   scsisrc->sgio)) < 0) {
++        if (ret == -2) {
++            virReportError(VIR_ERR_OPERATION_INVALID,
++                           _("sgio of shared scsi host device '%s-%u-%u-%llu' "
++                             "conflicts with other active domains"),
++                           scsihostsrc->adapter, scsihostsrc->bus,
++                           scsihostsrc->target, scsihostsrc->unit);
++        }
++        return -1;
++    }
++
++    if (!(key = qemuGetSharedDeviceKey(dev_path)))
+         return -1;
+ 
+     qemuDriverLock(driver);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-qemu-Alter-qemuSetUnprivSGIO-hostdev-shareable-logic.patch b/SOURCES/libvirt-RHEL-qemu-Alter-qemuSetUnprivSGIO-hostdev-shareable-logic.patch
new file mode 100644
index 0000000..2b30707
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemu-Alter-qemuSetUnprivSGIO-hostdev-shareable-logic.patch
@@ -0,0 +1,53 @@
+From e79d54ff8e760ac1a200a37fb05cc9aa758c48d3 Mon Sep 17 00:00:00 2001
+Message-Id: <e79d54ff8e760ac1a200a37fb05cc9aa758c48d3@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Mon, 17 Dec 2018 20:42:33 -0500
+Subject: [PATCH] RHEL: qemu: Alter qemuSetUnprivSGIO hostdev shareable logic
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1656362 (RHEL8)
+https://bugzilla.redhat.com/show_bug.cgi?id=1656360 (RHEL7)
+
+RHEL-only
+
+Fix the logic to handle the case where if the <shareable/> element
+was removed from the domain <hostdev.../>, then we have to reset the
+SGIO value back to 0. Without this patch the check for not shareable
+and return 0 would bypass resetting the value back to 0.
+
+Signed-off-by: John Ferlan <jferlan@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_conf.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index faabc4d49f..590052b035 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1844,9 +1844,6 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+     } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+         hostdev = dev->data.hostdev;
+ 
+-        if (!qemuIsSharedHostdev(hostdev))
+-            return 0;
+-
+         if (!(hostdev_path = qemuGetHostdevPath(hostdev)))
+             return -1;
+ 
+@@ -1863,7 +1860,9 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+         disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED) {
+         val = 1;
+     } else {
+-        if (hostdev->source.subsys.u.scsi.sgio ==
++        /* Only settable if <shareable/> was present for hostdev */
++        if (qemuIsSharedHostdev(hostdev) &&
++            hostdev->source.subsys.u.scsi.sgio ==
+             VIR_DOMAIN_DEVICE_SGIO_UNFILTERED)
+             val = 1;
+     }
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-qemu-Alter-val-usage-in-qemuSetUnprivSGIO.patch b/SOURCES/libvirt-RHEL-qemu-Alter-val-usage-in-qemuSetUnprivSGIO.patch
new file mode 100644
index 0000000..850b5ab
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemu-Alter-val-usage-in-qemuSetUnprivSGIO.patch
@@ -0,0 +1,60 @@
+From fa46b5b4d5bb732462d0d5484cc010aa652d821b Mon Sep 17 00:00:00 2001
+Message-Id: <fa46b5b4d5bb732462d0d5484cc010aa652d821b@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Mon, 17 Dec 2018 20:42:32 -0500
+Subject: [PATCH] RHEL: qemu: Alter @val usage in qemuSetUnprivSGIO
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1656362 (RHEL8)
+https://bugzilla.redhat.com/show_bug.cgi?id=1656360 (RHEL7)
+
+RHEL-only
+
+Rather than initializing to -1 and then setting to the result
+of a boolean check (either 0 or 1), let's just initialize @val
+to 0 and then only change to 1 if conditions are "right".
+
+Signed-off-by: John Ferlan <jferlan@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_conf.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 2a84972fd9..faabc4d49f 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1828,7 +1828,7 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+     g_autofree char *sysfs_path = NULL;
+     g_autofree char *hostdev_path = NULL;
+     const char *path = NULL;
+-    int val = -1;
++    int val = 0;
+ 
+     /* "sgio" is only valid for block disk; cdrom
+      * and floopy disk can have empty source.
+@@ -1859,11 +1859,14 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+         return -1;
+ 
+     /* By default, filter the SG_IO commands, i.e. set unpriv_sgio to 0.  */
+-    if (dev->type == VIR_DOMAIN_DEVICE_DISK)
+-        val = (disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED);
+-    else
+-        val = (hostdev->source.subsys.u.scsi.sgio ==
+-               VIR_DOMAIN_DEVICE_SGIO_UNFILTERED);
++    if (dev->type == VIR_DOMAIN_DEVICE_DISK &&
++        disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED) {
++        val = 1;
++    } else {
++        if (hostdev->source.subsys.u.scsi.sgio ==
++            VIR_DOMAIN_DEVICE_SGIO_UNFILTERED)
++            val = 1;
++    }
+ 
+     /* Do not do anything if unpriv_sgio is not supported by the kernel and the
+      * whitelist is enabled.  But if requesting unfiltered access, always call
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-qemu-Fix-crash-trying-to-use-iSCSI-hostdev.patch b/SOURCES/libvirt-RHEL-qemu-Fix-crash-trying-to-use-iSCSI-hostdev.patch
new file mode 100644
index 0000000..e0bc6a1
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemu-Fix-crash-trying-to-use-iSCSI-hostdev.patch
@@ -0,0 +1,45 @@
+From 163740bff28c6f1a82663bc652f2cd5df39e4276 Mon Sep 17 00:00:00 2001
+Message-Id: <163740bff28c6f1a82663bc652f2cd5df39e4276@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Fri, 25 Jan 2019 12:19:12 -0500
+Subject: [PATCH] RHEL: qemu: Fix crash trying to use iSCSI hostdev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1669424
+https://bugzilla.redhat.com/show_bug.cgi?id=1669966
+
+RHEL-only
+
+Commit 861a1a4d2 moved the qemuIsSharedHostdev filter in the
+HOSTDEV half of the logic to allow calling qemuGetHostdevPath;
+however, that neglected to check whether the SCSI hostdev was
+using the iSCSI protocol which has a different overlayed struct
+format (u.iscsi vs. u.host) resulting in attempted access of
+u.host when calling virSCSIDeviceGetDevName.
+
+Signed-off-by: John Ferlan <jferlan@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_conf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 0674292fab..3d2f0e7bbb 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1844,6 +1844,10 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+     } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+         hostdev = dev->data.hostdev;
+ 
++        if (hostdev->source.subsys.u.scsi.protocol ==
++            VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
++            return 0;
++
+         if (!(hostdev_path = qemuGetHostdevPath(hostdev)))
+             return -1;
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-qemu-Fix-logic-error-in-qemuSetUnprivSGIO.patch b/SOURCES/libvirt-RHEL-qemu-Fix-logic-error-in-qemuSetUnprivSGIO.patch
new file mode 100644
index 0000000..b4d84ed
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemu-Fix-logic-error-in-qemuSetUnprivSGIO.patch
@@ -0,0 +1,59 @@
+From f6a05ac3cb33c473de8ed49b53d22910fc0140df Mon Sep 17 00:00:00 2001
+Message-Id: <f6a05ac3cb33c473de8ed49b53d22910fc0140df@dist-git>
+From: John Ferlan <jferlan@redhat.com>
+Date: Wed, 16 Jan 2019 15:54:31 -0500
+Subject: [PATCH] RHEL: qemu: Fix logic error in qemuSetUnprivSGIO
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1666605
+
+RHEL-only
+
+Commit c0f26a13c6 had a logic error with using both DISK and
+sgio which resulted in a DISK that didn't have sgio set falling
+into the else clause and trying to deref a NULL @hostdev resulting
+in a libvirtd crash:
+
+Thread 1 (Thread 0x7ffbc6353700 (LWP 12642)):
+ 0  0x00007ffb958e7d7a in qemuSetUnprivSGIO
+ 1  0x00007ffb958d9d92 in qemuDomainAttachDeviceDiskLive
+ 2  0x00007ffb9594fce8 in qemuDomainAttachDeviceFlags
+ 3  0x00007ffbde399d71 in virDomainAttachDevice
+ 4  0x0000563b73ded4b2 in remoteDispatchDomainAttachDeviceHelper
+
+for hotplug of XML:
+
+<disk device="lun" type="block">
+  <source dev="/dev/sdb"/>
+  <driver name="qemu" type="raw"/>
+  <target bus="scsi" dev="sdb"/>
+</disk>
+
+Signed-off-by: John Ferlan <jferlan@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_conf.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 590052b035..0674292fab 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1856,9 +1856,9 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+         return -1;
+ 
+     /* By default, filter the SG_IO commands, i.e. set unpriv_sgio to 0.  */
+-    if (dev->type == VIR_DOMAIN_DEVICE_DISK &&
+-        disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED) {
+-        val = 1;
++    if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
++        if (disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED)
++            val = 1;
+     } else {
+         /* Only settable if <shareable/> was present for hostdev */
+         if (qemuIsSharedHostdev(hostdev) &&
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-RHEL-qemuCheckUnprivSGIO-use-sysfs_path-to-get-unpriv_sgio.patch b/SOURCES/libvirt-RHEL-qemuCheckUnprivSGIO-use-sysfs_path-to-get-unpriv_sgio.patch
new file mode 100644
index 0000000..d9855b0
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemuCheckUnprivSGIO-use-sysfs_path-to-get-unpriv_sgio.patch
@@ -0,0 +1,42 @@
+From ef5a82d50464478a302cb59804d03e4a3dada83e Mon Sep 17 00:00:00 2001
+Message-Id: <ef5a82d50464478a302cb59804d03e4a3dada83e@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 6 Mar 2020 15:52:26 +0100
+Subject: [PATCH] RHEL: qemuCheckUnprivSGIO: use @sysfs_path to get unpriv_sgio
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Downstream commit 65f4ff0e2c9a968b7ec65c8d751d4055cc212628
+  RHEL: qemuSetUnprivSGIO: Actually use calculated
+    @sysfs_path to set unpriv_sgio
+removed the device_path -> sysfs_path conversion from
+both virGetDeviceUnprivSGIO and virSetDeviceUnprivSGIO,
+but only adjusted one of the callers.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808400
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200306145226.1610708-7-abologna@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_conf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index b61d7e59fa..6a22d78ac6 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1430,7 +1430,7 @@ qemuCheckUnprivSGIO(virHashTablePtr sharedDevices,
+     if (!(virHashLookup(sharedDevices, key)))
+         return 0;
+ 
+-    if (virGetDeviceUnprivSGIO(device_path, &val) < 0)
++    if (virGetDeviceUnprivSGIO(sysfs_path, &val) < 0)
+         return -1;
+ 
+     /* Error message on failure needs to be handled in caller
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-RHEL-qemuSetUnprivSGIO-Actually-use-calculated-sysfs_path-to-set-unpriv_sgio.patch b/SOURCES/libvirt-RHEL-qemuSetUnprivSGIO-Actually-use-calculated-sysfs_path-to-set-unpriv_sgio.patch
new file mode 100644
index 0000000..b4ed1ae
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-qemuSetUnprivSGIO-Actually-use-calculated-sysfs_path-to-set-unpriv_sgio.patch
@@ -0,0 +1,170 @@
+From 717423e7a452b0715e95b492b15dc08983677d12 Mon Sep 17 00:00:00 2001
+Message-Id: <717423e7a452b0715e95b492b15dc08983677d12@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 6 Mar 2020 15:52:25 +0100
+Subject: [PATCH] RHEL: qemuSetUnprivSGIO: Actually use calculated @sysfs_path
+ to set unpriv_sgio
+
+In previous commits I've attempted to make qemuSetUnprivSGIO()
+construct a generic enough path for SCSI devices to set
+unpriv_sgio. However, virSetDeviceUnprivSGIO() does not care
+about that - it constructs the path on it's own again. This is
+suboptimal in either case - we already have the path constructed.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808390
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200306145226.1610708-6-abologna@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_conf.c |  8 +++-----
+ src/util/virutil.c   | 24 ++++++------------------
+ src/util/virutil.h   |  2 --
+ 3 files changed, 9 insertions(+), 25 deletions(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 6d6feb97cd..b61d7e59fa 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1430,7 +1430,7 @@ qemuCheckUnprivSGIO(virHashTablePtr sharedDevices,
+     if (!(virHashLookup(sharedDevices, key)))
+         return 0;
+ 
+-    if (virGetDeviceUnprivSGIO(device_path, NULL, &val) < 0)
++    if (virGetDeviceUnprivSGIO(device_path, &val) < 0)
+         return -1;
+ 
+     /* Error message on failure needs to be handled in caller
+@@ -1789,7 +1789,6 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+     virDomainDiskDefPtr disk = NULL;
+     virDomainHostdevDefPtr hostdev = NULL;
+     g_autofree char *sysfs_path = NULL;
+-    const char *path = NULL;
+     int val = 0;
+ 
+     /* "sgio" is only valid for block disk; cdrom
+@@ -1797,13 +1796,12 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+      */
+     if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+         disk = dev->data.disk;
++        const char *path = virDomainDiskGetSource(disk);
+ 
+         if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN ||
+             !virStorageSourceIsBlockLocal(disk->src))
+             return 0;
+ 
+-        path = virDomainDiskGetSource(disk);
+-
+         if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, NULL)))
+             return -1;
+ 
+@@ -1843,7 +1841,7 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+      * virSetDeviceUnprivSGIO, to report an error for unsupported unpriv_sgio.
+      */
+     if ((virFileExists(sysfs_path) || val == 1) &&
+-        virSetDeviceUnprivSGIO(path, NULL, val) < 0)
++        virSetDeviceUnprivSGIO(sysfs_path, val) < 0)
+         return -1;
+ 
+     return 0;
+diff --git a/src/util/virutil.c b/src/util/virutil.c
+index f142951acf..4198473fce 100644
+--- a/src/util/virutil.c
++++ b/src/util/virutil.c
+@@ -1421,18 +1421,13 @@ virGetUnprivSGIOSysfsPath(const char *path,
+ 
+ int
+ virSetDeviceUnprivSGIO(const char *path,
+-                       const char *sysfs_dir,
+                        int unpriv_sgio)
+ {
+-    char *sysfs_path = NULL;
+     char *val = NULL;
+     int ret = -1;
+     int rc;
+ 
+-    if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, sysfs_dir)))
+-        return -1;
+-
+-    if (!virFileExists(sysfs_path)) {
++    if (!virFileExists(path)) {
+         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                        _("unpriv_sgio is not supported by this kernel"));
+         goto cleanup;
+@@ -1440,38 +1435,32 @@ virSetDeviceUnprivSGIO(const char *path,
+ 
+     val = g_strdup_printf("%d", unpriv_sgio);
+ 
+-    if ((rc = virFileWriteStr(sysfs_path, val, 0)) < 0) {
+-        virReportSystemError(-rc, _("failed to set %s"), sysfs_path);
++    if ((rc = virFileWriteStr(path, val, 0)) < 0) {
++        virReportSystemError(-rc, _("failed to set %s"), path);
+         goto cleanup;
+     }
+ 
+     ret = 0;
+  cleanup:
+-    VIR_FREE(sysfs_path);
+     VIR_FREE(val);
+     return ret;
+ }
+ 
+ int
+ virGetDeviceUnprivSGIO(const char *path,
+-                       const char *sysfs_dir,
+                        int *unpriv_sgio)
+ {
+-    char *sysfs_path = NULL;
+     char *buf = NULL;
+     char *tmp = NULL;
+     int ret = -1;
+ 
+-    if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, sysfs_dir)))
+-        return -1;
+-
+-    if (!virFileExists(sysfs_path)) {
++    if (!virFileExists(path)) {
+         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                        _("unpriv_sgio is not supported by this kernel"));
+         goto cleanup;
+     }
+ 
+-    if (virFileReadAll(sysfs_path, 1024, &buf) < 0)
++    if (virFileReadAll(path, 1024, &buf) < 0)
+         goto cleanup;
+ 
+     if ((tmp = strchr(buf, '\n')))
+@@ -1479,13 +1468,12 @@ virGetDeviceUnprivSGIO(const char *path,
+ 
+     if (virStrToLong_i(buf, NULL, 10, unpriv_sgio) < 0) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("failed to parse value of %s"), sysfs_path);
++                       _("failed to parse value of %s"), path);
+         goto cleanup;
+     }
+ 
+     ret = 0;
+  cleanup:
+-    VIR_FREE(sysfs_path);
+     VIR_FREE(buf);
+     return ret;
+ }
+diff --git a/src/util/virutil.h b/src/util/virutil.h
+index 1a6ae1787a..a2530e21b5 100644
+--- a/src/util/virutil.h
++++ b/src/util/virutil.h
+@@ -124,10 +124,8 @@ int virGetDeviceID(const char *path,
+                    int *maj,
+                    int *min);
+ int virSetDeviceUnprivSGIO(const char *path,
+-                           const char *sysfs_dir,
+                            int unpriv_sgio);
+ int virGetDeviceUnprivSGIO(const char *path,
+-                           const char *sysfs_dir,
+                            int *unpriv_sgio);
+ char *virGetUnprivSGIOSysfsPath(const char *path,
+                                 const char *sysfs_dir);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-RHEL-virscsi-Check-device-type-before-getting-it-s-dev-node-name.patch b/SOURCES/libvirt-RHEL-virscsi-Check-device-type-before-getting-it-s-dev-node-name.patch
new file mode 100644
index 0000000..f371ff8
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-virscsi-Check-device-type-before-getting-it-s-dev-node-name.patch
@@ -0,0 +1,228 @@
+From f66beef45382be2aed6d021a409e90f8114c8671 Mon Sep 17 00:00:00 2001
+Message-Id: <f66beef45382be2aed6d021a409e90f8114c8671@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 6 Mar 2020 15:52:21 +0100
+Subject: [PATCH] RHEL: virscsi: Check device type before getting it's /dev
+ node name
+
+Not all SCSI devices are block devices, therefore
+/sys/bus/scsi/devices/X:X:X:X/block/ directory does not always
+exist. Check if the SCSI device is a block device beforehand.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808390
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200306145226.1610708-2-abologna@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virscsi.c             | 146 ++++++++++++++++++++++++++++++---
+ tests/virscsidata/0-0-0-0/type |   1 +
+ tests/virscsidata/1-0-0-0/type |   1 +
+ 3 files changed, 137 insertions(+), 11 deletions(-)
+ create mode 100644 tests/virscsidata/0-0-0-0/type
+ create mode 100644 tests/virscsidata/1-0-0-0/type
+
+diff --git a/src/util/virscsi.c b/src/util/virscsi.c
+index 06659c45c7..c40857977f 100644
+--- a/src/util/virscsi.c
++++ b/src/util/virscsi.c
+@@ -50,6 +50,32 @@ struct _virUsedByInfo {
+ typedef struct _virUsedByInfo virUsedByInfo;
+ typedef virUsedByInfo *virUsedByInfoPtr;
+ 
++
++/* Keep in sync with scsi/scsi_proto.h */
++typedef enum {
++    VIR_SCSI_DEVICE_TYPE_NONE = -1,
++    VIR_SCSI_DEVICE_TYPE_DISK = 0x00,
++    VIR_SCSI_DEVICE_TYPE_TAPE = 0x01,
++    VIR_SCSI_DEVICE_TYPE_PRINTER = 0x02,
++    VIR_SCSI_DEVICE_TYPE_PROCESSOR = 0x03,
++    VIR_SCSI_DEVICE_TYPE_WORM = 0x04,
++    VIR_SCSI_DEVICE_TYPE_ROM = 0x05,
++    VIR_SCSI_DEVICE_TYPE_SCANNER = 0x06,
++    VIR_SCSI_DEVICE_TYPE_MOD = 0x07,
++    VIR_SCSI_DEVICE_TYPE_MEDIUM_CHANGER = 0x08,
++    VIR_SCSI_DEVICE_TYPE_COMM = 0x09,
++    VIR_SCSI_DEVICE_TYPE_RAID = 0x0c,
++    VIR_SCSI_DEVICE_TYPE_ENCLOSURE = 0x0d,
++    VIR_SCSI_DEVICE_TYPE_RBC = 0x0e,
++    VIR_SCSI_DEVICE_TYPE_OSD = 0x11,
++    VIR_SCSI_DEVICE_TYPE_ZBC = 0x14,
++    VIR_SCSI_DEVICE_TYPE_WLUN = 0x1e,
++    VIR_SCSI_DEVICE_TYPE_NO_LUN = 0x7f,
++
++    VIR_SCSI_DEVICE_TYPE_LAST,
++} virSCSIDeviceType;
++
++
+ struct _virSCSIDevice {
+     unsigned int adapter;
+     unsigned int bus;
+@@ -134,6 +160,84 @@ virSCSIDeviceGetSgName(const char *sysfs_prefix,
+     return sg;
+ }
+ 
++
++static int
++virSCSIDeviceGetType(const char *prefix,
++                     unsigned int adapter,
++                     unsigned int bus,
++                     unsigned int target,
++                     unsigned long long unit,
++                     virSCSIDeviceType *type)
++{
++    int intType;
++
++    if (virFileReadValueInt(&intType,
++                            "%s/%d:%u:%u:%llu/type",
++                            prefix, adapter, bus, target, unit) < 0)
++        return -1;
++
++    switch (intType) {
++    case VIR_SCSI_DEVICE_TYPE_DISK:
++    case VIR_SCSI_DEVICE_TYPE_TAPE:
++    case VIR_SCSI_DEVICE_TYPE_PRINTER:
++    case VIR_SCSI_DEVICE_TYPE_PROCESSOR:
++    case VIR_SCSI_DEVICE_TYPE_WORM:
++    case VIR_SCSI_DEVICE_TYPE_ROM:
++    case VIR_SCSI_DEVICE_TYPE_SCANNER:
++    case VIR_SCSI_DEVICE_TYPE_MOD:
++    case VIR_SCSI_DEVICE_TYPE_MEDIUM_CHANGER:
++    case VIR_SCSI_DEVICE_TYPE_COMM:
++    case VIR_SCSI_DEVICE_TYPE_RAID:
++    case VIR_SCSI_DEVICE_TYPE_ENCLOSURE:
++    case VIR_SCSI_DEVICE_TYPE_RBC:
++    case VIR_SCSI_DEVICE_TYPE_OSD:
++    case VIR_SCSI_DEVICE_TYPE_ZBC:
++    case VIR_SCSI_DEVICE_TYPE_WLUN:
++    case VIR_SCSI_DEVICE_TYPE_NO_LUN:
++        *type = intType;
++        break;
++
++    default:
++        virReportError(VIR_ERR_INTERNAL_ERROR,
++                       _("unknown SCSI device type: %x"),
++                       intType);
++        return -1;
++    }
++
++    return 0;
++}
++
++
++static char *
++virSCSIDeviceGetDevNameBlock(const char *prefix,
++                             unsigned int adapter,
++                             unsigned int bus,
++                             unsigned int target,
++                             unsigned long long unit)
++{
++    DIR *dir = NULL;
++    struct dirent *entry;
++    g_autofree char *path = NULL;
++    char *name = NULL;
++
++    path = g_strdup_printf("%s/%d:%u:%u:%llu/block",
++                           prefix, adapter, bus, target, unit);
++
++    if (virDirOpen(&dir, path) < 0)
++        goto cleanup;
++
++    while (virDirRead(dir, &entry, path) > 0) {
++        name = g_strdup(entry->d_name);
++        break;
++    }
++
++ cleanup:
++    VIR_DIR_CLOSE(dir);
++
++    return name;
++}
++
++
+ /* Returns device name (e.g. "sdc") on success, or NULL
+  * on failure.
+  */
+@@ -144,32 +248,52 @@ virSCSIDeviceGetDevName(const char *sysfs_prefix,
+                         unsigned int target,
+                         unsigned long long unit)
+ {
+-    DIR *dir = NULL;
+-    struct dirent *entry;
+-    g_autofree char *path = NULL;
+     char *name = NULL;
+     unsigned int adapter_id;
++    virSCSIDeviceType type;
+     const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_DEVICES;
+ 
+     if (virSCSIDeviceGetAdapterId(adapter, &adapter_id) < 0)
+         return NULL;
+ 
+-    path = g_strdup_printf("%s/%d:%u:%u:%llu/block", prefix, adapter_id, bus,
+-                           target, unit);
++    if (virSCSIDeviceGetType(prefix, adapter_id,
++                             bus, target, unit, &type) < 0)
++        return NULL;
+ 
+-    if (virDirOpen(&dir, path) < 0)
+-        goto cleanup;
++    switch (type) {
++    case VIR_SCSI_DEVICE_TYPE_DISK:
++        name = virSCSIDeviceGetDevNameBlock(prefix, adapter_id, bus, target, unit);
++        break;
+ 
+-    while (virDirRead(dir, &entry, path) > 0) {
+-        name = g_strdup(entry->d_name);
++    case VIR_SCSI_DEVICE_TYPE_TAPE:
++    case VIR_SCSI_DEVICE_TYPE_PRINTER:
++    case VIR_SCSI_DEVICE_TYPE_PROCESSOR:
++    case VIR_SCSI_DEVICE_TYPE_WORM:
++    case VIR_SCSI_DEVICE_TYPE_ROM:
++    case VIR_SCSI_DEVICE_TYPE_SCANNER:
++    case VIR_SCSI_DEVICE_TYPE_MOD:
++    case VIR_SCSI_DEVICE_TYPE_MEDIUM_CHANGER:
++    case VIR_SCSI_DEVICE_TYPE_COMM:
++    case VIR_SCSI_DEVICE_TYPE_RAID:
++    case VIR_SCSI_DEVICE_TYPE_ENCLOSURE:
++    case VIR_SCSI_DEVICE_TYPE_RBC:
++    case VIR_SCSI_DEVICE_TYPE_OSD:
++    case VIR_SCSI_DEVICE_TYPE_ZBC:
++    case VIR_SCSI_DEVICE_TYPE_WLUN:
++    case VIR_SCSI_DEVICE_TYPE_NO_LUN:
++    case VIR_SCSI_DEVICE_TYPE_NONE:
++    case VIR_SCSI_DEVICE_TYPE_LAST:
++    default:
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                       _("unsupported SCSI device type: %x"),
++                       type);
+         break;
+     }
+ 
+- cleanup:
+-    VIR_DIR_CLOSE(dir);
+     return name;
+ }
+ 
++
+ virSCSIDevicePtr
+ virSCSIDeviceNew(const char *sysfs_prefix,
+                  const char *adapter,
+diff --git a/tests/virscsidata/0-0-0-0/type b/tests/virscsidata/0-0-0-0/type
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virscsidata/0-0-0-0/type
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virscsidata/1-0-0-0/type b/tests/virscsidata/1-0-0-0/type
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virscsidata/1-0-0-0/type
+@@ -0,0 +1 @@
++0
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch b/SOURCES/libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch
new file mode 100644
index 0000000..5feb8f5
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch
@@ -0,0 +1,137 @@
+From c9fc757c867d197c17350b6a9cabc63cc08105d2 Mon Sep 17 00:00:00 2001
+Message-Id: <c9fc757c867d197c17350b6a9cabc63cc08105d2@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 6 Mar 2020 15:52:23 +0100
+Subject: [PATCH] RHEL: virscsi: Introduce and use
+ virSCSIDeviceGetUnprivSGIOSysfsPath()
+
+When constructing a path to the 'unpriv_sgio' file of given SCSI
+device we don't need to go through /dev/* and major() + minor()
+path. The generated path points to
+/sys/dev/block/MAJ:MIN/queue/unpriv_sgio which is wrong if the
+SCSI device in question is not a block device. We can generate a
+different path: /sys/bus/scsi/devices/X:X:X:X/unpriv_sgio where
+the file is directly accessible regardless of the SCSI device
+type.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808390
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200306145226.1610708-4-abologna@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/qemu/qemu_conf.c     | 18 +++++++++++-------
+ src/util/virscsi.c       | 18 ++++++++++++++++++
+ src/util/virscsi.h       |  5 +++++
+ 4 files changed, 35 insertions(+), 7 deletions(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 5dc99e03cf..1f97879faa 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2959,6 +2959,7 @@ virSCSIDeviceGetSgName;
+ virSCSIDeviceGetShareable;
+ virSCSIDeviceGetTarget;
+ virSCSIDeviceGetUnit;
++virSCSIDeviceGetUnprivSGIOSysfsPath;
+ virSCSIDeviceIsAvailable;
+ virSCSIDeviceListAdd;
+ virSCSIDeviceListCount;
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 7aaf2862a4..6d6feb97cd 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1789,7 +1789,6 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+     virDomainDiskDefPtr disk = NULL;
+     virDomainHostdevDefPtr hostdev = NULL;
+     g_autofree char *sysfs_path = NULL;
+-    g_autofree char *hostdev_path = NULL;
+     const char *path = NULL;
+     int val = 0;
+ 
+@@ -1804,24 +1803,29 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev)
+             return 0;
+ 
+         path = virDomainDiskGetSource(disk);
++
++        if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, NULL)))
++            return -1;
++
+     } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
+         hostdev = dev->data.hostdev;
++        virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
++        virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
+ 
+         if (hostdev->source.subsys.u.scsi.protocol ==
+             VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
+             return 0;
+ 
+-        if (!(hostdev_path = qemuGetHostdevPath(hostdev)))
++        if (!(sysfs_path = virSCSIDeviceGetUnprivSGIOSysfsPath(NULL,
++                                                               scsihostsrc->adapter,
++                                                               scsihostsrc->bus,
++                                                               scsihostsrc->target,
++                                                               scsihostsrc->unit)))
+             return -1;
+-
+-        path = hostdev_path;
+     } else {
+         return 0;
+     }
+ 
+-    if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, NULL)))
+-        return -1;
+-
+     /* By default, filter the SG_IO commands, i.e. set unpriv_sgio to 0.  */
+     if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+         if (disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED)
+diff --git a/src/util/virscsi.c b/src/util/virscsi.c
+index 57958c06ea..1bba4051b6 100644
+--- a/src/util/virscsi.c
++++ b/src/util/virscsi.c
+@@ -322,6 +322,24 @@ virSCSIDeviceGetDevName(const char *sysfs_prefix,
+ }
+ 
+ 
++char *
++virSCSIDeviceGetUnprivSGIOSysfsPath(const char *sysfs_prefix,
++                                    const char *adapter,
++                                    unsigned int bus,
++                                    unsigned int target,
++                                    unsigned long long unit)
++{
++    unsigned int adapter_id;
++    const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_DEVICES;
++
++    if (virSCSIDeviceGetAdapterId(adapter, &adapter_id) < 0)
++        return NULL;
++
++    return g_strdup_printf("%s/%d:%u:%u:%llu/unpriv_sgio",
++                           prefix, adapter_id, bus, target, unit);
++}
++
++
+ virSCSIDevicePtr
+ virSCSIDeviceNew(const char *sysfs_prefix,
+                  const char *adapter,
+diff --git a/src/util/virscsi.h b/src/util/virscsi.h
+index 51627e0c05..c040d76716 100644
+--- a/src/util/virscsi.h
++++ b/src/util/virscsi.h
+@@ -42,6 +42,11 @@ char *virSCSIDeviceGetDevName(const char *sysfs_prefix,
+                               unsigned int bus,
+                               unsigned int target,
+                               unsigned long long unit);
++char *virSCSIDeviceGetUnprivSGIOSysfsPath(const char *sysfs_prefix,
++                                          const char *adapter,
++                                          unsigned int bus,
++                                          unsigned int target,
++                                          unsigned long long unit);
+ 
+ virSCSIDevicePtr virSCSIDeviceNew(const char *sysfs_prefix,
+                                   const char *adapter,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-RHEL-virscsi-Support-TAPEs-in-virSCSIDeviceGetDevName.patch b/SOURCES/libvirt-RHEL-virscsi-Support-TAPEs-in-virSCSIDeviceGetDevName.patch
new file mode 100644
index 0000000..7724e4d
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-virscsi-Support-TAPEs-in-virSCSIDeviceGetDevName.patch
@@ -0,0 +1,202 @@
+From c481bcacd1f515d2e93036dc452a25e9ff06f7ae Mon Sep 17 00:00:00 2001
+Message-Id: <c481bcacd1f515d2e93036dc452a25e9ff06f7ae@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 6 Mar 2020 15:52:22 +0100
+Subject: [PATCH] RHEL: virscsi: Support TAPEs in virSCSIDeviceGetDevName()
+
+If the SCSI device we want to get /dev node name for is TAPE
+device we need to look at 'tape' symlink in the sysfs dir
+corresponding to the device.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808390
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200306145226.1610708-3-abologna@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virscsi.c                          | 28 +++++++++++++++
+ tests/virscsidata/2-0-0-0/model             |  1 +
+ tests/virscsidata/2-0-0-0/scsi_tape/st0/dev |  1 +
+ tests/virscsidata/2-0-0-0/sg3/dev           |  1 +
+ tests/virscsidata/2-0-0-0/tape              |  1 +
+ tests/virscsidata/2-0-0-0/type              |  1 +
+ tests/virscsidata/2-0-0-0/vendor            |  1 +
+ tests/virscsidata/sg3                       |  0
+ tests/virscsitest.c                         | 38 ++++++++++++++++++---
+ 9 files changed, 67 insertions(+), 5 deletions(-)
+ create mode 100644 tests/virscsidata/2-0-0-0/model
+ create mode 100644 tests/virscsidata/2-0-0-0/scsi_tape/st0/dev
+ create mode 100644 tests/virscsidata/2-0-0-0/sg3/dev
+ create mode 120000 tests/virscsidata/2-0-0-0/tape
+ create mode 100644 tests/virscsidata/2-0-0-0/type
+ create mode 100644 tests/virscsidata/2-0-0-0/vendor
+ create mode 100644 tests/virscsidata/sg3
+
+diff --git a/src/util/virscsi.c b/src/util/virscsi.c
+index c40857977f..57958c06ea 100644
+--- a/src/util/virscsi.c
++++ b/src/util/virscsi.c
+@@ -238,6 +238,31 @@ virSCSIDeviceGetDevNameBlock(const char *prefix,
+ }
+ 
+ 
++static char *
++virSCSIDeviceGetDevNameTape(const char *prefix,
++                            unsigned int adapter,
++                            unsigned int bus,
++                            unsigned int target,
++                            unsigned long long unit)
++{
++    g_autofree char *path = NULL;
++    g_autofree char *resolvedPath = NULL;
++    g_autoptr(GError) err = NULL;
++
++    path = g_strdup_printf("%s/%d:%u:%u:%llu/tape",
++                           prefix, adapter, bus, target, unit);
++
++    if (!(resolvedPath = g_file_read_link(path, &err))) {
++        virReportError(VIR_ERR_SYSTEM_ERROR,
++                       _("Unable to read link: %s"),
++                       err->message);
++        return NULL;
++    }
++
++    return g_path_get_basename(resolvedPath);
++}
++
++
+ /* Returns device name (e.g. "sdc") on success, or NULL
+  * on failure.
+  */
+@@ -266,6 +291,9 @@ virSCSIDeviceGetDevName(const char *sysfs_prefix,
+         break;
+ 
+     case VIR_SCSI_DEVICE_TYPE_TAPE:
++        name = virSCSIDeviceGetDevNameTape(prefix, adapter_id, bus, target, unit);
++        break;
++
+     case VIR_SCSI_DEVICE_TYPE_PRINTER:
+     case VIR_SCSI_DEVICE_TYPE_PROCESSOR:
+     case VIR_SCSI_DEVICE_TYPE_WORM:
+diff --git a/tests/virscsidata/2-0-0-0/model b/tests/virscsidata/2-0-0-0/model
+new file mode 100644
+index 0000000000..d2ab4715c3
+--- /dev/null
++++ b/tests/virscsidata/2-0-0-0/model
+@@ -0,0 +1 @@
++scsi_debug
+diff --git a/tests/virscsidata/2-0-0-0/scsi_tape/st0/dev b/tests/virscsidata/2-0-0-0/scsi_tape/st0/dev
+new file mode 100644
+index 0000000000..3dd777e840
+--- /dev/null
++++ b/tests/virscsidata/2-0-0-0/scsi_tape/st0/dev
+@@ -0,0 +1 @@
++9:0
+diff --git a/tests/virscsidata/2-0-0-0/sg3/dev b/tests/virscsidata/2-0-0-0/sg3/dev
+new file mode 100644
+index 0000000000..b369a59b3e
+--- /dev/null
++++ b/tests/virscsidata/2-0-0-0/sg3/dev
+@@ -0,0 +1 @@
++21:3
+diff --git a/tests/virscsidata/2-0-0-0/tape b/tests/virscsidata/2-0-0-0/tape
+new file mode 120000
+index 0000000000..6ca7f77539
+--- /dev/null
++++ b/tests/virscsidata/2-0-0-0/tape
+@@ -0,0 +1 @@
++scsi_tape/st0
+\ No newline at end of file
+diff --git a/tests/virscsidata/2-0-0-0/type b/tests/virscsidata/2-0-0-0/type
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virscsidata/2-0-0-0/type
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virscsidata/2-0-0-0/vendor b/tests/virscsidata/2-0-0-0/vendor
+new file mode 100644
+index 0000000000..9b075671ea
+--- /dev/null
++++ b/tests/virscsidata/2-0-0-0/vendor
+@@ -0,0 +1 @@
++Linux
+diff --git a/tests/virscsidata/sg3 b/tests/virscsidata/sg3
+new file mode 100644
+index 0000000000..e69de29bb2
+diff --git a/tests/virscsitest.c b/tests/virscsitest.c
+index d5a0da4753..e501d6d041 100644
+--- a/tests/virscsitest.c
++++ b/tests/virscsitest.c
+@@ -32,18 +32,34 @@ VIR_LOG_INIT("tests.scsitest");
+ 
+ static char *virscsi_prefix;
+ 
++typedef struct {
++    const char *adapter;
++    unsigned int bus;
++    unsigned int target;
++    unsigned int unit;
++    const char *expectedName;
++} testGetDevNameData;
++
+ static int
+-test1(const void *data G_GNUC_UNUSED)
++testGetDevName(const void *opaque)
+ {
++    const testGetDevNameData *data = opaque;
+     char *name = NULL;
+     int ret = -1;
+ 
+     if (!(name = virSCSIDeviceGetDevName(virscsi_prefix,
+-                                         "scsi_host1", 0, 0, 0)))
++                                         data->adapter,
++                                         data->bus,
++                                         data->target,
++                                         data->unit)))
+         return -1;
+ 
+-    if (STRNEQ(name, "sdh"))
++    if (STRNEQ(name, data->expectedName)) {
++        fprintf(stderr,
++                "SCSI dev name mismatch, expected %s got %s",
++                data->expectedName, name);
+         goto cleanup;
++    }
+ 
+     ret = 0;
+  cleanup:
+@@ -212,15 +228,27 @@ mymain(void)
+ 
+     CREATE_SYMLINK("0-0-0-0", "0:0:0:0");
+     CREATE_SYMLINK("1-0-0-0", "1:0:0:0");
++    CREATE_SYMLINK("2-0-0-0", "2:0:0:0");
+     CREATE_SYMLINK("sg0", "sg0");
++    CREATE_SYMLINK("sg3", "sg3");
+     CREATE_SYMLINK("sg8", "sg8");
+ 
+     VIR_FREE(virscsi_prefix);
+ 
+     virscsi_prefix = g_strdup(tmpdir);
+ 
+-    if (virTestRun("test1", test1, NULL) < 0)
+-        ret = -1;
++#define TEST_GET_DEV_NAME(adapter, bus, target, unit, expectedName) \
++    do { \
++        testGetDevNameData data = {adapter, bus, target, unit, expectedName}; \
++        if (virTestRun("test getDevname " expectedName, \
++                       testGetDevName, &data) < 0) \
++            ret = -1; \
++    } while (0)
++
++    TEST_GET_DEV_NAME("scsi_host0", 0, 0, 0, "sda");
++    TEST_GET_DEV_NAME("scsi_host1", 0, 0, 0, "sdh");
++    TEST_GET_DEV_NAME("scsi_host2", 0, 0, 0, "st0");
++
+     if (virTestRun("test2", test2, NULL) < 0)
+         ret = -1;
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-RHEL-virutil-Accept-non-block-devices-in-virGetDeviceID.patch b/SOURCES/libvirt-RHEL-virutil-Accept-non-block-devices-in-virGetDeviceID.patch
new file mode 100644
index 0000000..4568177
--- /dev/null
+++ b/SOURCES/libvirt-RHEL-virutil-Accept-non-block-devices-in-virGetDeviceID.patch
@@ -0,0 +1,37 @@
+From cd2640c256389b4041e4cd38fd72f77184bb4414 Mon Sep 17 00:00:00 2001
+Message-Id: <cd2640c256389b4041e4cd38fd72f77184bb4414@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 6 Mar 2020 15:52:24 +0100
+Subject: [PATCH] RHEL: virutil: Accept non-block devices in virGetDeviceID()
+
+If a caller wants to learn major or minor number for a device,
+let them. There's no need to check if the device is a block
+device here.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808390
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200306145226.1610708-5-abologna@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virutil.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/util/virutil.c b/src/util/virutil.c
+index a0fd7618ee..f142951acf 100644
+--- a/src/util/virutil.c
++++ b/src/util/virutil.c
+@@ -1379,9 +1379,6 @@ virGetDeviceID(const char *path, int *maj, int *min)
+     if (stat(path, &sb) < 0)
+         return -errno;
+ 
+-    if (!S_ISBLK(sb.st_mode))
+-        return -EINVAL;
+-
+     if (maj)
+         *maj = major(sb.st_rdev);
+     if (min)
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-Remove-checking-of-return-value-of-virHashNew.patch b/SOURCES/libvirt-Remove-checking-of-return-value-of-virHashNew.patch
new file mode 100644
index 0000000..10e8801
--- /dev/null
+++ b/SOURCES/libvirt-Remove-checking-of-return-value-of-virHashNew.patch
@@ -0,0 +1,62 @@
+From ca7c7a8b07c31dc8bf96f7da6fb53af884e36ddb Mon Sep 17 00:00:00 2001
+Message-Id: <ca7c7a8b07c31dc8bf96f7da6fb53af884e36ddb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:01 +0100
+Subject: [PATCH] Remove checking of return value of virHashNew
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are two calls to virHashNew which check the return value. It's not
+necessary any more as virHashNew always returns a valid pointer.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 6eab924daa243afa67f2cc20dcbdf521904bb62b)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <08acb2e50b584a75c0131a628ee441f47e8fe823.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/backup_conf.c       | 6 +-----
+ src/qemu/qemu_monitor_json.c | 3 +--
+ 2 files changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/src/conf/backup_conf.c b/src/conf/backup_conf.c
+index b370b686f1..64c8f6cc09 100644
+--- a/src/conf/backup_conf.c
++++ b/src/conf/backup_conf.c
+@@ -439,15 +439,11 @@ virDomainBackupAlignDisks(virDomainBackupDefPtr def,
+                           virDomainDefPtr dom,
+                           const char *suffix)
+ {
+-    g_autoptr(virHashTable) disks = NULL;
++    g_autoptr(virHashTable) disks = virHashNew(NULL);
+     size_t i;
+     int ndisks;
+     bool backup_all = false;
+ 
+-
+-    if (!(disks = virHashNew(NULL)))
+-        return -1;
+-
+     /* Unlikely to have a guest without disks but technically possible.  */
+     if (!dom->ndisks) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index 5d8c7e9b5e..3fc0bcb80c 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -2992,8 +2992,7 @@ qemuMonitorJSONBlockGetNamedNodeDataJSON(virJSONValuePtr nodes)
+ {
+     g_autoptr(virHashTable) ret = NULL;
+ 
+-    if (!(ret = virHashNew((virHashDataFree) qemuMonitorJSONBlockNamedNodeDataFree)))
+-        return NULL;
++    ret = virHashNew((virHashDataFree) qemuMonitorJSONBlockNamedNodeDataFree);
+ 
+     if (virJSONValueArrayForeachSteal(nodes,
+                                       qemuMonitorJSONBlockGetNamedNodeDataWorker,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-Remove-qemuDomainSecretInfoNew.patch b/SOURCES/libvirt-Remove-qemuDomainSecretInfoNew.patch
new file mode 100644
index 0000000..4534ae8
--- /dev/null
+++ b/SOURCES/libvirt-Remove-qemuDomainSecretInfoNew.patch
@@ -0,0 +1,109 @@
+From 160863c5cac5519c287462439b9ce8abc6a8237e Mon Sep 17 00:00:00 2001
+Message-Id: <160863c5cac5519c287462439b9ce8abc6a8237e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:48 +0100
+Subject: [PATCH] Remove qemuDomainSecretInfoNew
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Replace it by a direct call to qemuDomainSecretAESSetupFromSecret.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit f742461389c11a7d4cc8bda941814c4128eadf94)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <c14d98c90ae9d0e9c5e4fef6a8e5061411c43a78.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 53 +++++++++++-------------------------------
+ 1 file changed, 13 insertions(+), 40 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index c286f50650..af23079d5d 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1669,33 +1669,6 @@ qemuDomainSecretInfoNewPlain(virSecretUsageType usageType,
+ }
+ 
+ 
+-/* qemuDomainSecretInfoNew:
+- * @priv: pointer to domain private object
+- * @srcAlias: Alias base to use for TLS object
+- * @usageType: Secret usage type
+- * @username: username
+- * @looupDef: lookup def describing secret
+- * @isLuks: boolean for luks lookup
+- *
+- * Helper function to create a secinfo to be used for secinfo consumers. This
+- * sets up encrypted data to be used with qemu's 'secret' object.
+- *
+- * Returns @secinfo on success, NULL on failure. Caller is responsible
+- * to eventually free @secinfo.
+- */
+-static qemuDomainSecretInfoPtr
+-qemuDomainSecretInfoNew(qemuDomainObjPrivatePtr priv,
+-                        const char *srcAlias,
+-                        virSecretUsageType usageType,
+-                        const char *username,
+-                        virSecretLookupTypeDefPtr lookupDef,
+-                        bool isLuks)
+-{
+-    return qemuDomainSecretAESSetupFromSecret(priv, srcAlias, usageType, username,
+-                                              lookupDef, isLuks);
+-}
+-
+-
+ /**
+  * qemuDomainSecretInfoTLSNew:
+  * @priv: pointer to domain private object
+@@ -1722,9 +1695,9 @@ qemuDomainSecretInfoTLSNew(qemuDomainObjPrivatePtr priv,
+     }
+     seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
+ 
+-    return qemuDomainSecretInfoNew(priv, srcAlias,
+-                                   VIR_SECRET_USAGE_TYPE_TLS, NULL,
+-                                   &seclookupdef, false);
++    return qemuDomainSecretAESSetupFromSecret(priv, srcAlias,
++                                              VIR_SECRET_USAGE_TYPE_TLS,
++                                              NULL, &seclookupdef, false);
+ }
+ 
+ 
+@@ -1814,11 +1787,11 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+                                                             src->auth->username,
+                                                             &src->auth->seclookupdef);
+         } else {
+-            srcPriv->secinfo = qemuDomainSecretInfoNew(priv, authalias,
+-                                                       usageType,
+-                                                       src->auth->username,
+-                                                       &src->auth->seclookupdef,
+-                                                       false);
++            srcPriv->secinfo = qemuDomainSecretAESSetupFromSecret(priv, authalias,
++                                                                  usageType,
++                                                                  src->auth->username,
++                                                                  &src->auth->seclookupdef,
++                                                                  false);
+         }
+ 
+         if (!srcPriv->secinfo)
+@@ -1826,11 +1799,11 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+     }
+ 
+     if (hasEnc) {
+-        if (!(srcPriv->encinfo =
+-              qemuDomainSecretInfoNew(priv, encalias,
+-                                      VIR_SECRET_USAGE_TYPE_VOLUME, NULL,
+-                                      &src->encryption->secrets[0]->seclookupdef,
+-                                      true)))
++        if (!(srcPriv->encinfo = qemuDomainSecretAESSetupFromSecret(priv, encalias,
++                                                                    VIR_SECRET_USAGE_TYPE_VOLUME,
++                                                                    NULL,
++                                                                    &src->encryption->secrets[0]->seclookupdef,
++                                                                    true)))
+               return -1;
+     }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-api-disallow-virDomainAgentSetResponseTimeout-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virDomainAgentSetResponseTimeout-on-read-only-connections.patch
new file mode 100644
index 0000000..5d9ae06
--- /dev/null
+++ b/SOURCES/libvirt-api-disallow-virDomainAgentSetResponseTimeout-on-read-only-connections.patch
@@ -0,0 +1,45 @@
+From 0c1bec6a89f97c77ba9e0ed4146deb8606ea6f16 Mon Sep 17 00:00:00 2001
+Message-Id: <0c1bec6a89f97c77ba9e0ed4146deb8606ea6f16@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Wed, 25 Mar 2020 11:21:19 -0500
+Subject: [PATCH] api: disallow virDomainAgentSetResponseTimeout() on read-only
+ connections
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This function changes the amount of time that libvirt waits for a
+response from the guest agent for all guest agent commands. Since this
+is a configuration change, it should not be allowed on read-only
+connections.
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 4cc90c2e62df653e909ad31fd810224bf8bcf913)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1814508
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Message-Id: <20200325162119.9047-2-jjongsma@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/libvirt-domain.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
+index eb66999f07..3deee54e48 100644
+--- a/src/libvirt-domain.c
++++ b/src/libvirt-domain.c
+@@ -12554,6 +12554,8 @@ virDomainAgentSetResponseTimeout(virDomainPtr domain,
+     virCheckDomainReturn(domain, -1);
+     conn = domain->conn;
+ 
++    virCheckReadOnlyGoto(conn->flags, error);
++
+     if (conn->driver->domainAgentSetResponseTimeout) {
+         if (conn->driver->domainAgentSetResponseTimeout(domain, timeout, flags) < 0)
+             goto error;
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-conf-Add-support-for-cookies-for-HTTP-based-disks.patch b/SOURCES/libvirt-conf-Add-support-for-cookies-for-HTTP-based-disks.patch
new file mode 100644
index 0000000..ed4e875
--- /dev/null
+++ b/SOURCES/libvirt-conf-Add-support-for-cookies-for-HTTP-based-disks.patch
@@ -0,0 +1,449 @@
+From 4abdfae3b67295a0143f650768630e009d1b2798 Mon Sep 17 00:00:00 2001
+Message-Id: <4abdfae3b67295a0143f650768630e009d1b2798@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:57 +0100
+Subject: [PATCH] conf: Add support for cookies for HTTP based disks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add possibility to specify one or more cookies for http based disks.
+This patch adds the config parser, storage and validation of the
+cookies.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 3b076391befc3fe72deb0c244ac6c2b4c100b410)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <3135a30f0d0a1a4bb8da02c49f10a1bcf3a394f4.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in                     |  10 ++
+ docs/schemas/domaincommon.rng                 |  24 ++++
+ src/conf/domain_conf.c                        |  82 +++++++++++++
+ src/libvirt_private.syms                      |   1 +
+ src/util/virstoragefile.c                     | 115 ++++++++++++++++++
+ src/util/virstoragefile.h                     |  15 +++
+ .../disk-network-http.xml                     |   8 ++
+ 7 files changed, 255 insertions(+)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 2cce247958..5a10d64e83 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -2839,6 +2839,9 @@
+     &lt;driver name='qemu' type='raw'/&gt;
+     &lt;source protocol="http" name="url_path"&gt;
+       &lt;host name="hostname" port="80"/&gt;
++      &lt;cookies&gt;
++        &lt;cookie name="test"&gt;somevalue&lt;/cookie&gt;
++      &lt;/cookies&gt;
+     &lt;/source&gt;
+     &lt;target dev='hde' bus='ide' tray='open'/&gt;
+     &lt;readonly/&gt;
+@@ -3382,6 +3385,13 @@
+             certificate validation. Supported values are <code>yes</code> and
+             <code>no</code>. <span class="since">Since 6.2.0</span>
+           </dd>
++          <dt><code>cookies</code></dt>
++          <dd>
++            For <code>http</code> and <code>https</code> accessed storage it's
++            possible to pass one or more cookies. The cookie name and value
++            must conform to the HTTP specification.
++            <span class="since">Since 6.2.0</span>
++          </dd>
+         </dl>
+ 
+         <p>
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 548601b61c..bdf35e64f6 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1817,6 +1817,24 @@
+     </element>
+   </define>
+ 
++  <define name="diskSourceNetworkProtocolHTTPCookies">
++    <element name="cookies">
++      <oneOrMore>
++        <element name="cookie">
++          <attribute name="name">
++            <data type="string">
++              <param name="pattern">[!#$%&amp;'*+\-.0-9A-Z\^_`a-z|~]+</param>
++            </data>
++          </attribute>
++          <data type="string">
++            <param name="pattern">[!#$%&amp;'()*+\-./0-9:&gt;=&lt;?@A-Z\^_`\[\]a-z|~]+</param>
++          </data>
++        </element>
++      </oneOrMore>
++      <empty/>
++    </element>
++  </define>
++
+   <define name="diskSourceNetworkProtocolHTTPS">
+     <element name="source">
+       <attribute name="protocol">
+@@ -1833,6 +1851,9 @@
+       <optional>
+         <ref name="diskSourceNetworkProtocolSSLVerify"/>
+       </optional>
++      <optional>
++        <ref name="diskSourceNetworkProtocolHTTPCookies"/>
++      </optional>
+     </element>
+   </define>
+ 
+@@ -1849,6 +1870,9 @@
+       <optional>
+         <ref name="encryption"/>
+       </optional>
++      <optional>
++        <ref name="diskSourceNetworkProtocolHTTPCookies"/>
++      </optional>
+     </element>
+   </define>
+ 
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 70bbc35bb3..d066d3aac1 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -9249,6 +9249,62 @@ virDomainDiskSourcePoolDefParse(xmlNodePtr node,
+ }
+ 
+ 
++static virStorageNetCookieDefPtr
++virDomainStorageNetCookieParse(xmlNodePtr node,
++                               xmlXPathContextPtr ctxt)
++{
++    VIR_XPATH_NODE_AUTORESTORE(ctxt);
++    g_autoptr(virStorageNetCookieDef) cookie = NULL;
++
++    ctxt->node = node;
++
++    cookie = g_new0(virStorageNetCookieDef, 1);
++
++    if (!(cookie->name = virXPathString("string(./@name)", ctxt))) {
++        virReportError(VIR_ERR_XML_ERROR, "%s", _("missing cookie name"));
++        return NULL;
++    }
++
++    if (!(cookie->value = virXPathString("string(.)", ctxt))) {
++        virReportError(VIR_ERR_XML_ERROR, _("missing value for cookie '%s'"),
++                       cookie->name);
++        return NULL;
++    }
++
++    return g_steal_pointer(&cookie);
++}
++
++
++static int
++virDomainStorageNetCookiesParse(xmlNodePtr node,
++                                xmlXPathContextPtr ctxt,
++                                virStorageSourcePtr src)
++{
++    VIR_XPATH_NODE_AUTORESTORE(ctxt);
++    g_autofree xmlNodePtr *nodes = NULL;
++    ssize_t nnodes;
++    size_t i;
++
++    ctxt->node = node;
++
++    if ((nnodes = virXPathNodeSet("./cookie", ctxt, &nodes)) < 0)
++        return -1;
++
++    src->cookies = g_new0(virStorageNetCookieDefPtr, nnodes);
++    src->ncookies = nnodes;
++
++    for (i = 0; i < nnodes; i++) {
++        if (!(src->cookies[i] = virDomainStorageNetCookieParse(nodes[i], ctxt)))
++            return -1;
++    }
++
++    if (virStorageSourceNetCookiesValidate(src) < 0)
++        return -1;
++
++    return 0;
++}
++
++
+ static int
+ virDomainDiskSourceNetworkParse(xmlNodePtr node,
+                                 xmlXPathContextPtr ctxt,
+@@ -9260,6 +9316,7 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
+     g_autofree char *haveTLS = NULL;
+     g_autofree char *tlsCfg = NULL;
+     g_autofree char *sslverifystr = NULL;
++    xmlNodePtr tmpnode;
+ 
+     if (!(protocol = virXMLPropString(node, "protocol"))) {
+         virReportError(VIR_ERR_XML_ERROR, "%s",
+@@ -9345,6 +9402,13 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
+         src->sslverify = verify;
+     }
+ 
++    if ((src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTP ||
++         src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS) &&
++        (tmpnode = virXPathNode("./cookies", ctxt))) {
++        if (virDomainStorageNetCookiesParse(tmpnode, ctxt, src) < 0)
++            return -1;
++    }
++
+     return 0;
+ }
+ 
+@@ -24281,6 +24345,22 @@ virDomainSourceDefFormatSeclabel(virBufferPtr buf,
+ }
+ 
+ 
++static void
++virDomainDiskSourceFormatNetworkCookies(virBufferPtr buf,
++                                        virStorageSourcePtr src)
++{
++    g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
++    size_t i;
++
++    for (i = 0; i < src->ncookies; i++) {
++        virBufferEscapeString(&childBuf, "<cookie name='%s'>", src->cookies[i]->name);
++        virBufferEscapeString(&childBuf, "%s</cookie>\n", src->cookies[i]->value);
++    }
++
++    virXMLFormatElement(buf, "cookies", NULL, &childBuf);
++}
++
++
+ static int
+ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
+                                  virBufferPtr childBuf,
+@@ -24331,6 +24411,8 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
+                           virTristateBoolTypeToString(src->sslverify));
+     }
+ 
++    virDomainDiskSourceFormatNetworkCookies(childBuf, src);
++
+     return 0;
+ }
+ 
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index dbbec0d567..ac5527ef01 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -3123,6 +3123,7 @@ virStorageSourceIsEmpty;
+ virStorageSourceIsLocalStorage;
+ virStorageSourceIsRelative;
+ virStorageSourceIsSameLocation;
++virStorageSourceNetCookiesValidate;
+ virStorageSourceNetworkAssignDefaultPorts;
+ virStorageSourceNew;
+ virStorageSourceNewFromBacking;
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index cfa77fccf8..6350168d73 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2157,6 +2157,118 @@ virStorageSourceSeclabelsCopy(virStorageSourcePtr to,
+ }
+ 
+ 
++void
++virStorageNetCookieDefFree(virStorageNetCookieDefPtr def)
++{
++    if (!def)
++        return;
++
++    g_free(def->name);
++    g_free(def->value);
++
++    g_free(def);
++}
++
++
++static void
++virStorageSourceNetCookiesClear(virStorageSourcePtr src)
++{
++    size_t i;
++
++    if (!src || !src->cookies)
++        return;
++
++    for (i = 0; i < src->ncookies; i++)
++        virStorageNetCookieDefFree(src->cookies[i]);
++
++    g_clear_pointer(&src->cookies, g_free);
++    src->ncookies = 0;
++}
++
++
++static void
++virStorageSourceNetCookiesCopy(virStorageSourcePtr to,
++                               const virStorageSource *from)
++{
++    size_t i;
++
++    if (from->ncookies == 0)
++        return;
++
++    to->cookies = g_new0(virStorageNetCookieDefPtr, from->ncookies);
++    to->ncookies = from->ncookies;
++
++    for (i = 0; i < from->ncookies; i++) {
++        to->cookies[i]->name = g_strdup(from->cookies[i]->name);
++        to->cookies[i]->value = g_strdup(from->cookies[i]->value);
++    }
++}
++
++
++/* see https://tools.ietf.org/html/rfc6265#section-4.1.1 */
++static const char virStorageSourceCookieValueInvalidChars[] =
++ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
++ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
++ " \",;\\";
++
++/* in addition cookie name can't contain these */
++static const char virStorageSourceCookieNameInvalidChars[] =
++ "()<>@:/[]?={}";
++
++static int
++virStorageSourceNetCookieValidate(virStorageNetCookieDefPtr def)
++{
++    /* name must have at least 1 character */
++    if (*(def->name) == '\0') {
++        virReportError(VIR_ERR_XML_ERROR, "%s",
++                       _("cookie name must not be empty"));
++        return -1;
++    }
++
++    /* check invalid characters in name */
++    if (virStringHasChars(def->name, virStorageSourceCookieValueInvalidChars) ||
++        virStringHasChars(def->name, virStorageSourceCookieNameInvalidChars)) {
++        virReportError(VIR_ERR_XML_ERROR,
++                       _("cookie name '%s' contains invalid characters"),
++                       def->name);
++        return -1;
++    }
++
++    /* check invalid characters in value */
++    if (virStringHasChars(def->value, virStorageSourceCookieValueInvalidChars)) {
++        virReportError(VIR_ERR_XML_ERROR,
++                       _("value of cookie '%s' contains invalid characters"),
++                       def->name);
++        return -1;
++    }
++
++    return 0;
++}
++
++
++int
++virStorageSourceNetCookiesValidate(virStorageSourcePtr src)
++{
++    size_t i;
++    size_t j;
++
++    for (i = 0; i < src->ncookies; i++) {
++        if (virStorageSourceNetCookieValidate(src->cookies[i]) < 0)
++            return -1;
++
++        for (j = i + 1; j < src->ncookies; j++) {
++            if (STREQ(src->cookies[i]->name, src->cookies[j]->name)) {
++                virReportError(VIR_ERR_XML_ERROR, _("duplicate cookie '%s'"),
++                               src->cookies[i]->name);
++                return -1;
++            }
++        }
++    }
++
++    return 0;
++}
++
++
+ static virStorageTimestampsPtr
+ virStorageTimestampsCopy(const virStorageTimestamps *src)
+ {
+@@ -2299,6 +2411,8 @@ virStorageSourceCopy(const virStorageSource *src,
+         def->nhosts = src->nhosts;
+     }
+ 
++    virStorageSourceNetCookiesCopy(def, src);
++
+     if (src->srcpool &&
+         !(def->srcpool = virStorageSourcePoolDefCopy(src->srcpool)))
+         return NULL;
+@@ -2560,6 +2674,7 @@ virStorageSourceClear(virStorageSourcePtr def)
+     VIR_FREE(def->volume);
+     VIR_FREE(def->snapshot);
+     VIR_FREE(def->configFile);
++    virStorageSourceNetCookiesClear(def);
+     virStorageSourcePoolDefFree(def->srcpool);
+     virBitmapFree(def->features);
+     VIR_FREE(def->compat);
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index fab4248c3d..1c7c046ad6 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -162,6 +162,17 @@ struct _virStorageNetHostDef {
+     char *socket;  /* path to unix socket */
+ };
+ 
++typedef struct _virStorageNetCookieDef virStorageNetCookieDef;
++typedef virStorageNetCookieDef *virStorageNetCookieDefPtr;
++struct _virStorageNetCookieDef {
++    char *name;
++    char *value;
++};
++
++void virStorageNetCookieDefFree(virStorageNetCookieDefPtr def);
++
++G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageNetCookieDef, virStorageNetCookieDefFree);
++
+ /* Information for a storage volume from a virStoragePool */
+ 
+ /*
+@@ -276,6 +287,8 @@ struct _virStorageSource {
+                          the source definition */
+     size_t nhosts;
+     virStorageNetHostDefPtr hosts;
++    size_t ncookies;
++    virStorageNetCookieDefPtr *cookies;
+     virStorageSourcePoolDefPtr srcpool;
+     virStorageAuthDefPtr auth;
+     bool authInherited;
+@@ -477,6 +490,8 @@ int virStorageSourceUpdateCapacity(virStorageSourcePtr src,
+ int virStorageSourceNewFromBacking(virStorageSourcePtr parent,
+                                    virStorageSourcePtr *backing);
+ 
++int virStorageSourceNetCookiesValidate(virStorageSourcePtr src);
++
+ virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
+                                          bool backingChain)
+     ATTRIBUTE_NONNULL(1);
+diff --git a/tests/genericxml2xmlindata/disk-network-http.xml b/tests/genericxml2xmlindata/disk-network-http.xml
+index bdcc1977f2..bafb77c8ec 100644
+--- a/tests/genericxml2xmlindata/disk-network-http.xml
++++ b/tests/genericxml2xmlindata/disk-network-http.xml
+@@ -33,6 +33,10 @@
+       <driver name='qemu' type='raw'/>
+       <source protocol='http' name='test3.img'>
+         <host name='example.org' port='1234'/>
++        <cookies>
++          <cookie name='test'>testcookievalue</cookie>
++          <cookie name='test2'>blurb</cookie>
++        </cookies>
+       </source>
+       <target dev='vdc' bus='virtio'/>
+     </disk>
+@@ -41,6 +45,10 @@
+       <source protocol='https' name='test4.img'>
+         <host name='example.org' port='1234'/>
+         <ssl verify='yes'/>
++        <cookies>
++          <cookie name='test'>testcookievalue</cookie>
++          <cookie name='test2'>blurb</cookie>
++        </cookies>
+       </source>
+       <target dev='vdd' bus='virtio'/>
+     </disk>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-conf-Add-support-for-http-s-query-strings.patch b/SOURCES/libvirt-conf-Add-support-for-http-s-query-strings.patch
new file mode 100644
index 0000000..32169e7
--- /dev/null
+++ b/SOURCES/libvirt-conf-Add-support-for-http-s-query-strings.patch
@@ -0,0 +1,160 @@
+From 45ecbd824c92bd05a46557bfcaff39196f701e6c Mon Sep 17 00:00:00 2001
+Message-Id: <45ecbd824c92bd05a46557bfcaff39196f701e6c@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:45 +0200
+Subject: [PATCH] conf: Add support for http(s) query strings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a new attribute for holding the query part for http(s) disks.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 56368124728f0d65dde07244c741b459fcd6b939)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <b60abcf1e7711e9e29175e1fdcfe2820d5694a17.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/formatdomain.html.in                                  | 7 ++++++-
+ docs/schemas/domaincommon.rng                              | 6 ++++++
+ src/conf/domain_conf.c                                     | 5 +++++
+ src/util/virstoragefile.c                                  | 2 ++
+ src/util/virstoragefile.h                                  | 1 +
+ tests/qemuxml2argvdata/disk-network-http.xml               | 2 +-
+ .../qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml | 2 +-
+ 7 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 143db21d4d..9c588185df 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -2837,7 +2837,7 @@
+   &lt;/disk&gt;
+   &lt;disk type='network' device='cdrom'&gt;
+     &lt;driver name='qemu' type='raw'/&gt;
+-    &lt;source protocol="http" name="url_path"&gt;
++    &lt;source protocol="http" name="url_path" query="foo=bar&amp;amp;baz=flurb&gt;
+       &lt;host name="hostname" port="80"/&gt;
+       &lt;cookies&gt;
+         &lt;cookie name="test"&gt;somevalue&lt;/cookie&gt;
+@@ -3103,6 +3103,11 @@
+               ('tls' <span class="since">Since 4.5.0</span>)
+               </p>
+ 
++              <p>For protocols <code>http</code> and <code>https</code> an
++              optional attribute <code>query</code> specifies the query string.
++              (<span class="since">Since 6.2.0</span>)
++              </p>
++
+               <p>For "iscsi" (<span class="since">since 1.0.4</span>), the
+               <code>name</code> attribute may include a logical unit number,
+               separated from the target's name by a slash (e.g.,
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index e17f7ff8c0..dd8f27243a 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1869,6 +1869,9 @@
+           </choice>
+         </attribute>
+         <attribute name="name"/>
++        <optional>
++          <attribute name="query"/>
++        </optional>
+         <ref name="diskSourceCommon"/>
+         <ref name="diskSourceNetworkHost"/>
+         <optional>
+@@ -1894,6 +1897,9 @@
+           </choice>
+         </attribute>
+         <attribute name="name"/>
++        <optional>
++          <attribute name="query"/>
++        </optional>
+         <ref name="diskSourceCommon"/>
+         <ref name="diskSourceNetworkHost"/>
+         <optional>
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index e3755fa285..28160a2967 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -9382,6 +9382,10 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
+     /* config file currently only works with remote disks */
+     src->configFile = virXPathString("string(./config/@file)", ctxt);
+ 
++    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTP ||
++        src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS)
++        src->query = virXMLPropString(node, "query");
++
+     if (virDomainStorageNetworkParseHosts(node, &src->hosts, &src->nhosts) < 0)
+         return -1;
+ 
+@@ -24390,6 +24394,7 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
+         path = g_strdup_printf("%s/%s", src->volume, src->path);
+ 
+     virBufferEscapeString(attrBuf, " name='%s'", path ? path : src->path);
++    virBufferEscapeString(attrBuf, " query='%s'", src->query);
+ 
+     if (src->haveTLS != VIR_TRISTATE_BOOL_ABSENT &&
+         !(flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE &&
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index f8d741f040..4082e3f5f7 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2418,6 +2418,7 @@ virStorageSourceCopy(const virStorageSource *src,
+     def->compat = g_strdup(src->compat);
+     def->tlsAlias = g_strdup(src->tlsAlias);
+     def->tlsCertdir = g_strdup(src->tlsCertdir);
++    def->query = g_strdup(src->query);
+ 
+     if (src->sliceStorage)
+         def->sliceStorage = virStorageSourceSliceCopy(src->sliceStorage);
+@@ -2696,6 +2697,7 @@ virStorageSourceClear(virStorageSourcePtr def)
+     VIR_FREE(def->volume);
+     VIR_FREE(def->snapshot);
+     VIR_FREE(def->configFile);
++    VIR_FREE(def->query);
+     virStorageSourceNetCookiesClear(def);
+     virStorageSourcePoolDefFree(def->srcpool);
+     virBitmapFree(def->features);
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 0230f44652..8089d1e07f 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -285,6 +285,7 @@ struct _virStorageSource {
+     char *snapshot; /* for storage systems supporting internal snapshots */
+     char *configFile; /* some storage systems use config file as part of
+                          the source definition */
++    char *query; /* query string for HTTP based protocols */
+     size_t nhosts;
+     virStorageNetHostDefPtr hosts;
+     size_t ncookies;
+diff --git a/tests/qemuxml2argvdata/disk-network-http.xml b/tests/qemuxml2argvdata/disk-network-http.xml
+index 93e6617433..3abf499019 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.xml
++++ b/tests/qemuxml2argvdata/disk-network-http.xml
+@@ -42,7 +42,7 @@
+     </disk>
+     <disk type='network' device='disk'>
+       <driver name='qemu' type='raw'/>
+-      <source protocol='https' name='test4.img'>
++      <source protocol='https' name='test4.img' query='par=val&amp;other=ble'>
+         <host name='example.org' port='1234'/>
+         <ssl verify='no'/>
+         <cookies>
+diff --git a/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
+index 60073c227c..45b01841ec 100644
+--- a/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
++++ b/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
+@@ -46,7 +46,7 @@
+     </disk>
+     <disk type='network' device='disk'>
+       <driver name='qemu' type='raw'/>
+-      <source protocol='https' name='test4.img'>
++      <source protocol='https' name='test4.img' query='par=val&amp;other=ble'>
+         <host name='example.org' port='1234'/>
+         <ssl verify='no'/>
+         <cookies>
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-conf-Add-support-for-modifying-ssl-validation-for-https-ftps-disks.patch b/SOURCES/libvirt-conf-Add-support-for-modifying-ssl-validation-for-https-ftps-disks.patch
new file mode 100644
index 0000000..995852c
--- /dev/null
+++ b/SOURCES/libvirt-conf-Add-support-for-modifying-ssl-validation-for-https-ftps-disks.patch
@@ -0,0 +1,242 @@
+From ffe8028ca07eb049b12d5c152b3d66489378d731 Mon Sep 17 00:00:00 2001
+Message-Id: <ffe8028ca07eb049b12d5c152b3d66489378d731@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:56 +0100
+Subject: [PATCH] conf: Add support for modifying ssl validation for https/ftps
+ disks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+To allow turning off verification of SSL cerificates add a new element
+<ssl> to the disk source XML which will allow configuring the validation
+process using the 'verify' attribute.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 25481e25b14108373bf2e5e95c04fe30bff96bb4)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <ede13179128fc9ef05036a5408f4115132a2c12d.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in                     |  9 ++++
+ docs/schemas/domaincommon.rng                 | 51 ++++++++++++++++++-
+ src/conf/domain_conf.c                        | 19 +++++++
+ src/util/virstoragefile.c                     |  1 +
+ src/util/virstoragefile.h                     |  1 +
+ .../disk-network-http.xml                     |  9 ++++
+ 6 files changed, 88 insertions(+), 2 deletions(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index e9830ab231..2cce247958 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -2847,6 +2847,7 @@
+     &lt;driver name='qemu' type='raw'/&gt;
+     &lt;source protocol="https" name="url_path"&gt;
+       &lt;host name="hostname" port="443"/&gt;
++      &lt;ssl verify="no"/&gt;
+     &lt;/source&gt;
+     &lt;target dev='hdf' bus='ide' tray='open'/&gt;
+     &lt;readonly/&gt;
+@@ -3373,6 +3374,14 @@
+             The <code>offset</code> and <code>size</code> values are in bytes.
+             <span class="since">Since 6.1.0</span>
+           </dd>
++          <dt><code>ssl</code></dt>
++          <dd>
++            For <code>https</code> and <code>ftps</code> accessed storage it's
++            possible to tweak the SSL transport parameters with this element.
++            The <code>verify</code> attribute allows to turn on or off SSL
++            certificate validation. Supported values are <code>yes</code> and
++            <code>no</code>. <span class="since">Since 6.2.0</span>
++          </dd>
+         </dl>
+ 
+         <p>
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index aa70e340b9..548601b61c 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1808,12 +1808,39 @@
+     </element>
+   </define>
+ 
++  <define name="diskSourceNetworkProtocolSSLVerify">
++    <element name="ssl">
++      <attribute name="verify">
++        <ref name="virYesNo"/>
++      </attribute>
++      <empty/>
++    </element>
++  </define>
++
++  <define name="diskSourceNetworkProtocolHTTPS">
++    <element name="source">
++      <attribute name="protocol">
++        <choice>
++          <value>https</value>
++        </choice>
++      </attribute>
++      <attribute name="name"/>
++      <ref name="diskSourceCommon"/>
++      <ref name="diskSourceNetworkHost"/>
++      <optional>
++        <ref name="encryption"/>
++      </optional>
++      <optional>
++        <ref name="diskSourceNetworkProtocolSSLVerify"/>
++      </optional>
++    </element>
++  </define>
++
+   <define name="diskSourceNetworkProtocolHTTP">
+     <element name="source">
+       <attribute name="protocol">
+         <choice>
+           <value>http</value>
+-          <value>https</value>
+         </choice>
+       </attribute>
+       <attribute name="name"/>
+@@ -1825,13 +1852,31 @@
+     </element>
+   </define>
+ 
++  <define name="diskSourceNetworkProtocolFTPS">
++    <element name="source">
++      <attribute name="protocol">
++        <choice>
++          <value>ftps</value>
++        </choice>
++      </attribute>
++      <attribute name="name"/>
++      <ref name="diskSourceCommon"/>
++      <ref name="diskSourceNetworkHost"/>
++      <optional>
++        <ref name="encryption"/>
++      </optional>
++      <optional>
++        <ref name="diskSourceNetworkProtocolSSLVerify"/>
++      </optional>
++    </element>
++  </define>
++
+   <define name="diskSourceNetworkProtocolSimple">
+     <element name="source">
+       <attribute name="protocol">
+         <choice>
+           <value>sheepdog</value>
+           <value>ftp</value>
+-          <value>ftps</value>
+           <value>tftp</value>
+         </choice>
+       </attribute>
+@@ -1909,6 +1954,8 @@
+       <ref name="diskSourceNetworkProtocolRBD"/>
+       <ref name="diskSourceNetworkProtocolISCSI"/>
+       <ref name="diskSourceNetworkProtocolHTTP"/>
++      <ref name="diskSourceNetworkProtocolHTTPS"/>
++      <ref name="diskSourceNetworkProtocolFTPS"/>
+       <ref name="diskSourceNetworkProtocolSimple"/>
+       <ref name="diskSourceNetworkProtocolVxHS"/>
+     </choice>
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index b3c4084c38..70bbc35bb3 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -9259,6 +9259,7 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
+     g_autofree char *protocol = NULL;
+     g_autofree char *haveTLS = NULL;
+     g_autofree char *tlsCfg = NULL;
++    g_autofree char *sslverifystr = NULL;
+ 
+     if (!(protocol = virXMLPropString(node, "protocol"))) {
+         virReportError(VIR_ERR_XML_ERROR, "%s",
+@@ -9331,6 +9332,19 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
+ 
+     virStorageSourceInitiatorParseXML(ctxt, &src->initiator);
+ 
++    if ((src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS ||
++         src->protocol == VIR_STORAGE_NET_PROTOCOL_FTPS) &&
++        (sslverifystr = virXPathString("string(./ssl/@verify)", ctxt))) {
++        int verify;
++        if ((verify = virTristateBoolTypeFromString(sslverifystr)) < 0) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("invalid ssl verify mode '%s'"), sslverifystr);
++            return -1;
++        }
++
++        src->sslverify = verify;
++    }
++
+     return 0;
+ }
+ 
+@@ -24312,6 +24326,11 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
+ 
+     virStorageSourceInitiatorFormatXML(&src->initiator, childBuf);
+ 
++    if (src->sslverify != VIR_TRISTATE_BOOL_ABSENT) {
++        virBufferAsprintf(childBuf, "<ssl verify='%s'/>\n",
++                          virTristateBoolTypeToString(src->sslverify));
++    }
++
+     return 0;
+ }
+ 
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index b88763b267..cfa77fccf8 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2270,6 +2270,7 @@ virStorageSourceCopy(const virStorageSource *src,
+     def->cachemode = src->cachemode;
+     def->discard = src->discard;
+     def->detect_zeroes = src->detect_zeroes;
++    def->sslverify = src->sslverify;
+ 
+     /* storage driver metadata are not copied */
+     def->drv = NULL;
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 5b995d54ab..fab4248c3d 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -282,6 +282,7 @@ struct _virStorageSource {
+     virStorageEncryptionPtr encryption;
+     bool encryptionInherited;
+     virStoragePRDefPtr pr;
++    virTristateBool sslverify;
+ 
+     virStorageSourceNVMeDefPtr nvme; /* type == VIR_STORAGE_TYPE_NVME */
+ 
+diff --git a/tests/genericxml2xmlindata/disk-network-http.xml b/tests/genericxml2xmlindata/disk-network-http.xml
+index fde1222fd0..bdcc1977f2 100644
+--- a/tests/genericxml2xmlindata/disk-network-http.xml
++++ b/tests/genericxml2xmlindata/disk-network-http.xml
+@@ -25,6 +25,7 @@
+       <driver name='qemu' type='raw'/>
+       <source protocol='https' name='test2.img'>
+         <host name='example.org' port='443'/>
++        <ssl verify='no'/>
+       </source>
+       <target dev='vdb' bus='virtio'/>
+     </disk>
+@@ -35,6 +36,14 @@
+       </source>
+       <target dev='vdc' bus='virtio'/>
+     </disk>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='https' name='test4.img'>
++        <host name='example.org' port='1234'/>
++        <ssl verify='yes'/>
++      </source>
++      <target dev='vdd' bus='virtio'/>
++    </disk>
+     <controller type='usb' index='0'/>
+     <controller type='pci' index='0' model='pci-root'/>
+     <input type='mouse' bus='ps2'/>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-conf-Add-support-for-setting-timeout-and-readahead-size-for-network-disks.patch b/SOURCES/libvirt-conf-Add-support-for-setting-timeout-and-readahead-size-for-network-disks.patch
new file mode 100644
index 0000000..5fe493e
--- /dev/null
+++ b/SOURCES/libvirt-conf-Add-support-for-setting-timeout-and-readahead-size-for-network-disks.patch
@@ -0,0 +1,205 @@
+From 3050ddce41896311b8c3ad06f148bea358e597b8 Mon Sep 17 00:00:00 2001
+Message-Id: <3050ddce41896311b8c3ad06f148bea358e597b8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:58 +0100
+Subject: [PATCH] conf: Add support for setting timeout and readahead size for
+ network disks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some disk backends support configuring the readahead buffer or timeout
+for requests. Add the knobs to the XML.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 63fd46177367c6653c4c986558f6d0e4a700cfcc)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <2694bc6f9a327f89d82da18320e7137152915ad3.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in                     | 16 +++++++++++++
+ docs/schemas/domaincommon.rng                 | 23 +++++++++++++++++++
+ src/conf/domain_conf.c                        | 19 +++++++++++++++
+ src/util/virstoragefile.c                     |  2 ++
+ src/util/virstoragefile.h                     |  3 +++
+ .../disk-network-http.xml                     |  2 ++
+ 6 files changed, 65 insertions(+)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 5a10d64e83..2b8f9eabc2 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -2842,6 +2842,8 @@
+       &lt;cookies&gt;
+         &lt;cookie name="test"&gt;somevalue&lt;/cookie&gt;
+       &lt;/cookies&gt;
++      &lt;readahead size='65536'/&gt;
++      &lt;timeout seconds='6'/&gt;
+     &lt;/source&gt;
+     &lt;target dev='hde' bus='ide' tray='open'/&gt;
+     &lt;readonly/&gt;
+@@ -3392,6 +3394,20 @@
+             must conform to the HTTP specification.
+             <span class="since">Since 6.2.0</span>
+           </dd>
++          <dt><code>readahead</code></dt>
++          <dd>
++            Specifies the size of the readahead buffer for protocols
++            which support it. (all 'curl' based drivers in qemu). The size
++            is in bytes. Note that '0' is considered as if the value is not
++            provided.
++            <span class="since">Since 6.2.0</span>
++          </dd>
++          <dt><code>timeout</code></dt>
++          <dd>
++            Specifies the connection timeout for protocols which support it.
++            Note that '0' is considered as if the value is not provided.
++            <span class="since">Since 6.2.0</span>
++          </dd>
+         </dl>
+ 
+         <p>
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index bdf35e64f6..3a0edbed97 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1808,6 +1808,25 @@
+     </element>
+   </define>
+ 
++  <define name="diskSourceNetworkProtocolPropsCommon">
++    <optional>
++      <element name="readahead">
++        <attribute name="size">
++          <ref name="positiveInteger"/>
++        </attribute>
++        <empty/>
++      </element>
++    </optional>
++    <optional>
++      <element name="timeout">
++        <attribute name="seconds">
++          <ref name="positiveInteger"/>
++        </attribute>
++        <empty/>
++      </element>
++    </optional>
++  </define>
++
+   <define name="diskSourceNetworkProtocolSSLVerify">
+     <element name="ssl">
+       <attribute name="verify">
+@@ -1854,6 +1873,7 @@
+       <optional>
+         <ref name="diskSourceNetworkProtocolHTTPCookies"/>
+       </optional>
++      <ref name="diskSourceNetworkProtocolPropsCommon"/>
+     </element>
+   </define>
+ 
+@@ -1873,6 +1893,7 @@
+       <optional>
+         <ref name="diskSourceNetworkProtocolHTTPCookies"/>
+       </optional>
++      <ref name="diskSourceNetworkProtocolPropsCommon"/>
+     </element>
+   </define>
+ 
+@@ -1892,6 +1913,7 @@
+       <optional>
+         <ref name="diskSourceNetworkProtocolSSLVerify"/>
+       </optional>
++      <ref name="diskSourceNetworkProtocolPropsCommon"/>
+     </element>
+   </define>
+ 
+@@ -1910,6 +1932,7 @@
+       <optional>
+         <ref name="encryption"/>
+       </optional>
++      <ref name="diskSourceNetworkProtocolPropsCommon"/>
+     </element>
+   </define>
+ 
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index d066d3aac1..8aec85e83c 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -9409,6 +9409,19 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
+             return -1;
+     }
+ 
++    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTP ||
++        src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS ||
++        src->protocol == VIR_STORAGE_NET_PROTOCOL_FTP ||
++        src->protocol == VIR_STORAGE_NET_PROTOCOL_FTPS) {
++
++        if (virXPathULongLong("string(./readahead/@size)", ctxt, &src->readahead) == -2 ||
++            virXPathULongLong("string(./timeout/@seconds)", ctxt, &src->timeout) == -2) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                          _("invalid readahead size or timeout"));
++            return -1;
++        }
++    }
++
+     return 0;
+ }
+ 
+@@ -24413,6 +24426,12 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
+ 
+     virDomainDiskSourceFormatNetworkCookies(childBuf, src);
+ 
++    if (src->readahead)
++        virBufferAsprintf(childBuf, "<readahead size='%llu'/>\n", src->readahead);
++
++    if (src->timeout)
++        virBufferAsprintf(childBuf, "<timeout seconds='%llu'/>\n", src->timeout);
++
+     return 0;
+ }
+ 
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 6350168d73..7893e054c3 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2383,6 +2383,8 @@ virStorageSourceCopy(const virStorageSource *src,
+     def->discard = src->discard;
+     def->detect_zeroes = src->detect_zeroes;
+     def->sslverify = src->sslverify;
++    def->readahead = src->readahead;
++    def->timeout = src->timeout;
+ 
+     /* storage driver metadata are not copied */
+     def->drv = NULL;
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 1c7c046ad6..1abdaf89ce 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -296,6 +296,9 @@ struct _virStorageSource {
+     bool encryptionInherited;
+     virStoragePRDefPtr pr;
+     virTristateBool sslverify;
++    /* both values below have 0 as default value */
++    unsigned long long readahead; /* size of the readahead buffer in bytes */
++    unsigned long long timeout; /* connection timeout in seconds */
+ 
+     virStorageSourceNVMeDefPtr nvme; /* type == VIR_STORAGE_TYPE_NVME */
+ 
+diff --git a/tests/genericxml2xmlindata/disk-network-http.xml b/tests/genericxml2xmlindata/disk-network-http.xml
+index bafb77c8ec..a8430b8365 100644
+--- a/tests/genericxml2xmlindata/disk-network-http.xml
++++ b/tests/genericxml2xmlindata/disk-network-http.xml
+@@ -49,6 +49,8 @@
+           <cookie name='test'>testcookievalue</cookie>
+           <cookie name='test2'>blurb</cookie>
+         </cookies>
++        <readahead size='65536'/>
++        <timeout seconds='10'/>
+       </source>
+       <target dev='vdd' bus='virtio'/>
+     </disk>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-conf-Don-t-generate-machine-names-with-a-dot.patch b/SOURCES/libvirt-conf-Don-t-generate-machine-names-with-a-dot.patch
new file mode 100644
index 0000000..1a24e0b
--- /dev/null
+++ b/SOURCES/libvirt-conf-Don-t-generate-machine-names-with-a-dot.patch
@@ -0,0 +1,97 @@
+From 3ff27fe469c36e5655231f6759150350b17de298 Mon Sep 17 00:00:00 2001
+Message-Id: <3ff27fe469c36e5655231f6759150350b17de298@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:09 +0100
+Subject: [PATCH] conf: Don't generate machine names with a dot
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+According to the linked BZ, machined expects either valid
+hostname or valid FQDN (see systemd commit
+v239-3092-gd65652f1f2). While in case of multiple dots, a
+trailing one doesn't violate FQDN, it does violate the rule in
+case of something simple, like "domain.". But it's safe to remove
+it in both cases.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+Fixes: 45464db8ba502764cf37ec9335770248bdb3d9a8
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 2695191a44eb7375225b4ad073825ed3563a172a)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <355e05e31ec98522fa0e03a0c2c7af8ca097070d.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 14 +++++++-------
+ tests/virsystemdtest.c |  5 +++--
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 4b297c96bc..b3c4084c38 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -30688,20 +30688,20 @@ static void
+ virDomainMachineNameAppendValid(virBufferPtr buf,
+                                 const char *name)
+ {
+-    bool skip_dot = false;
++    bool skip = true;
+ 
+     for (; *name; name++) {
+         if (strlen(virBufferCurrentContent(buf)) >= 64)
+             break;
+ 
+-        if (*name == '.') {
+-            if (!skip_dot)
++        if (*name == '.' || *name == '-') {
++            if (!skip)
+                 virBufferAddChar(buf, *name);
+-            skip_dot = true;
++            skip = true;
+             continue;
+         }
+ 
+-        skip_dot = false;
++        skip = false;
+ 
+         if (!strchr(HOSTNAME_CHARS, *name))
+             continue;
+@@ -30709,8 +30709,8 @@ virDomainMachineNameAppendValid(virBufferPtr buf,
+         virBufferAddChar(buf, *name);
+     }
+ 
+-    /* trailing dashes are not allowed */
+-    virBufferTrimChars(buf, "-");
++    /* trailing dashes or dots are not allowed */
++    virBufferTrimChars(buf, "-.");
+ }
+ 
+ #undef HOSTNAME_CHARS
+diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
+index 26876850b8..eb510b40e4 100644
+--- a/tests/virsystemdtest.c
++++ b/tests/virsystemdtest.c
+@@ -733,7 +733,7 @@ mymain(void)
+     TEST_MACHINE("demo", 1, "qemu-1-demo");
+     TEST_MACHINE("demo-name", 2, "qemu-2-demo-name");
+     TEST_MACHINE("demo!name", 3, "qemu-3-demoname");
+-    TEST_MACHINE(".demo", 4, "qemu-4-.demo");
++    TEST_MACHINE(".demo", 4, "qemu-4-demo");
+     TEST_MACHINE("bull\U0001f4a9", 5, "qemu-5-bull");
+     TEST_MACHINE("demo..name", 6, "qemu-6-demo.name");
+     TEST_MACHINE("12345678901234567890123456789012345678901234567890123456789", 7,
+@@ -743,7 +743,8 @@ mymain(void)
+     TEST_MACHINE("kstest-network-device-default-httpks_(c9eed63e-981e-48ec-acdc-56b3f8c5f678)", 100,
+                  "qemu-100-kstest-network-device-default-httpksc9eed63e-981e-48ec");
+     TEST_MACHINE("kstest-network-device-default-httpks_(c9eed63e-981e-48ec--cdc-56b3f8c5f678)", 10,
+-                 "qemu-10-kstest-network-device-default-httpksc9eed63e-981e-48ec");
++                 "qemu-10-kstest-network-device-default-httpksc9eed63e-981e-48ec-c");
++    TEST_MACHINE("demo.-.test.", 11, "qemu-11-demo.test");
+ 
+ # define TESTS_PM_SUPPORT_HELPER(name, function) \
+     do { \
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-conf-Implement-support-for-slices-of-disk-source.patch b/SOURCES/libvirt-conf-Implement-support-for-slices-of-disk-source.patch
new file mode 100644
index 0000000..3083b2c
--- /dev/null
+++ b/SOURCES/libvirt-conf-Implement-support-for-slices-of-disk-source.patch
@@ -0,0 +1,143 @@
+From 6d5174acd7530d554ac2651f3e6a5da9f69fe6e4 Mon Sep 17 00:00:00 2001
+Message-Id: <6d5174acd7530d554ac2651f3e6a5da9f69fe6e4@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:20 +0100
+Subject: [PATCH] conf: Implement support for <slices> of disk source
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Implement parsing and formatting of the 'storage' slice.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit bbf5d05cfd003e33600009cac7ea98ef1539dd7c)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <d31bb27ae30140c9deb696972ee76a90d7bcc610.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 86 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 86 insertions(+)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index b46b92aecf..5c11f49463 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -9441,6 +9441,57 @@ virDomainStorageSourceParseBase(const char *type,
+ }
+ 
+ 
++static virStorageSourceSlicePtr
++virDomainStorageSourceParseSlice(xmlNodePtr node,
++                                 xmlXPathContextPtr ctxt)
++{
++    VIR_XPATH_NODE_AUTORESTORE(ctxt);
++    g_autofree char *offset = NULL;
++    g_autofree char *size = NULL;
++    g_autofree virStorageSourceSlicePtr ret = g_new0(virStorageSourceSlice, 1);
++
++    ctxt->node = node;
++
++    if (!(offset = virXPathString("string(./@offset)", ctxt)) ||
++        !(size = virXPathString("string(./@size)", ctxt))) {
++        virReportError(VIR_ERR_XML_ERROR, "%s",
++                       _("missing offset or size attribute of slice"));
++        return NULL;
++    }
++
++    if (virStrToLong_ullp(offset, NULL, 10, &ret->offset) < 0) {
++        virReportError(VIR_ERR_XML_ERROR,
++                       _("malformed value '%s' of 'offset' attribute of slice"),
++                       offset);
++        return NULL;
++    }
++
++    if (virStrToLong_ullp(size, NULL, 10, &ret->size) < 0) {
++        virReportError(VIR_ERR_XML_ERROR,
++                       _("malformed value '%s' of 'size' attribute of slice"),
++                       size);
++        return NULL;
++    }
++
++    return g_steal_pointer(&ret);
++}
++
++
++static int
++virDomainStorageSourceParseSlices(virStorageSourcePtr src,
++                                  xmlXPathContextPtr ctxt)
++{
++    xmlNodePtr node;
++
++    if ((node = virXPathNode("./slices/slice[@type='storage']", ctxt))) {
++        if (!(src->sliceStorage = virDomainStorageSourceParseSlice(node, ctxt)))
++            return -1;
++    }
++
++    return 0;
++}
++
++
+ /**
+  * virDomainStorageSourceParse:
+  * @node: XML node pointing to the source element to parse
+@@ -9506,6 +9557,9 @@ virDomainStorageSourceParse(xmlNodePtr node,
+     if (virDomainDiskSourcePRParse(node, ctxt, &src->pr) < 0)
+         return -1;
+ 
++    if (virDomainStorageSourceParseSlices(src, ctxt) < 0)
++        return -1;
++
+     if (virSecurityDeviceLabelDefParseXML(&src->seclabels, &src->nseclabels,
+                                           ctxt, flags) < 0)
+         return -1;
+@@ -24226,6 +24280,36 @@ virDomainDiskSourceFormatPrivateData(virBufferPtr buf,
+ }
+ 
+ 
++static void
++virDomainDiskSourceFormatSlice(virBufferPtr buf,
++                               const char *slicetype,
++                               virStorageSourceSlicePtr slice)
++{
++    g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
++
++    if (!slice)
++        return;
++
++    virBufferAsprintf(&attrBuf, " type='%s'", slicetype);
++    virBufferAsprintf(&attrBuf, " offset='%llu'", slice->offset);
++    virBufferAsprintf(&attrBuf, " size='%llu'", slice->size);
++
++    virXMLFormatElement(buf, "slice", &attrBuf, NULL);
++}
++
++
++static void
++virDomainDiskSourceFormatSlices(virBufferPtr buf,
++                                virStorageSourcePtr src)
++{
++    g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
++
++    virDomainDiskSourceFormatSlice(&childBuf, "storage", src->sliceStorage);
++
++    virXMLFormatElement(buf, "slices", NULL, &childBuf);
++}
++
++
+ /**
+  * virDomainDiskSourceFormat:
+  * @buf: output buffer
+@@ -24296,6 +24380,8 @@ virDomainDiskSourceFormat(virBufferPtr buf,
+         return -1;
+     }
+ 
++    virDomainDiskSourceFormatSlices(&childBuf, src);
++
+     if (src->type != VIR_STORAGE_TYPE_NETWORK)
+         virDomainSourceDefFormatSeclabel(&childBuf, src->nseclabels,
+                                          src->seclabels, flags);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-conf-Introduce-VIR_DOMAIN_TIMER_NAME_ARMVTIMER.patch b/SOURCES/libvirt-conf-Introduce-VIR_DOMAIN_TIMER_NAME_ARMVTIMER.patch
new file mode 100644
index 0000000..ba2679f
--- /dev/null
+++ b/SOURCES/libvirt-conf-Introduce-VIR_DOMAIN_TIMER_NAME_ARMVTIMER.patch
@@ -0,0 +1,129 @@
+From eb6bdf4798eea9bae5ddca1fdd13fb5ef6e99596 Mon Sep 17 00:00:00 2001
+Message-Id: <eb6bdf4798eea9bae5ddca1fdd13fb5ef6e99596@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 13:12:35 +0100
+Subject: [PATCH] conf: Introduce VIR_DOMAIN_TIMER_NAME_ARMVTIMER
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This new timer model will be used to control the behavior of the
+virtual timer for KVM ARM/virt guests.
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 3809e88a87e5898c9cf3a277cb32e20fca8fb2d0)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214121237.623948-5-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/schemas/domaincommon.rng | 1 +
+ src/conf/domain_conf.c        | 1 +
+ src/conf/domain_conf.h        | 1 +
+ src/libxl/libxl_conf.c        | 1 +
+ src/libxl/xen_common.c        | 1 +
+ src/qemu/qemu_command.c       | 2 ++
+ src/qemu/qemu_domain.c        | 3 +++
+ 7 files changed, 10 insertions(+)
+
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 026e753567..19476a2735 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1239,6 +1239,7 @@
+             <choice>
+               <value>hpet</value>
+               <value>pit</value>
++              <value>armvtimer</value>
+             </choice>
+           </attribute>
+           <optional>
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 58f72b3b0f..68d9ce9c4e 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -1062,6 +1062,7 @@ VIR_ENUM_IMPL(virDomainTimerName,
+               "tsc",
+               "kvmclock",
+               "hypervclock",
++              "armvtimer",
+ );
+ 
+ VIR_ENUM_IMPL(virDomainTimerTrack,
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index ee8eb3ddc0..ef2c1b80f7 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -1989,6 +1989,7 @@ typedef enum {
+     VIR_DOMAIN_TIMER_NAME_TSC,
+     VIR_DOMAIN_TIMER_NAME_KVMCLOCK,
+     VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK,
++    VIR_DOMAIN_TIMER_NAME_ARMVTIMER,
+ 
+     VIR_DOMAIN_TIMER_NAME_LAST
+ } virDomainTimerNameType;
+diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
+index 2488bb9d32..ffac890262 100644
+--- a/src/libxl/libxl_conf.c
++++ b/src/libxl/libxl_conf.c
+@@ -361,6 +361,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
+         case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
+         case VIR_DOMAIN_TIMER_NAME_RTC:
+         case VIR_DOMAIN_TIMER_NAME_PIT:
++        case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("unsupported timer type (name) '%s'"),
+                            virDomainTimerNameTypeToString(clock.timers[i]->name));
+diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c
+index 415549a42c..9a385eba0d 100644
+--- a/src/libxl/xen_common.c
++++ b/src/libxl/xen_common.c
+@@ -2182,6 +2182,7 @@ xenFormatCPUFeatures(virConfPtr conf, virDomainDefPtr def)
+         case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
+         case VIR_DOMAIN_TIMER_NAME_RTC:
+         case VIR_DOMAIN_TIMER_NAME_PIT:
++        case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("unsupported timer type (name) '%s'"),
+                            virDomainTimerNameTypeToString(def->clock.timers[i]->name));
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 0ad09baa1d..e1e19e0fcc 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -6200,6 +6200,7 @@ qemuBuildClockCommandLine(virCommandPtr cmd,
+         case VIR_DOMAIN_TIMER_NAME_TSC:
+         case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
+         case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
++        case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
+             /* Timers above are handled when building -cpu.  */
+         case VIR_DOMAIN_TIMER_NAME_LAST:
+             break;
+@@ -6631,6 +6632,7 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
+             if (timer->frequency > 0)
+                 virBufferAsprintf(&buf, ",tsc-frequency=%lu", timer->frequency);
+             break;
++        case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
+         case VIR_DOMAIN_TIMER_NAME_PLATFORM:
+         case VIR_DOMAIN_TIMER_NAME_PIT:
+         case VIR_DOMAIN_TIMER_NAME_RTC:
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 846d1ecb29..4de4f9da53 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -5504,6 +5504,9 @@ qemuDomainDefValidateClockTimers(const virDomainDef *def,
+                 return -1;
+             }
+             break;
++
++        case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
++            break;
+         }
+     }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-conf-add-support-for-specifying-CPU-dies-parameter.patch b/SOURCES/libvirt-conf-add-support-for-specifying-CPU-dies-parameter.patch
new file mode 100644
index 0000000..341c98f
--- /dev/null
+++ b/SOURCES/libvirt-conf-add-support-for-specifying-CPU-dies-parameter.patch
@@ -0,0 +1,1510 @@
+From c86535685add6ff59a6cce0fa48ee27a23d71815 Mon Sep 17 00:00:00 2001
+Message-Id: <c86535685add6ff59a6cce0fa48ee27a23d71815@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 3 Feb 2020 18:07:22 +0000
+Subject: [PATCH] conf: add support for specifying CPU "dies" parameter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Recently CPU hardware vendors have started to support a new structure
+inside the CPU package topology known as a "die". Thus the hierarchy
+is now:
+
+  sockets > dies > cores > threads
+
+This adds support for "dies" in the XML parser, with the value
+defaulting to 1 if not specified for backwards compatibility.
+
+For example a system with 64 logical CPUs might report
+
+   <topology sockets="4" dies="2" cores="4" threads="2"/>
+
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit fbf27730a36da573b1065c179f4d96b9a751f22f)
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785207
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785211
+Message-Id: <20200203180726.2203691-2-berrange@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/formatcaps.html.in                       |  2 +-
+ docs/formatdomain.html.in                     | 22 ++++++++++--------
+ docs/schemas/cputypes.rng                     |  5 ++++
+ src/bhyve/bhyve_command.c                     |  5 ++++
+ src/conf/cpu_conf.c                           | 23 +++++++++++++++++--
+ src/conf/cpu_conf.h                           |  1 +
+ src/conf/domain_conf.c                        |  3 ++-
+ src/cpu/cpu.c                                 |  1 +
+ src/libxl/libxl_capabilities.c                |  1 +
+ src/qemu/qemu_command.c                       |  5 ++++
+ src/vmx/vmx.c                                 |  7 ++++++
+ .../x86_64-host+guest,model486-result.xml     |  2 +-
+ .../x86_64-host+guest,models-result.xml       |  2 +-
+ .../cputestdata/x86_64-host+guest-result.xml  |  2 +-
+ tests/cputestdata/x86_64-host+guest.xml       |  2 +-
+ .../x86_64-host+host-model-nofallback.xml     |  2 +-
+ ...t-Haswell-noTSX+Haswell,haswell-result.xml |  2 +-
+ ...ell-noTSX+Haswell-noTSX,haswell-result.xml |  2 +-
+ ...ost-Haswell-noTSX+Haswell-noTSX-result.xml |  2 +-
+ .../x86_64-host-worse+guest-result.xml        |  2 +-
+ .../ppc64-modern-bulk-result-conf.xml         |  2 +-
+ .../ppc64-modern-bulk-result-live.xml         |  2 +-
+ .../ppc64-modern-individual-result-conf.xml   |  2 +-
+ .../ppc64-modern-individual-result-live.xml   |  2 +-
+ .../x86-modern-bulk-result-conf.xml           |  2 +-
+ .../x86-modern-bulk-result-live.xml           |  2 +-
+ .../x86-modern-individual-add-result-conf.xml |  2 +-
+ .../x86-modern-individual-add-result-live.xml |  2 +-
+ .../x86-old-bulk-result-conf.xml              |  2 +-
+ .../x86-old-bulk-result-live.xml              |  2 +-
+ .../cpu-hotplug-granularity.xml               |  2 +-
+ .../qemuxml2argvdata/cpu-hotplug-startup.xml  |  2 +-
+ tests/qemuxml2argvdata/cpu-numa-disjoint.xml  |  2 +-
+ .../qemuxml2argvdata/cpu-numa-disordered.xml  |  2 +-
+ tests/qemuxml2argvdata/cpu-numa-memshared.xml |  2 +-
+ .../cpu-numa-no-memory-element.xml            |  2 +-
+ tests/qemuxml2argvdata/cpu-numa1.xml          |  2 +-
+ tests/qemuxml2argvdata/cpu-numa2.xml          |  2 +-
+ tests/qemuxml2argvdata/cpu-numa3.xml          |  2 +-
+ tests/qemuxml2argvdata/cpu-topology1.xml      |  2 +-
+ tests/qemuxml2argvdata/cpu-topology2.xml      |  2 +-
+ tests/qemuxml2argvdata/cpu-topology3.xml      |  2 +-
+ .../fd-memory-no-numa-topology.xml            |  2 +-
+ .../fd-memory-numa-topology.xml               |  2 +-
+ .../fd-memory-numa-topology2.xml              |  2 +-
+ .../fd-memory-numa-topology3.xml              |  2 +-
+ .../graphics-spice-timeout.xml                |  2 +-
+ tests/qemuxml2argvdata/hugepages-nvdimm.xml   |  2 +-
+ .../memfd-memory-default-hugepage.xml         |  2 +-
+ tests/qemuxml2argvdata/memfd-memory-numa.xml  |  2 +-
+ tests/qemuxml2argvdata/memory-align-fail.xml  |  2 +-
+ .../memory-hotplug-dimm-addr.xml              |  2 +-
+ .../qemuxml2argvdata/memory-hotplug-dimm.xml  |  2 +-
+ .../memory-hotplug-nvdimm-access.xml          |  2 +-
+ .../memory-hotplug-nvdimm-align.xml           |  2 +-
+ .../memory-hotplug-nvdimm-label.xml           |  2 +-
+ .../memory-hotplug-nvdimm-pmem.xml            |  2 +-
+ .../memory-hotplug-nvdimm-readonly.xml        |  2 +-
+ .../memory-hotplug-nvdimm.xml                 |  2 +-
+ tests/qemuxml2argvdata/memory-hotplug.xml     |  2 +-
+ .../numad-auto-memory-vcpu-cpuset.xml         |  2 +-
+ ...to-memory-vcpu-no-cpuset-and-placement.xml |  2 +-
+ .../numad-auto-vcpu-no-numatune.xml           |  2 +-
+ ...d-auto-vcpu-static-numatune-no-nodeset.xml |  2 +-
+ .../numad-auto-vcpu-static-numatune.xml       |  2 +-
+ .../numad-static-memory-auto-vcpu.xml         |  2 +-
+ .../numad-static-vcpu-no-numatune.xml         |  2 +-
+ tests/qemuxml2argvdata/numad.xml              |  2 +-
+ .../numatune-auto-nodeset-invalid.xml         |  2 +-
+ .../numatune-memory-invalid-nodeset.xml       |  2 +-
+ tests/qemuxml2argvdata/numatune-memory.xml    |  2 +-
+ .../pci-expander-bus-bad-machine.xml          |  2 +-
+ tests/qemuxml2argvdata/pci-expander-bus.xml   |  2 +-
+ .../pcie-expander-bus-bad-bus.xml             |  2 +-
+ .../pcie-expander-bus-bad-machine.xml         |  2 +-
+ tests/qemuxml2argvdata/pcie-expander-bus.xml  |  2 +-
+ .../pseries-default-phb-numa-node.xml         |  2 +-
+ .../pseries-phb-numa-node.xml                 |  2 +-
+ tests/qemuxml2argvdata/smp.xml                |  2 +-
+ .../qemuxml2xmloutdata/cpu-numa-disjoint.xml  |  2 +-
+ .../cpu-numa-disordered.xml                   |  2 +-
+ .../qemuxml2xmloutdata/cpu-numa-memshared.xml |  2 +-
+ .../cpu-numa-no-memory-element.xml            |  2 +-
+ tests/qemuxml2xmloutdata/cpu-numa1.xml        |  2 +-
+ tests/qemuxml2xmloutdata/cpu-numa2.xml        |  2 +-
+ .../graphics-spice-timeout.xml                |  2 +-
+ .../memory-hotplug-dimm.xml                   |  2 +-
+ tests/qemuxml2xmloutdata/memory-hotplug.xml   |  2 +-
+ .../numad-auto-memory-vcpu-cpuset.xml         |  2 +-
+ ...to-memory-vcpu-no-cpuset-and-placement.xml |  2 +-
+ .../numad-auto-vcpu-no-numatune.xml           |  2 +-
+ .../numad-static-vcpu-no-numatune.xml         |  2 +-
+ tests/qemuxml2xmloutdata/pci-expander-bus.xml |  2 +-
+ .../qemuxml2xmloutdata/pcie-expander-bus.xml  |  2 +-
+ .../pseries-phb-numa-node.xml                 |  2 +-
+ tests/qemuxml2xmloutdata/smp.xml              |  2 +-
+ .../vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml |  2 +-
+ .../vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml |  2 +-
+ 98 files changed, 148 insertions(+), 101 deletions(-)
+
+diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in
+index 2a0aa963bb..59d21a7d9e 100644
+--- a/docs/formatcaps.html.in
++++ b/docs/formatcaps.html.in
+@@ -173,7 +173,7 @@
+       &lt;/features&gt;
+       &lt;model&gt;core2duo&lt;/model&gt;
+       &lt;vendor&gt;Intel&lt;/vendor&gt;
+-      &lt;topology sockets="1" cores="2" threads="1"/&gt;
++      &lt;topology sockets="1" dies="1" cores="2" threads="1"/&gt;
+       &lt;feature name="lahf_lm"/&gt;
+       &lt;feature name='xtpr'/&gt;
+       ...
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 6e86d057a8..4db9c292b7 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -1470,7 +1470,7 @@
+ &lt;cpu match='exact'&gt;
+   &lt;model fallback='allow'&gt;core2duo&lt;/model&gt;
+   &lt;vendor&gt;Intel&lt;/vendor&gt;
+-  &lt;topology sockets='1' cores='2' threads='1'/&gt;
++  &lt;topology sockets='1' dies='1' cores='2' threads='1'/&gt;
+   &lt;cache level='3' mode='emulate'/&gt;
+   &lt;feature policy='disable' name='lahf_lm'/&gt;
+ &lt;/cpu&gt;
+@@ -1479,7 +1479,7 @@
+ <pre>
+ &lt;cpu mode='host-model'&gt;
+   &lt;model fallback='forbid'/&gt;
+-  &lt;topology sockets='1' cores='2' threads='1'/&gt;
++  &lt;topology sockets='1' dies='1' cores='2' threads='1'/&gt;
+ &lt;/cpu&gt;
+ ...</pre>
+ 
+@@ -1498,7 +1498,7 @@
+ <pre>
+ ...
+ &lt;cpu&gt;
+-  &lt;topology sockets='1' cores='2' threads='1'/&gt;
++  &lt;topology sockets='1' dies='1' cores='2' threads='1'/&gt;
+ &lt;/cpu&gt;
+ ...</pre>
+ 
+@@ -1673,13 +1673,15 @@
+ 
+       <dt><code>topology</code></dt>
+       <dd>The <code>topology</code> element specifies requested topology of
+-        virtual CPU provided to the guest. Three non-zero values have to be
+-        given for <code>sockets</code>, <code>cores</code>, and
+-        <code>threads</code>: total number of CPU sockets, number of cores per
+-        socket, and number of threads per core, respectively. Hypervisors may
+-        require that the maximum number of vCPUs specified by the
+-        <code>cpus</code> element equals to the number of vcpus resulting
+-        from the topology.</dd>
++        virtual CPU provided to the guest. Four attributes, <code>sockets</code>,
++        <code>dies</code>, <code>cores</code>, and <code>threads</code>,
++        accept non-zero positive integer values. They refer to the total number
++        of CPU sockets, number of dies per socket, number of cores per die, and
++        number of threads per core, respectively. The <code>dies</code>
++        attribute is optional and will default to 1 if omitted, while the other
++        attributes are all mandatory. Hypervisors may require that the maximum
++        number of vCPUs specified by the <code>cpus</code> element equals to
++        the number of vcpus resulting from the topology.</dd>
+ 
+       <dt><code>feature</code></dt>
+       <dd>The <code>cpu</code> element can contain zero or more
+diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng
+index 1f1e0e36d5..e2744acad3 100644
+--- a/docs/schemas/cputypes.rng
++++ b/docs/schemas/cputypes.rng
+@@ -86,6 +86,11 @@
+       <attribute name="sockets">
+         <ref name="positiveInteger"/>
+       </attribute>
++      <optional>
++        <attribute name="dies">
++          <ref name="positiveInteger"/>
++        </attribute>
++      </optional>
+       <attribute name="cores">
+         <ref name="positiveInteger"/>
+       </attribute>
+diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
+index 48336ffa1b..d78221aea8 100644
+--- a/src/bhyve/bhyve_command.c
++++ b/src/bhyve/bhyve_command.c
+@@ -453,6 +453,11 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
+     /* CPUs */
+     virCommandAddArg(cmd, "-c");
+     if (def->cpu && def->cpu->sockets) {
++        if (def->dies != 1) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("Only 1 die per socket is supported"));
++            goto cleanup;
++        }
+         if (nvcpus != def->cpu->sockets * def->cpu->cores * def->cpu->threads) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                            _("Invalid CPU topology: total number of vCPUs "
+diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
+index b463981de0..837d77581c 100644
+--- a/src/conf/cpu_conf.c
++++ b/src/conf/cpu_conf.c
+@@ -239,6 +239,7 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
+     copy->check = cpu->check;
+     copy->fallback = cpu->fallback;
+     copy->sockets = cpu->sockets;
++    copy->dies = cpu->dies;
+     copy->cores = cpu->cores;
+     copy->threads = cpu->threads;
+     copy->arch = cpu->arch;
+@@ -535,6 +536,17 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
+         }
+         def->sockets = (unsigned int) ul;
+ 
++        if (virXPathNode("./topology[1]/@dies", ctxt)) {
++            if (virXPathULong("string(./topology[1]/@dies)", ctxt, &ul) < 0) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("Malformed 'dies' attribute in CPU topology"));
++                goto cleanup;
++            }
++            def->dies = (unsigned int) ul;
++        } else {
++            def->dies = 1;
++        }
++
+         if (virXPathULong("string(./topology[1]/@cores)", ctxt, &ul) < 0) {
+             virReportError(VIR_ERR_XML_ERROR, "%s",
+                            _("Missing 'cores' attribute in CPU topology"));
+@@ -549,7 +561,7 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
+         }
+         def->threads = (unsigned int) ul;
+ 
+-        if (!def->sockets || !def->cores || !def->threads) {
++        if (!def->sockets || !def->cores || !def->threads || !def->dies) {
+             virReportError(VIR_ERR_XML_ERROR, "%s",
+                            _("Invalid CPU topology"));
+             goto cleanup;
+@@ -817,9 +829,10 @@ virCPUDefFormatBuf(virBufferPtr buf,
+         virBufferAddLit(buf, "/>\n");
+     }
+ 
+-    if (def->sockets && def->cores && def->threads) {
++    if (def->sockets && def->dies && def->cores && def->threads) {
+         virBufferAddLit(buf, "<topology");
+         virBufferAsprintf(buf, " sockets='%u'", def->sockets);
++        virBufferAsprintf(buf, " dies='%u'", def->dies);
+         virBufferAsprintf(buf, " cores='%u'", def->cores);
+         virBufferAsprintf(buf, " threads='%u'", def->threads);
+         virBufferAddLit(buf, "/>\n");
+@@ -1058,6 +1071,12 @@ virCPUDefIsEqual(virCPUDefPtr src,
+         return false;
+     }
+ 
++    if (src->dies != dst->dies) {
++        MISMATCH(_("Target CPU dies %d does not match source %d"),
++                 dst->dies, src->dies);
++        return false;
++    }
++
+     if (src->cores != dst->cores) {
+         MISMATCH(_("Target CPU cores %d does not match source %d"),
+                  dst->cores, src->cores);
+diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
+index ec3d2379cf..6cef9e9726 100644
+--- a/src/conf/cpu_conf.h
++++ b/src/conf/cpu_conf.h
+@@ -134,6 +134,7 @@ struct _virCPUDef {
+     char *vendor;
+     unsigned int microcodeVersion;
+     unsigned int sockets;
++    unsigned int dies;
+     unsigned int cores;
+     unsigned int threads;
+     size_t nfeatures;
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index ee57152da7..0478914c69 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -2053,7 +2053,8 @@ virDomainDefGetVcpusTopology(const virDomainDef *def,
+     tmp = def->cpu->sockets;
+ 
+     /* multiplication of 32bit numbers fits into a 64bit variable */
+-    if ((tmp *= def->cpu->cores) > UINT_MAX ||
++    if ((tmp *= def->cpu->dies) > UINT_MAX ||
++        (tmp *= def->cpu->cores) > UINT_MAX ||
+         (tmp *= def->cpu->threads) > UINT_MAX) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                        _("cpu topology results in more than %u cpus"), UINT_MAX);
+diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
+index d99466472b..ae3a0acc10 100644
+--- a/src/cpu/cpu.c
++++ b/src/cpu/cpu.c
+@@ -421,6 +421,7 @@ virCPUGetHost(virArch arch,
+ 
+     if (nodeInfo) {
+         cpu->sockets = nodeInfo->sockets;
++        cpu->dies = 1;
+         cpu->cores = nodeInfo->cores;
+         cpu->threads = nodeInfo->threads;
+     }
+diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c
+index e9f958cd8a..beac8c8cfc 100644
+--- a/src/libxl/libxl_capabilities.c
++++ b/src/libxl/libxl_capabilities.c
+@@ -186,6 +186,7 @@ libxlCapsInitCPU(virCapsPtr caps, libxl_physinfo *phy_info,
+     cpu->type = VIR_CPU_TYPE_HOST;
+     cpu->cores = phy_info->cores_per_socket;
+     cpu->threads = phy_info->threads_per_core;
++    cpu->dies = 1;
+     cpu->sockets = phy_info->nr_cpus / (cpu->cores * cpu->threads);
+     caps->host.cpu = cpu;
+ 
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index e10cc7fc74..d7e8216092 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -7130,6 +7130,11 @@ qemuBuildSmpCommandLine(virCommandPtr cmd,
+     /* sockets, cores, and threads are either all zero
+      * or all non-zero, thus checking one of them is enough */
+     if (def->cpu && def->cpu->sockets) {
++        if (def->cpu->dies != 1) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("Only 1 die per socket is supported"));
++            return -1;
++        }
+         virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets);
+         virBufferAsprintf(&buf, ",cores=%u", def->cpu->cores);
+         virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
+diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
+index aa88dfcb5d..4362da6cee 100644
+--- a/src/vmx/vmx.c
++++ b/src/vmx/vmx.c
+@@ -1485,6 +1485,7 @@ virVMXParseConfig(virVMXContext *ctx,
+                              "'numvcpus'"));
+             goto cleanup;
+         }
++        cpu->dies = 1;
+         cpu->cores = coresPerSocket;
+         cpu->threads = 1;
+ 
+@@ -3206,6 +3207,12 @@ virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virDomainDe
+             goto cleanup;
+         }
+ 
++        if (def->cpu->dies != 1) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("Only 1 die per socket is supported"));
++            goto cleanup;
++        }
++
+         calculated_vcpus = def->cpu->sockets * def->cpu->cores;
+         if (calculated_vcpus != maxvcpus) {
+             virReportError(VIR_ERR_INTERNAL_ERROR,
+diff --git a/tests/cputestdata/x86_64-host+guest,model486-result.xml b/tests/cputestdata/x86_64-host+guest,model486-result.xml
+index 85564ff458..ea8e2d3a48 100644
+--- a/tests/cputestdata/x86_64-host+guest,model486-result.xml
++++ b/tests/cputestdata/x86_64-host+guest,model486-result.xml
+@@ -1,6 +1,6 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>486</model>
+-  <topology sockets='2' cores='4' threads='1'/>
++  <topology sockets='2' dies='1' cores='4' threads='1'/>
+   <feature policy='require' name='de'/>
+   <feature policy='require' name='tsc'/>
+   <feature policy='require' name='msr'/>
+diff --git a/tests/cputestdata/x86_64-host+guest,models-result.xml b/tests/cputestdata/x86_64-host+guest,models-result.xml
+index f79ed324c1..0dd6955898 100644
+--- a/tests/cputestdata/x86_64-host+guest,models-result.xml
++++ b/tests/cputestdata/x86_64-host+guest,models-result.xml
+@@ -1,6 +1,6 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>Nehalem</model>
+-  <topology sockets='2' cores='4' threads='1'/>
++  <topology sockets='2' dies='1' cores='4' threads='1'/>
+   <feature policy='force' name='pbe'/>
+   <feature policy='force' name='monitor'/>
+   <feature policy='require' name='xtpr'/>
+diff --git a/tests/cputestdata/x86_64-host+guest-result.xml b/tests/cputestdata/x86_64-host+guest-result.xml
+index 137a3d6647..28e3152cbf 100644
+--- a/tests/cputestdata/x86_64-host+guest-result.xml
++++ b/tests/cputestdata/x86_64-host+guest-result.xml
+@@ -1,6 +1,6 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>Penryn</model>
+-  <topology sockets='2' cores='4' threads='1'/>
++  <topology sockets='2' dies='1' cores='4' threads='1'/>
+   <feature policy='require' name='dca'/>
+   <feature policy='require' name='xtpr'/>
+   <feature policy='disable' name='sse4.2'/>
+diff --git a/tests/cputestdata/x86_64-host+guest.xml b/tests/cputestdata/x86_64-host+guest.xml
+index 137a3d6647..28e3152cbf 100644
+--- a/tests/cputestdata/x86_64-host+guest.xml
++++ b/tests/cputestdata/x86_64-host+guest.xml
+@@ -1,6 +1,6 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>Penryn</model>
+-  <topology sockets='2' cores='4' threads='1'/>
++  <topology sockets='2' dies='1' cores='4' threads='1'/>
+   <feature policy='require' name='dca'/>
+   <feature policy='require' name='xtpr'/>
+   <feature policy='disable' name='sse4.2'/>
+diff --git a/tests/cputestdata/x86_64-host+host-model-nofallback.xml b/tests/cputestdata/x86_64-host+host-model-nofallback.xml
+index 0c3ede0f6a..16d6e1daf2 100644
+--- a/tests/cputestdata/x86_64-host+host-model-nofallback.xml
++++ b/tests/cputestdata/x86_64-host+host-model-nofallback.xml
+@@ -1,7 +1,7 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='forbid'>Penryn</model>
+   <vendor>Intel</vendor>
+-  <topology sockets='1' cores='2' threads='1'/>
++  <topology sockets='1' dies='1' cores='2' threads='1'/>
+   <feature policy='require' name='dca'/>
+   <feature policy='require' name='xtpr'/>
+   <feature policy='require' name='tm2'/>
+diff --git a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml
+index 2dbe06c314..8eda6684a0 100644
+--- a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml
++++ b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml
+@@ -1,6 +1,6 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>Haswell</model>
+-  <topology sockets='1' cores='2' threads='2'/>
++  <topology sockets='1' dies='1' cores='2' threads='2'/>
+   <feature policy='disable' name='rtm'/>
+   <feature policy='disable' name='hle'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml
+index 5d149bb295..cb02449d60 100644
+--- a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml
++++ b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml
+@@ -1,6 +1,6 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>Haswell</model>
+-  <topology sockets='1' cores='2' threads='2'/>
++  <topology sockets='1' dies='1' cores='2' threads='2'/>
+   <feature policy='disable' name='hle'/>
+   <feature policy='disable' name='rtm'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml
+index 3b74089647..7ee926aba8 100644
+--- a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml
++++ b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml
+@@ -1,4 +1,4 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>Haswell-noTSX</model>
+-  <topology sockets='1' cores='2' threads='2'/>
++  <topology sockets='1' dies='1' cores='2' threads='2'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-host-worse+guest-result.xml b/tests/cputestdata/x86_64-host-worse+guest-result.xml
+index 2edc8756c4..9d54c66a8f 100644
+--- a/tests/cputestdata/x86_64-host-worse+guest-result.xml
++++ b/tests/cputestdata/x86_64-host-worse+guest-result.xml
+@@ -1,6 +1,6 @@
+ <cpu mode='custom' match='exact'>
+   <model fallback='allow'>Penryn</model>
+-  <topology sockets='2' cores='4' threads='1'/>
++  <topology sockets='2' dies='1' cores='4' threads='1'/>
+   <feature policy='disable' name='dca'/>
+   <feature policy='disable' name='xtpr'/>
+   <feature policy='disable' name='sse4.2'/>
+diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml
+index 1a769235a3..f80c4367df 100644
+--- a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml
++++ b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml
+@@ -43,7 +43,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='4' threads='8'/>
++    <topology sockets='1' dies='1' cores='4' threads='8'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml
+index 43e6267250..7998b978fb 100644
+--- a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml
++++ b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml
+@@ -43,7 +43,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='4' threads='8'/>
++    <topology sockets='1' dies='1' cores='4' threads='8'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml
+index cfb44cc433..2a48a97eef 100644
+--- a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml
++++ b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml
+@@ -43,7 +43,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='4' threads='8'/>
++    <topology sockets='1' dies='1' cores='4' threads='8'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml
+index 0a8d372149..90518d1fa9 100644
+--- a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml
++++ b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml
+@@ -43,7 +43,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='4' threads='8'/>
++    <topology sockets='1' dies='1' cores='4' threads='8'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml
+index 6457f4056b..0d622fc8ae 100644
+--- a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml
++++ b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml
+@@ -19,7 +19,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='2' threads='1'/>
++    <topology sockets='4' dies='1' cores='2' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml
+index fe9a81a091..ed9deaea4a 100644
+--- a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml
++++ b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml
+@@ -19,7 +19,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='2' threads='1'/>
++    <topology sockets='4' dies='1' cores='2' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml
+index 58c088de88..342f172108 100644
+--- a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml
++++ b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml
+@@ -19,7 +19,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='2' threads='1'/>
++    <topology sockets='4' dies='1' cores='2' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml
+index 12b28be5fe..b8341c74e5 100644
+--- a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml
++++ b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml
+@@ -19,7 +19,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='2' threads='1'/>
++    <topology sockets='4' dies='1' cores='2' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml b/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml
+index f635e37b82..29da89f5bc 100644
+--- a/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml
++++ b/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='2' threads='1'/>
++    <topology sockets='4' dies='1' cores='2' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml b/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml
+index 6f50bb5c12..f81194db5b 100644
+--- a/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml
++++ b/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='2' threads='1'/>
++    <topology sockets='4' dies='1' cores='2' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/cpu-hotplug-granularity.xml b/tests/qemuxml2argvdata/cpu-hotplug-granularity.xml
+index a94f41e46a..bf6a42c306 100644
+--- a/tests/qemuxml2argvdata/cpu-hotplug-granularity.xml
++++ b/tests/qemuxml2argvdata/cpu-hotplug-granularity.xml
+@@ -7,7 +7,7 @@
+     <type arch='ppc64' machine='pseries'>hvm</type>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='2' threads='4'/>
++    <topology sockets='1' dies='1' cores='2' threads='4'/>
+   </cpu>
+   <devices>
+     <emulator>/usr/bin/qemu-system-ppc64</emulator>
+diff --git a/tests/qemuxml2argvdata/cpu-hotplug-startup.xml b/tests/qemuxml2argvdata/cpu-hotplug-startup.xml
+index 99987ba15a..9d764e2f8c 100644
+--- a/tests/qemuxml2argvdata/cpu-hotplug-startup.xml
++++ b/tests/qemuxml2argvdata/cpu-hotplug-startup.xml
+@@ -17,7 +17,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets="3" cores="2" threads="1"/>
++    <topology sockets="3" dies="1" cores="2" threads="1"/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/cpu-numa-disjoint.xml b/tests/qemuxml2argvdata/cpu-numa-disjoint.xml
+index b022384e97..c164b15e82 100644
+--- a/tests/qemuxml2argvdata/cpu-numa-disjoint.xml
++++ b/tests/qemuxml2argvdata/cpu-numa-disjoint.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-3,8-11' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='4-7,12-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/cpu-numa-disordered.xml b/tests/qemuxml2argvdata/cpu-numa-disordered.xml
+index e209150a55..6e00b91281 100644
+--- a/tests/qemuxml2argvdata/cpu-numa-disordered.xml
++++ b/tests/qemuxml2argvdata/cpu-numa-disordered.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-5' memory='109550' unit='KiB'/>
+       <cell id='2' cpus='6-10' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/cpu-numa-memshared.xml b/tests/qemuxml2argvdata/cpu-numa-memshared.xml
+index 7e05916f78..f2ef035b00 100644
+--- a/tests/qemuxml2argvdata/cpu-numa-memshared.xml
++++ b/tests/qemuxml2argvdata/cpu-numa-memshared.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB' memAccess='shared'/>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB' memAccess='private'/>
+diff --git a/tests/qemuxml2argvdata/cpu-numa-no-memory-element.xml b/tests/qemuxml2argvdata/cpu-numa-no-memory-element.xml
+index ee6b6aa870..97dac01e84 100644
+--- a/tests/qemuxml2argvdata/cpu-numa-no-memory-element.xml
++++ b/tests/qemuxml2argvdata/cpu-numa-no-memory-element.xml
+@@ -8,7 +8,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB'/>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/cpu-numa1.xml b/tests/qemuxml2argvdata/cpu-numa1.xml
+index b21941d51a..867d21e152 100644
+--- a/tests/qemuxml2argvdata/cpu-numa1.xml
++++ b/tests/qemuxml2argvdata/cpu-numa1.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell cpus='0-7' memory='109550' unit='KiB'/>
+       <cell cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/cpu-numa2.xml b/tests/qemuxml2argvdata/cpu-numa2.xml
+index b85b19f5e0..e589948dc7 100644
+--- a/tests/qemuxml2argvdata/cpu-numa2.xml
++++ b/tests/qemuxml2argvdata/cpu-numa2.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB'/>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/cpu-numa3.xml b/tests/qemuxml2argvdata/cpu-numa3.xml
+index e2b9e9014d..350fbe7c07 100644
+--- a/tests/qemuxml2argvdata/cpu-numa3.xml
++++ b/tests/qemuxml2argvdata/cpu-numa3.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='1' cpus='0-7' memory='109550' unit='KiB'/>
+       <cell id='2' cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/cpu-topology1.xml b/tests/qemuxml2argvdata/cpu-topology1.xml
+index 9d77d10a5c..af82a1c51a 100644
+--- a/tests/qemuxml2argvdata/cpu-topology1.xml
++++ b/tests/qemuxml2argvdata/cpu-topology1.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets="3" cores="2" threads="1"/>
++    <topology sockets="3" dies="1" cores="2" threads="1"/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/cpu-topology2.xml b/tests/qemuxml2argvdata/cpu-topology2.xml
+index 9d9701914a..1b113b8b13 100644
+--- a/tests/qemuxml2argvdata/cpu-topology2.xml
++++ b/tests/qemuxml2argvdata/cpu-topology2.xml
+@@ -10,7 +10,7 @@
+   </os>
+   <cpu match='exact'>
+     <model>core2duo</model>
+-    <topology sockets="1" cores="2" threads="3"/>
++    <topology sockets="1" dies="1" cores="2" threads="3"/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/cpu-topology3.xml b/tests/qemuxml2argvdata/cpu-topology3.xml
+index 9d77d10a5c..af82a1c51a 100644
+--- a/tests/qemuxml2argvdata/cpu-topology3.xml
++++ b/tests/qemuxml2argvdata/cpu-topology3.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets="3" cores="2" threads="1"/>
++    <topology sockets="3" dies="1" cores="2" threads="1"/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml b/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml
+index 4c30761110..eb3300b1fb 100644
+--- a/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml
++++ b/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml
+@@ -14,7 +14,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='8' cores='1' threads='1'/>
++    <topology sockets='8' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/fd-memory-numa-topology.xml b/tests/qemuxml2argvdata/fd-memory-numa-topology.xml
+index f22a8e81f8..b7b5a19166 100644
+--- a/tests/qemuxml2argvdata/fd-memory-numa-topology.xml
++++ b/tests/qemuxml2argvdata/fd-memory-numa-topology.xml
+@@ -14,7 +14,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='8' threads='1'/>
++    <topology sockets='1' dies='1' cores='8' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='14680064' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml b/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml
+index 925f39b6ab..07de0bd717 100644
+--- a/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml
++++ b/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml
+@@ -14,7 +14,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='8' threads='1'/>
++    <topology sockets='1' dies='1' cores='8' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='14680064' unit='KiB'/>
+       <cell id='1' cpus='8-15' memory='14680064' unit='KiB' memAccess='shared'/>
+diff --git a/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml b/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml
+index 71a8e083c9..8711641b68 100644
+--- a/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml
++++ b/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml
+@@ -14,7 +14,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='24' threads='1'/>
++    <topology sockets='1' dies='1' cores='24' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='14680064' unit='KiB'/>
+       <cell id='1' cpus='2-3' memory='14680064' unit='KiB' memAccess='shared'/>
+diff --git a/tests/qemuxml2argvdata/graphics-spice-timeout.xml b/tests/qemuxml2argvdata/graphics-spice-timeout.xml
+index 6bb4eb8f4c..d96f519bf8 100644
+--- a/tests/qemuxml2argvdata/graphics-spice-timeout.xml
++++ b/tests/qemuxml2argvdata/graphics-spice-timeout.xml
+@@ -18,7 +18,7 @@
+   <cpu match='exact'>
+     <model>core2duo</model>
+     <vendor>Intel</vendor>
+-    <topology sockets='1' cores='2' threads='1'/>
++    <topology sockets='1' dies='1' cores='2' threads='1'/>
+     <feature policy='require' name='ds'/>
+     <feature policy='require' name='acpi'/>
+     <feature policy='require' name='ss'/>
+diff --git a/tests/qemuxml2argvdata/hugepages-nvdimm.xml b/tests/qemuxml2argvdata/hugepages-nvdimm.xml
+index b784777805..144d02b56e 100644
+--- a/tests/qemuxml2argvdata/hugepages-nvdimm.xml
++++ b/tests/qemuxml2argvdata/hugepages-nvdimm.xml
+@@ -16,7 +16,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='1048576' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml b/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml
+index 45ff012711..ded56dd538 100644
+--- a/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml
++++ b/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml
+@@ -18,7 +18,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='8' threads='1'/>
++    <topology sockets='1' dies='1' cores='8' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='14680064' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memfd-memory-numa.xml b/tests/qemuxml2argvdata/memfd-memory-numa.xml
+index f088f01d11..ebe638f600 100644
+--- a/tests/qemuxml2argvdata/memfd-memory-numa.xml
++++ b/tests/qemuxml2argvdata/memfd-memory-numa.xml
+@@ -20,7 +20,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='1' cores='8' threads='1'/>
++    <topology sockets='1' dies='1' cores='8' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='14680064' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-align-fail.xml b/tests/qemuxml2argvdata/memory-align-fail.xml
+index 75c1a46068..636f0e3d8e 100644
+--- a/tests/qemuxml2argvdata/memory-align-fail.xml
++++ b/tests/qemuxml2argvdata/memory-align-fail.xml
+@@ -10,7 +10,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='9007199254740991' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml b/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml
+index c289fdd5ff..ea4f4fd745 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml
+@@ -10,7 +10,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-dimm.xml b/tests/qemuxml2argvdata/memory-hotplug-dimm.xml
+index c68336f871..585e0a5f51 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-dimm.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-dimm.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml
+index 4e62dd0e18..a1cc1264eb 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml
+index defa109e80..018a693aaf 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml
+index 89d01d672f..c9d54a6088 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml
+index e6a4f7901a..391d70f20e 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml
+index dd48540712..09b2c5c833 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml
+index 9c76dda6c8..a32474da06 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='1048576' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/memory-hotplug.xml b/tests/qemuxml2argvdata/memory-hotplug.xml
+index e1f086567b..8d09856e95 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug.xml
++++ b/tests/qemuxml2argvdata/memory-hotplug.xml
+@@ -10,7 +10,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/numad-auto-memory-vcpu-cpuset.xml b/tests/qemuxml2argvdata/numad-auto-memory-vcpu-cpuset.xml
+index 50dbc3c466..5758e65d09 100644
+--- a/tests/qemuxml2argvdata/numad-auto-memory-vcpu-cpuset.xml
++++ b/tests/qemuxml2argvdata/numad-auto-memory-vcpu-cpuset.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml b/tests/qemuxml2argvdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml
+index d9cd6b83f1..80314d05a3 100644
+--- a/tests/qemuxml2argvdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml
++++ b/tests/qemuxml2argvdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numad-auto-vcpu-no-numatune.xml b/tests/qemuxml2argvdata/numad-auto-vcpu-no-numatune.xml
+index f21ba0a786..0edf8ee46f 100644
+--- a/tests/qemuxml2argvdata/numad-auto-vcpu-no-numatune.xml
++++ b/tests/qemuxml2argvdata/numad-auto-vcpu-no-numatune.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune-no-nodeset.xml b/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune-no-nodeset.xml
+index 378d17face..517dd5dbd7 100644
+--- a/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune-no-nodeset.xml
++++ b/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune-no-nodeset.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune.xml b/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune.xml
+index e20bd8db0b..a7f32b6802 100644
+--- a/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune.xml
++++ b/tests/qemuxml2argvdata/numad-auto-vcpu-static-numatune.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numad-static-memory-auto-vcpu.xml b/tests/qemuxml2argvdata/numad-static-memory-auto-vcpu.xml
+index 50dbc3c466..5758e65d09 100644
+--- a/tests/qemuxml2argvdata/numad-static-memory-auto-vcpu.xml
++++ b/tests/qemuxml2argvdata/numad-static-memory-auto-vcpu.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numad-static-vcpu-no-numatune.xml b/tests/qemuxml2argvdata/numad-static-vcpu-no-numatune.xml
+index 7ccaa5aff4..3237e7c7c5 100644
+--- a/tests/qemuxml2argvdata/numad-static-vcpu-no-numatune.xml
++++ b/tests/qemuxml2argvdata/numad-static-vcpu-no-numatune.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numad.xml b/tests/qemuxml2argvdata/numad.xml
+index 081a59a013..ae995e2d6b 100644
+--- a/tests/qemuxml2argvdata/numad.xml
++++ b/tests/qemuxml2argvdata/numad.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numatune-auto-nodeset-invalid.xml b/tests/qemuxml2argvdata/numatune-auto-nodeset-invalid.xml
+index 44ec55a810..e6ca895b0d 100644
+--- a/tests/qemuxml2argvdata/numatune-auto-nodeset-invalid.xml
++++ b/tests/qemuxml2argvdata/numatune-auto-nodeset-invalid.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numatune-memory-invalid-nodeset.xml b/tests/qemuxml2argvdata/numatune-memory-invalid-nodeset.xml
+index 441f2b8989..70e7b92f34 100644
+--- a/tests/qemuxml2argvdata/numatune-memory-invalid-nodeset.xml
++++ b/tests/qemuxml2argvdata/numatune-memory-invalid-nodeset.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/numatune-memory.xml b/tests/qemuxml2argvdata/numatune-memory.xml
+index c9887dbebc..93ee70cc0b 100644
+--- a/tests/qemuxml2argvdata/numatune-memory.xml
++++ b/tests/qemuxml2argvdata/numatune-memory.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2argvdata/pci-expander-bus-bad-machine.xml b/tests/qemuxml2argvdata/pci-expander-bus-bad-machine.xml
+index 606ddfd73c..5093944a1c 100644
+--- a/tests/qemuxml2argvdata/pci-expander-bus-bad-machine.xml
++++ b/tests/qemuxml2argvdata/pci-expander-bus-bad-machine.xml
+@@ -8,7 +8,7 @@
+     <type arch='x86_64' machine='q35'>hvm</type>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell cpus='0-7' memory='109550' unit='KiB'/>
+       <cell cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/pci-expander-bus.xml b/tests/qemuxml2argvdata/pci-expander-bus.xml
+index 79c959346d..d9aeda1757 100644
+--- a/tests/qemuxml2argvdata/pci-expander-bus.xml
++++ b/tests/qemuxml2argvdata/pci-expander-bus.xml
+@@ -8,7 +8,7 @@
+     <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell cpus='0-7' memory='109550' unit='KiB'/>
+       <cell cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/pcie-expander-bus-bad-bus.xml b/tests/qemuxml2argvdata/pcie-expander-bus-bad-bus.xml
+index f0ab0a16d1..4a6cb492bb 100644
+--- a/tests/qemuxml2argvdata/pcie-expander-bus-bad-bus.xml
++++ b/tests/qemuxml2argvdata/pcie-expander-bus-bad-bus.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell cpus='0-7' memory='109550' unit='KiB'/>
+       <cell cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/pcie-expander-bus-bad-machine.xml b/tests/qemuxml2argvdata/pcie-expander-bus-bad-machine.xml
+index dc64d97b83..1c27047b75 100644
+--- a/tests/qemuxml2argvdata/pcie-expander-bus-bad-machine.xml
++++ b/tests/qemuxml2argvdata/pcie-expander-bus-bad-machine.xml
+@@ -8,7 +8,7 @@
+     <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell cpus='0-7' memory='109550' unit='KiB'/>
+       <cell cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/pcie-expander-bus.xml b/tests/qemuxml2argvdata/pcie-expander-bus.xml
+index 5c5d34d1e0..80693f8a1c 100644
+--- a/tests/qemuxml2argvdata/pcie-expander-bus.xml
++++ b/tests/qemuxml2argvdata/pcie-expander-bus.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell cpus='0-7' memory='109550' unit='KiB'/>
+       <cell cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/pseries-default-phb-numa-node.xml b/tests/qemuxml2argvdata/pseries-default-phb-numa-node.xml
+index 12d277aaf8..27f211d59d 100644
+--- a/tests/qemuxml2argvdata/pseries-default-phb-numa-node.xml
++++ b/tests/qemuxml2argvdata/pseries-default-phb-numa-node.xml
+@@ -7,7 +7,7 @@
+     <memnode cellid="0" mode="strict" nodeset="1"/>
+   </numatune>
+   <cpu>
+-    <topology sockets='3' cores='1' threads='8'/>
++    <topology sockets='3' dies='1' cores='1' threads='8'/>
+     <numa>
+       <cell id='0' cpus='0-23' memory='1048576' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2argvdata/pseries-phb-numa-node.xml b/tests/qemuxml2argvdata/pseries-phb-numa-node.xml
+index aeccb14dfb..52c39d5dbd 100644
+--- a/tests/qemuxml2argvdata/pseries-phb-numa-node.xml
++++ b/tests/qemuxml2argvdata/pseries-phb-numa-node.xml
+@@ -8,7 +8,7 @@
+     <memnode cellid="1" mode="strict" nodeset="2"/>
+   </numatune>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='4'/>
++    <topology sockets='2' dies='1' cores='1' threads='4'/>
+     <numa>
+       <cell id='0' cpus='0-3' memory='1048576' unit='KiB'/>
+       <cell id='1' cpus='4-7' memory='1048576' unit='KiB'/>
+diff --git a/tests/qemuxml2argvdata/smp.xml b/tests/qemuxml2argvdata/smp.xml
+index 55d5cdeff2..6041506ed8 100644
+--- a/tests/qemuxml2argvdata/smp.xml
++++ b/tests/qemuxml2argvdata/smp.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml b/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml
+index f0ca39b5d3..d7f5372fbc 100644
+--- a/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml
++++ b/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-3,8-11' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='4-7,12-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml b/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml
+index 1e672adc44..487ced1008 100644
+--- a/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml
++++ b/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-5' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='11-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml b/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml
+index 3db0db047c..f472bffec3 100644
+--- a/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml
++++ b/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB' memAccess='shared'/>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB' memAccess='private'/>
+diff --git a/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml b/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml
+index 8596baae6c..2ef7f84646 100644
+--- a/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml
++++ b/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/cpu-numa1.xml b/tests/qemuxml2xmloutdata/cpu-numa1.xml
+index 8596baae6c..2ef7f84646 100644
+--- a/tests/qemuxml2xmloutdata/cpu-numa1.xml
++++ b/tests/qemuxml2xmloutdata/cpu-numa1.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/cpu-numa2.xml b/tests/qemuxml2xmloutdata/cpu-numa2.xml
+index 8596baae6c..2ef7f84646 100644
+--- a/tests/qemuxml2xmloutdata/cpu-numa2.xml
++++ b/tests/qemuxml2xmloutdata/cpu-numa2.xml
+@@ -9,7 +9,7 @@
+     <boot dev='network'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml b/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml
+index 3f0babd8fc..6e23652448 100644
+--- a/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml
++++ b/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml
+@@ -18,7 +18,7 @@
+   <cpu mode='custom' match='exact' check='partial'>
+     <model fallback='allow'>core2duo</model>
+     <vendor>Intel</vendor>
+-    <topology sockets='1' cores='2' threads='1'/>
++    <topology sockets='1' dies='1' cores='2' threads='1'/>
+     <feature policy='require' name='ds'/>
+     <feature policy='require' name='acpi'/>
+     <feature policy='require' name='ss'/>
+diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml b/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml
+index f4a118cea5..326b5c954c 100644
+--- a/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml
++++ b/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml
+@@ -14,7 +14,7 @@
+     <gid start='0' target='1000' count='10'/>
+   </idmap>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2xmloutdata/memory-hotplug.xml b/tests/qemuxml2xmloutdata/memory-hotplug.xml
+index 0e02f210bc..0e5295dcd0 100644
+--- a/tests/qemuxml2xmloutdata/memory-hotplug.xml
++++ b/tests/qemuxml2xmloutdata/memory-hotplug.xml
+@@ -10,7 +10,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+     <numa>
+       <cell id='0' cpus='0-1' memory='219136' unit='KiB'/>
+     </numa>
+diff --git a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml
+index 133177b679..841ea699a1 100644
+--- a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml
++++ b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml
+index dc14ecd139..2e3998e155 100644
+--- a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml
++++ b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml b/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml
+index 76d7c3b835..7c1f18c216 100644
+--- a/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml
++++ b/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml
+@@ -12,7 +12,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml b/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml
+index 523962117e..3d05790c0e 100644
+--- a/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml
++++ b/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/qemuxml2xmloutdata/pci-expander-bus.xml b/tests/qemuxml2xmloutdata/pci-expander-bus.xml
+index e0d787e57c..60e4e4af7f 100644
+--- a/tests/qemuxml2xmloutdata/pci-expander-bus.xml
++++ b/tests/qemuxml2xmloutdata/pci-expander-bus.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml
+index 643b4823bb..452d476da6 100644
+--- a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml
++++ b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='4' threads='2'/>
++    <topology sockets='2' dies='1' cores='4' threads='2'/>
+     <numa>
+       <cell id='0' cpus='0-7' memory='109550' unit='KiB'/>
+       <cell id='1' cpus='8-15' memory='109550' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml b/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml
+index 80b771e89d..b05ac334a6 100644
+--- a/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml
++++ b/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml
+@@ -13,7 +13,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='4'/>
++    <topology sockets='2' dies='1' cores='1' threads='4'/>
+     <numa>
+       <cell id='0' cpus='0-3' memory='1048576' unit='KiB'/>
+       <cell id='1' cpus='4-7' memory='1048576' unit='KiB'/>
+diff --git a/tests/qemuxml2xmloutdata/smp.xml b/tests/qemuxml2xmloutdata/smp.xml
+index d3712cb7df..3e00f578e5 100644
+--- a/tests/qemuxml2xmloutdata/smp.xml
++++ b/tests/qemuxml2xmloutdata/smp.xml
+@@ -9,7 +9,7 @@
+     <boot dev='hd'/>
+   </os>
+   <cpu>
+-    <topology sockets='2' cores='1' threads='1'/>
++    <topology sockets='2' dies='1' cores='1' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml
+index eba5f4734a..2011bfb3b9 100644
+--- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml
++++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml
+@@ -11,7 +11,7 @@
+     <type arch='x86_64'>hvm</type>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='2' threads='1'/>
++    <topology sockets='4' dies='1' cores='2' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml
+index f1fe6dd4c9..fa428c1986 100644
+--- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml
++++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml
+@@ -12,7 +12,7 @@
+     <type arch='x86_64'>hvm</type>
+   </os>
+   <cpu>
+-    <topology sockets='4' cores='4' threads='1'/>
++    <topology sockets='4' dies='1' cores='4' threads='1'/>
+   </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-conf-add-virtiofs-related-elements-and-attributes.patch b/SOURCES/libvirt-conf-add-virtiofs-related-elements-and-attributes.patch
new file mode 100644
index 0000000..7cf26c8
--- /dev/null
+++ b/SOURCES/libvirt-conf-add-virtiofs-related-elements-and-attributes.patch
@@ -0,0 +1,395 @@
+From c811bd72130364673dd4a0d2a997a1d8f675eb71 Mon Sep 17 00:00:00 2001
+Message-Id: <c811bd72130364673dd4a0d2a997a1d8f675eb71@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:42 +0100
+Subject: [PATCH] conf: add virtiofs-related elements and attributes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add more elements for tuning the virtiofsd daemon
+and the vhost-user-fs device:
+
+  <driver type='virtiofs' queue='1024' xattr='on'>
+    <binary path='/usr/libexec/virtiofsd'>
+      <cache mode='always'/>
+      <lock posix='off' flock='off'/>
+    </binary>
+  </driver>
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 66079339847dc942b9b673e3040b56b055a8d8f5)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <506d0532c6043a9b8c946bdc42c3d9c5529f6fb8.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ docs/formatdomain.html.in                     |  25 ++++-
+ docs/schemas/domaincommon.rng                 |  48 ++++++++
+ src/conf/domain_conf.c                        | 104 +++++++++++++++++-
+ src/conf/domain_conf.h                        |  15 +++
+ src/libvirt_private.syms                      |   1 +
+ .../vhost-user-fs-fd-memory.xml               |   6 +-
+ .../vhost-user-fs-hugepages.xml               |   1 +
+ 7 files changed, 197 insertions(+), 3 deletions(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 337ab01316..e9830ab231 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -3936,7 +3936,11 @@
+     &lt;readonly/&gt;
+   &lt;/filesystem&gt;
+   &lt;filesystem type='mount' accessmode='passthrough'&gt;
+-      &lt;driver type='virtiofs'/&gt;
++      &lt;driver type='virtiofs queue='1024'/&gt;
++      &lt;binary path='/usr/libexec/virtiofsd' xattr='on'&gt;
++         &lt;cache mode='always'/&gt;
++         &lt;lock posix='on' flock='on'/&gt;
++      &lt;/binary&gt;
+       &lt;source dir='/path'/&gt;
+       &lt;target dir='mount_tag'/&gt;
+   &lt;/filesystem&gt;
+@@ -4063,9 +4067,28 @@
+           <a href="#elementsVirtio">Virtio-specific options</a> can also be
+           set. (<span class="since">Since 3.5.0</span>)
+           </li>
++          <li>
++            For <code>virtiofs</code>, the <code>queue</code> attribute can be used
++            to specify the queue size (i.e. how many requests can the queue fit).
++            (<span class="since">Since 6.2.0</span>)
++          </li>
+         </ul>
+       </dd>
+ 
++      <dt><code>binary</code></dt>
++      <dd>
++        The optional <code>binary</code> element can tune the options for virtiofsd.
++        All of the following attributes and elements are optional.
++        The attribute <code>path</code> can be used to override the path to the daemon.
++        Attribute <code>xattr</code> enables the use of filesystem extended attributes.
++        Caching can be tuned via the <code>cache</code> element, possible <code>mode</code>
++        values being <code>none</code> and <code>always</code>.
++        Locking can be controlled via the <code>lock</code>
++        element - attributes <code>posix</code> and <code>flock</code> both accepting
++        values <code>on</code> or <code>off</code>.
++        (<span class="since">Since 6.2.0</span>)
++      </dd>
++
+       <dt><code>source</code></dt>
+       <dd>
+         The resource on the host that is being accessed in the guest. The
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 5a9291b443..aa70e340b9 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -2500,6 +2500,9 @@
+           <optional>
+             <ref name="fsDriver"/>
+           </optional>
++          <optional>
++            <ref name="fsBinary"/>
++          </optional>
+           <interleave>
+             <element name="source">
+               <attribute name="dir">
+@@ -2649,12 +2652,57 @@
+           <attribute name="type">
+             <value>virtiofs</value>
+           </attribute>
++          <optional>
++            <attribute name="queue">
++              <ref name="unsignedInt"/>
++            </attribute>
++          </optional>
+           <ref name='virtioOptions'/>
+         </group>
+         <empty/>
+       </choice>
+     </element>
+   </define>
++  <define name="fsBinary">
++    <element name="binary">
++      <optional>
++        <attribute name="path">
++          <ref name="absFilePath"/>
++        </attribute>
++      </optional>
++      <optional>
++        <attribute name="xattr">
++          <ref name="virOnOff"/>
++        </attribute>
++      </optional>
++      <optional>
++        <element name="cache">
++          <optional>
++            <attribute name="mode">
++              <choice>
++                <value>none</value>
++                <value>always</value>
++              </choice>
++            </attribute>
++          </optional>
++        </element>
++      </optional>
++      <optional>
++        <element name="lock">
++          <optional>
++            <attribute name="posix">
++              <ref name="virOnOff"/>
++            </attribute>
++          </optional>
++          <optional>
++            <attribute name="flock">
++              <ref name="virOnOff"/>
++            </attribute>
++          </optional>
++        </element>
++      </optional>
++    </element>
++  </define>
+ 
+   <define name="interface-network-attributes">
+     <attribute name="network">
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 31d4828802..3a370e6b90 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -500,6 +500,14 @@ VIR_ENUM_IMPL(virDomainFSModel,
+               "virtio-non-transitional",
+ );
+ 
++VIR_ENUM_IMPL(virDomainFSCacheMode,
++              VIR_DOMAIN_FS_CACHE_MODE_LAST,
++              "default",
++              "none",
++              "always",
++);
++
++
+ VIR_ENUM_IMPL(virDomainNet,
+               VIR_DOMAIN_NET_TYPE_LAST,
+               "user",
+@@ -2322,6 +2330,7 @@ void virDomainFSDefFree(virDomainFSDefPtr def)
+     virDomainDeviceInfoClear(&def->info);
+     VIR_FREE(def->virtio);
+     virObjectUnref(def->privateData);
++    VIR_FREE(def->binary);
+ 
+     VIR_FREE(def);
+ }
+@@ -11293,6 +11302,63 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
+         }
+     }
+ 
++    if (def->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
++        g_autofree char *queue_size = virXPathString("string(./driver/@queue)", ctxt);
++        g_autofree char *binary = virXPathString("string(./binary/@path)", ctxt);
++        g_autofree char *xattr = virXPathString("string(./binary/@xattr)", ctxt);
++        g_autofree char *cache = virXPathString("string(./binary/cache/@mode)", ctxt);
++        g_autofree char *posix_lock = virXPathString("string(./binary/lock/@posix)", ctxt);
++        g_autofree char *flock = virXPathString("string(./binary/lock/@flock)", ctxt);
++        int val;
++
++        if (queue_size && virStrToLong_ull(queue_size, NULL, 10, &def->queue_size) < 0) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("cannot parse queue size '%s' for virtiofs"),
++                           queue_size);
++            goto error;
++        }
++
++        if (binary)
++            def->binary = virFileSanitizePath(binary);
++
++        if (xattr) {
++            if ((val = virTristateSwitchTypeFromString(xattr)) <= 0) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                               _("unknown xattr value '%s'"), xattr);
++                goto error;
++            }
++            def->xattr = val;
++        }
++
++        if (cache) {
++            if ((val = virDomainFSCacheModeTypeFromString(cache)) <= 0) {
++                virReportError(VIR_ERR_XML_ERROR,
++                               _("cannot parse cache mode '%s' for virtiofs"),
++                               cache);
++                goto error;
++            }
++            def->cache = val;
++        }
++
++        if (posix_lock) {
++            if ((val = virTristateSwitchTypeFromString(posix_lock)) <= 0) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                               _("unknown posix lock value '%s'"), posix_lock);
++                goto error;
++            }
++            def->posix_lock = val;
++        }
++
++        if (flock) {
++            if ((val = virTristateSwitchTypeFromString(flock)) <= 0) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                               _("unknown flock value '%s'"), flock);
++                goto error;
++            }
++            def->flock = val;
++        }
++    }
++
+     if (format) {
+         if ((def->format = virStorageFileFormatTypeFromString(format)) <= 0) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+@@ -24994,6 +25060,9 @@ virDomainFSDefFormat(virBufferPtr buf,
+     const char *wrpolicy = virDomainFSWrpolicyTypeToString(def->wrpolicy);
+     const char *src = def->src->path;
+     g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
++    g_auto(virBuffer) driverBuf = VIR_BUFFER_INIT_CHILD(buf);
++    g_auto(virBuffer) binaryAttrBuf = VIR_BUFFER_INITIALIZER;
++    g_auto(virBuffer) binaryBuf = VIR_BUFFER_INIT_CHILD(buf);
+ 
+     if (!type) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+@@ -25017,6 +25086,8 @@ virDomainFSDefFormat(virBufferPtr buf,
+     virBufferAddLit(buf, ">\n");
+ 
+     virBufferAdjustIndent(buf, 2);
++    virBufferAdjustIndent(&driverBuf, 2);
++    virBufferAdjustIndent(&binaryBuf, 2);
+     if (def->fsdriver) {
+         virBufferAsprintf(&driverAttrBuf, " type='%s'", fsdriver);
+ 
+@@ -25028,11 +25099,42 @@ virDomainFSDefFormat(virBufferPtr buf,
+         if (def->wrpolicy)
+             virBufferAsprintf(&driverAttrBuf, " wrpolicy='%s'", wrpolicy);
+ 
++        if (def->queue_size)
++            virBufferAsprintf(&driverAttrBuf, " queue='%llu'", def->queue_size);
++
++    }
++
++    if (def->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
++        g_auto(virBuffer) lockAttrBuf = VIR_BUFFER_INITIALIZER;
++        virBufferEscapeString(&binaryAttrBuf, " path='%s'", def->binary);
++
++        if (def->xattr != VIR_TRISTATE_SWITCH_ABSENT) {
++            virBufferAsprintf(&binaryAttrBuf, " xattr='%s'",
++                              virTristateSwitchTypeToString(def->xattr));
++        }
++
++        if (def->cache != VIR_DOMAIN_FS_CACHE_MODE_DEFAULT) {
++            virBufferAsprintf(&binaryBuf, "<cache mode='%s'/>\n",
++                              virDomainFSCacheModeTypeToString(def->cache));
++        }
++
++        if (def->posix_lock != VIR_TRISTATE_SWITCH_ABSENT) {
++            virBufferAsprintf(&lockAttrBuf, " posix='%s'",
++                              virTristateSwitchTypeToString(def->posix_lock));
++        }
++
++        if (def->flock != VIR_TRISTATE_SWITCH_ABSENT) {
++            virBufferAsprintf(&lockAttrBuf, " flock='%s'",
++                              virTristateSwitchTypeToString(def->flock));
++        }
++
++        virXMLFormatElement(&binaryBuf, "lock", &lockAttrBuf, NULL);
+     }
+ 
+     virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio);
+ 
+-    virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL);
++    virXMLFormatElement(buf, "driver", &driverAttrBuf, &driverBuf);
++    virXMLFormatElement(buf, "binary", &binaryAttrBuf, &binaryBuf);
+ 
+     switch (def->type) {
+     case VIR_DOMAIN_FS_TYPE_MOUNT:
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 921cc42a57..2a382ede72 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -802,6 +802,14 @@ typedef enum {
+     VIR_DOMAIN_FS_MODEL_LAST
+ } virDomainFSModel;
+ 
++typedef enum {
++    VIR_DOMAIN_FS_CACHE_MODE_DEFAULT = 0,
++    VIR_DOMAIN_FS_CACHE_MODE_NONE,
++    VIR_DOMAIN_FS_CACHE_MODE_ALWAYS,
++
++    VIR_DOMAIN_FS_CACHE_MODE_LAST
++} virDomainFSCacheMode;
++
+ struct _virDomainFSDef {
+     int type;
+     int fsdriver; /* enum virDomainFSDriverType */
+@@ -817,6 +825,12 @@ struct _virDomainFSDef {
+     unsigned long long space_hard_limit; /* in bytes */
+     unsigned long long space_soft_limit; /* in bytes */
+     bool symlinksResolved;
++    char *binary;
++    unsigned long long queue_size;
++    virTristateSwitch xattr;
++    virDomainFSCacheMode cache;
++    virTristateSwitch posix_lock;
++    virTristateSwitch flock;
+     virDomainVirtioOptionsPtr virtio;
+     virObjectPtr privateData;
+ };
+@@ -3437,6 +3451,7 @@ VIR_ENUM_DECL(virDomainFSDriver);
+ VIR_ENUM_DECL(virDomainFSAccessMode);
+ VIR_ENUM_DECL(virDomainFSWrpolicy);
+ VIR_ENUM_DECL(virDomainFSModel);
++VIR_ENUM_DECL(virDomainFSCacheMode);
+ VIR_ENUM_DECL(virDomainNet);
+ VIR_ENUM_DECL(virDomainNetBackend);
+ VIR_ENUM_DECL(virDomainNetVirtioTxMode);
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index bc2858fc00..5dc99e03cf 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -389,6 +389,7 @@ virDomainDiskSourceFormat;
+ virDomainDiskTranslateSourcePool;
+ virDomainFeatureTypeFromString;
+ virDomainFeatureTypeToString;
++virDomainFSCacheModeTypeToString;
+ virDomainFSDefFree;
+ virDomainFSDefNew;
+ virDomainFSDriverTypeToString;
+diff --git a/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml
+index a6b6279fb8..f6bb663e97 100644
+--- a/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml
++++ b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml
+@@ -27,7 +27,11 @@
+     <controller type='usb' index='0' model='none'/>
+     <controller type='pci' index='0' model='pci-root'/>
+     <filesystem type='mount' accessmode='passthrough'>
+-      <driver type='virtiofs'/>
++      <driver type='virtiofs' queue='1024'/>
++      <binary path='/usr/libexec/virtiofsd' xattr='on'>
++        <cache mode='always'/>
++        <lock posix='off' flock='off'/>
++      </binary>
+       <source dir='/path'/>
+       <target dir='mount_tag'/>
+       <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+diff --git a/tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml b/tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml
+index 70df7b890d..96b9774704 100644
+--- a/tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml
++++ b/tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml
+@@ -63,6 +63,7 @@
+     </controller>
+     <filesystem type='mount' accessmode='passthrough'>
+       <driver type='virtiofs'/>
++      <binary path='/usr/libexec/virtiofsd'/>
+       <source dir='/path'/>
+       <target dir='mount_tag'/>
+       <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-conf-backup-Allow-configuration-of-names-exported-via-NBD.patch b/SOURCES/libvirt-conf-backup-Allow-configuration-of-names-exported-via-NBD.patch
new file mode 100644
index 0000000..1f1335e
--- /dev/null
+++ b/SOURCES/libvirt-conf-backup-Allow-configuration-of-names-exported-via-NBD.patch
@@ -0,0 +1,146 @@
+From 100ae962cd0f4dbfd5270bc2d61f05ec1c524c0a Mon Sep 17 00:00:00 2001
+Message-Id: <100ae962cd0f4dbfd5270bc2d61f05ec1c524c0a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:40 +0100
+Subject: [PATCH] conf: backup: Allow configuration of names exported via NBD
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If users wish to use different name for exported disks or bitmaps
+the new fields allow to do so. Additionally they also document the
+current settings.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 12ccd8d4db12d71a270d903701a8edb83d41f127)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <8043f75d8d4b4ae7e7ae3671d71407f733e6a3cf.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatbackup.html.in                             |  9 +++++++++
+ docs/schemas/domainbackup.rng                         |  8 ++++++++
+ src/conf/backup_conf.c                                | 10 ++++++++++
+ src/conf/backup_conf.h                                |  2 ++
+ tests/domainbackupxml2xmlin/backup-pull-seclabel.xml  |  2 +-
+ tests/domainbackupxml2xmlout/backup-pull-seclabel.xml |  2 +-
+ 6 files changed, 31 insertions(+), 2 deletions(-)
+
+diff --git a/docs/formatbackup.html.in b/docs/formatbackup.html.in
+index 1c690901c7..543d913072 100644
+--- a/docs/formatbackup.html.in
++++ b/docs/formatbackup.html.in
+@@ -85,6 +85,15 @@
+               <dd>Setting this attribute to <code>yes</code>(default) specifies
+                 that the disk should take part in the backup and using
+                 <code>no</code> excludes the disk from the backup.</dd>
++              <dt><code>exportname</code></dt>
++              <dd>Allows modification of the NBD export name for the given disk.
++                By default equal to disk target.
++                Valid only for pull mode backups.</dd>
++              <dt><code>exportbitmap</code></dt>
++              <dd>Allows modification of the name of the bitmap describing dirty
++                blocks for an incremental backup exported via NBD export name
++                for the given disk.
++                Valid only for pull mode backups.</dd>
+               <dt><code>type</code></dt>
+               <dd>A mandatory attribute to describe the type of the
+                 disk, except when <code>backup='no'</code> is
+diff --git a/docs/schemas/domainbackup.rng b/docs/schemas/domainbackup.rng
+index c1e4d80302..395ea841f9 100644
+--- a/docs/schemas/domainbackup.rng
++++ b/docs/schemas/domainbackup.rng
+@@ -165,6 +165,14 @@
+             <attribute name='name'>
+               <ref name='diskTarget'/>
+             </attribute>
++            <optional>
++              <attribute name='exportname'>
++                <text/>
++              </attribute>
++              <attribute name='exportbitmap'>
++                <text/>
++              </attribute>
++            </optional>
+             <choice>
+               <group>
+                 <attribute name='backup'>
+diff --git a/src/conf/backup_conf.c b/src/conf/backup_conf.c
+index 61dc8cd4b2..b370b686f1 100644
+--- a/src/conf/backup_conf.c
++++ b/src/conf/backup_conf.c
+@@ -71,6 +71,8 @@ virDomainBackupDefFree(virDomainBackupDefPtr def)
+         virDomainBackupDiskDefPtr disk = def->disks + i;
+ 
+         g_free(disk->name);
++        g_free(disk->exportname);
++        g_free(disk->exportbitmap);
+         virObjectUnref(disk->store);
+     }
+ 
+@@ -124,6 +126,11 @@ virDomainBackupDiskDefParseXML(xmlNodePtr node,
+     if (def->backup == VIR_TRISTATE_BOOL_NO)
+         return 0;
+ 
++    if (!push) {
++        def->exportname = virXMLPropString(node, "exportname");
++        def->exportbitmap = virXMLPropString(node, "exportbitmap");
++    }
++
+     if (internal) {
+         if (!(state = virXMLPropString(node, "state")) ||
+             (tmp = virDomainBackupDiskStateTypeFromString(state)) < 0) {
+@@ -333,6 +340,9 @@ virDomainBackupDiskDefFormat(virBufferPtr buf,
+     if (disk->backup == VIR_TRISTATE_BOOL_YES) {
+         virBufferAsprintf(&attrBuf, " type='%s'", virStorageTypeToString(disk->store->type));
+ 
++        virBufferEscapeString(&attrBuf, " exportname='%s'", disk->exportname);
++        virBufferEscapeString(&attrBuf, " exportbitmap='%s'", disk->exportbitmap);
++
+         if (disk->store->format > 0)
+             virBufferEscapeString(&childBuf, "<driver type='%s'/>\n",
+                                   virStorageFileFormatTypeToString(disk->store->format));
+diff --git a/src/conf/backup_conf.h b/src/conf/backup_conf.h
+index 7cf44245d4..672fd52ee7 100644
+--- a/src/conf/backup_conf.h
++++ b/src/conf/backup_conf.h
+@@ -51,6 +51,8 @@ typedef virDomainBackupDiskDef *virDomainBackupDiskDefPtr;
+ struct _virDomainBackupDiskDef {
+     char *name;     /* name matching the <target dev='...' of the domain */
+     virTristateBool backup; /* whether backup is requested */
++    char *exportname; /* name of the NBD export for pull mode backup */
++    char *exportbitmap; /* name of the bitmap exposed in NBD for pull mode backup */
+ 
+     /* details of target for push-mode, or of the scratch file for pull-mode */
+     virStorageSourcePtr store;
+diff --git a/tests/domainbackupxml2xmlin/backup-pull-seclabel.xml b/tests/domainbackupxml2xmlin/backup-pull-seclabel.xml
+index a00d8758bb..4e6e602c19 100644
+--- a/tests/domainbackupxml2xmlin/backup-pull-seclabel.xml
++++ b/tests/domainbackupxml2xmlin/backup-pull-seclabel.xml
+@@ -2,7 +2,7 @@
+   <incremental>1525889631</incremental>
+   <server transport='tcp' name='localhost' port='10809'/>
+   <disks>
+-    <disk name='vda' type='file'>
++    <disk name='vda' type='file' exportname='test-vda' exportbitmap='blah'>
+       <driver type='qcow2'/>
+       <scratch file='/path/to/file'>
+         <seclabel model='dac' relabel='no'/>
+diff --git a/tests/domainbackupxml2xmlout/backup-pull-seclabel.xml b/tests/domainbackupxml2xmlout/backup-pull-seclabel.xml
+index c631c9b979..450f007d3a 100644
+--- a/tests/domainbackupxml2xmlout/backup-pull-seclabel.xml
++++ b/tests/domainbackupxml2xmlout/backup-pull-seclabel.xml
+@@ -2,7 +2,7 @@
+   <incremental>1525889631</incremental>
+   <server transport='tcp' name='localhost' port='10809'/>
+   <disks>
+-    <disk name='vda' backup='yes' type='file'>
++    <disk name='vda' backup='yes' type='file' exportname='test-vda' exportbitmap='blah'>
+       <driver type='qcow2'/>
+       <scratch file='/path/to/file'>
+         <seclabel model='dac' relabel='no'/>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-conf-do-not-generate-machine-names-ending-with-a-dash.patch b/SOURCES/libvirt-conf-do-not-generate-machine-names-ending-with-a-dash.patch
new file mode 100644
index 0000000..e67d233
--- /dev/null
+++ b/SOURCES/libvirt-conf-do-not-generate-machine-names-ending-with-a-dash.patch
@@ -0,0 +1,70 @@
+From f9fdeb29a61a98868d1a9f5284a85c57f826d6d1 Mon Sep 17 00:00:00 2001
+Message-Id: <f9fdeb29a61a98868d1a9f5284a85c57f826d6d1@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:08 +0100
+Subject: [PATCH] conf: do not generate machine names ending with a dash
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+As of systemd commit:
+
+commit d65652f1f21a4b0c59711320f34266c635393c89
+Author:     Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
+CommitDate: 2018-12-10 09:56:56 +0100
+
+    Partially unify hostname_is_valid() and dns_name_is_valid()
+
+Dashes are no longer allowed at the end of machine names.
+
+Trim the trailing dashes from the generated name before passing
+it to machined.
+
+Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1790409
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit 45464db8ba502764cf37ec9335770248bdb3d9a8)
+
+Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <ae17f80d69ee7772d32dd5c34c332be6b77e7afb.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 3 +++
+ tests/virsystemdtest.c | 4 ++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 77e3d25a2d..4b297c96bc 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -30708,6 +30708,9 @@ virDomainMachineNameAppendValid(virBufferPtr buf,
+ 
+         virBufferAddChar(buf, *name);
+     }
++
++    /* trailing dashes are not allowed */
++    virBufferTrimChars(buf, "-");
+ }
+ 
+ #undef HOSTNAME_CHARS
+diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
+index 9b95ca6789..26876850b8 100644
+--- a/tests/virsystemdtest.c
++++ b/tests/virsystemdtest.c
+@@ -740,6 +740,10 @@ mymain(void)
+                  "qemu-7-123456789012345678901234567890123456789012345678901234567");
+     TEST_MACHINE("123456789012345678901234567890123456789012345678901234567890", 8,
+                  "qemu-8-123456789012345678901234567890123456789012345678901234567");
++    TEST_MACHINE("kstest-network-device-default-httpks_(c9eed63e-981e-48ec-acdc-56b3f8c5f678)", 100,
++                 "qemu-100-kstest-network-device-default-httpksc9eed63e-981e-48ec");
++    TEST_MACHINE("kstest-network-device-default-httpks_(c9eed63e-981e-48ec--cdc-56b3f8c5f678)", 10,
++                 "qemu-10-kstest-network-device-default-httpksc9eed63e-981e-48ec");
+ 
+ # define TESTS_PM_SUPPORT_HELPER(name, function) \
+     do { \
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-conf-domain-Remove-checking-of-return-value-of-virHashCreateFull.patch b/SOURCES/libvirt-conf-domain-Remove-checking-of-return-value-of-virHashCreateFull.patch
new file mode 100644
index 0000000..fe8367a
--- /dev/null
+++ b/SOURCES/libvirt-conf-domain-Remove-checking-of-return-value-of-virHashCreateFull.patch
@@ -0,0 +1,73 @@
+From 04792aa0715be4e779fca81fa8f7e9f2c5c1b71f Mon Sep 17 00:00:00 2001
+Message-Id: <04792aa0715be4e779fca81fa8f7e9f2c5c1b71f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:00 +0100
+Subject: [PATCH] conf: domain: Remove checking of return value of
+ virHashCreateFull
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This module has last two direct checks whether the value returned by
+virHashCreateFull is NULL. Remove them so that static analyzers don't
+get the false idea that checking the value is necessary.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 2a5ea0a0c1843c7c43e673b3d2082cc3abdef602)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <2e310ad44b341511caba735608bc0bba4b072d6c.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_addr.c | 30 ++++++++++++------------------
+ 1 file changed, 12 insertions(+), 18 deletions(-)
+
+diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
+index 607ba56efd..f07b3d9725 100644
+--- a/src/conf/domain_addr.c
++++ b/src/conf/domain_addr.c
+@@ -1044,28 +1044,22 @@ virDomainPCIAddressSetExtensionAlloc(virDomainPCIAddressSetPtr addrs,
+         if (VIR_ALLOC(addrs->zpciIds) < 0)
+             return -1;
+ 
+-        if (!(addrs->zpciIds->uids = virHashCreateFull(10, NULL,
+-                                                       virZPCIAddrKeyCode,
+-                                                       virZPCIAddrKeyEqual,
+-                                                       virZPCIAddrKeyCopy,
+-                                                       virZPCIAddrKeyPrintHuman,
+-                                                       virZPCIAddrKeyFree)))
+-            goto error;
++        addrs->zpciIds->uids = virHashCreateFull(10, NULL,
++                                                 virZPCIAddrKeyCode,
++                                                 virZPCIAddrKeyEqual,
++                                                 virZPCIAddrKeyCopy,
++                                                 virZPCIAddrKeyPrintHuman,
++                                                 virZPCIAddrKeyFree);
+ 
+-        if (!(addrs->zpciIds->fids = virHashCreateFull(10, NULL,
+-                                                       virZPCIAddrKeyCode,
+-                                                       virZPCIAddrKeyEqual,
+-                                                       virZPCIAddrKeyCopy,
+-                                                       virZPCIAddrKeyPrintHuman,
+-                                                       virZPCIAddrKeyFree)))
+-            goto error;
++        addrs->zpciIds->fids = virHashCreateFull(10, NULL,
++                                                 virZPCIAddrKeyCode,
++                                                 virZPCIAddrKeyEqual,
++                                                 virZPCIAddrKeyCopy,
++                                                 virZPCIAddrKeyPrintHuman,
++                                                 virZPCIAddrKeyFree);
+     }
+ 
+     return 0;
+-
+- error:
+-    virDomainPCIAddressSetExtensionFree(addrs);
+-    return -1;
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-conf-parse-format-teaming-subelement-of-interface.patch b/SOURCES/libvirt-conf-parse-format-teaming-subelement-of-interface.patch
new file mode 100644
index 0000000..10aec7f
--- /dev/null
+++ b/SOURCES/libvirt-conf-parse-format-teaming-subelement-of-interface.patch
@@ -0,0 +1,468 @@
+From 653245c4de76aba4e75131da8d40eed5b15ffd0d Mon Sep 17 00:00:00 2001
+Message-Id: <653245c4de76aba4e75131da8d40eed5b15ffd0d@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Thu, 30 Jan 2020 14:12:40 -0500
+Subject: [PATCH] conf: parse/format <teaming> subelement of <interface>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The subelement <teaming> of <interface> devices is used to configure a
+simple teaming association between two interfaces in a domain. Example:
+
+  <interface type='bridge'>
+    <source bridge='br0'/>
+    <model type='virtio'/>
+    <mac address='00:11:22:33:44:55'/>
+    <alias name='ua-backup0'/>
+    <teaming type='persistent'/>
+  </interface>
+  <interface type='hostdev'>
+    <source>
+      <address type='pci' bus='0x02' slot='0x10' function='0x4'/>
+    </source>
+    <mac address='00:11:22:33:44:55'/>
+    <teaming type='transient' persistent='ua-backup0'/>
+  </interface>
+
+The interface with <teaming type='persistent'/> is assumed to always
+be present, while the interface with type='transient' may be be
+unplugged and later re-plugged; the persistent='blah' attribute (and
+in the one currently available implementation, also the matching MAC
+addresses) is what associates the two devices with each other. It is
+up to the hypervisor and the guest network drivers to determine what
+to do with this information.
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit fb0509d06ac57434c2edbd81ee63deb32a0e598a)
+
+https://bugzilla.redhat.com/1693587
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20200130191244.24174-3-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/schemas/domaincommon.rng                 | 19 ++++++
+ src/conf/domain_conf.c                        | 47 +++++++++++++
+ src/conf/domain_conf.h                        | 14 ++++
+ .../net-virtio-teaming-network.xml            | 37 +++++++++++
+ tests/qemuxml2argvdata/net-virtio-teaming.xml | 50 ++++++++++++++
+ .../net-virtio-teaming-network.xml            | 51 ++++++++++++++
+ .../qemuxml2xmloutdata/net-virtio-teaming.xml | 66 +++++++++++++++++++
+ tests/qemuxml2xmltest.c                       |  6 ++
+ 8 files changed, 290 insertions(+)
+ create mode 100644 tests/qemuxml2argvdata/net-virtio-teaming-network.xml
+ create mode 100644 tests/qemuxml2argvdata/net-virtio-teaming.xml
+ create mode 100644 tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml
+ create mode 100644 tests/qemuxml2xmloutdata/net-virtio-teaming.xml
+
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 76d94b156f..026e753567 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -3158,6 +3158,25 @@
+       <optional>
+         <ref name="vlan"/>
+       </optional>
++      <optional>
++        <element name="teaming">
++          <choice>
++            <group>
++              <attribute name="type">
++                <value>persistent</value>
++              </attribute>
++            </group>
++            <group>
++              <attribute name="type">
++                <value>transient</value>
++              </attribute>
++              <attribute name="persistent">
++                <ref name="aliasName"/>
++              </attribute>
++            </group>
++          </choice>
++        </element>
++      </optional>
+     </interleave>
+   </define>
+ 
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 0478914c69..58f72b3b0f 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -554,6 +554,13 @@ VIR_ENUM_IMPL(virDomainNetVirtioTxMode,
+               "timer",
+ );
+ 
++VIR_ENUM_IMPL(virDomainNetTeaming,
++              VIR_DOMAIN_NET_TEAMING_TYPE_LAST,
++              "none",
++              "persistent",
++              "transient",
++);
++
+ VIR_ENUM_IMPL(virDomainNetInterfaceLinkState,
+               VIR_DOMAIN_NET_INTERFACE_LINK_STATE_LAST,
+               "default",
+@@ -6276,6 +6283,21 @@ virDomainNetDefValidate(const virDomainNetDef *net)
+                        virDomainNetTypeToString(net->type));
+         return -1;
+     }
++
++    if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT) {
++        if (!net->teaming.persistent) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("teaming persistent attribute must be set if teaming type is 'transient'"));
++            return -1;
++        }
++    } else {
++        if (net->teaming.persistent) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                           _("teaming persistent attribute not allowed if teaming type is '%s'"),
++                           virDomainNetTeamingTypeToString(net->teaming.type));
++            return -1;
++        }
++    }
+     return 0;
+ }
+ 
+@@ -11574,6 +11596,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
+     g_autofree char *vhostuser_type = NULL;
+     g_autofree char *trustGuestRxFilters = NULL;
+     g_autofree char *vhost_path = NULL;
++    g_autofree char *teamingType = NULL;
++    g_autofree char *teamingPersistent = NULL;
+     const char *prefix = xmlopt ? xmlopt->config.netPrefix : NULL;
+ 
+     if (!(def = virDomainNetDefNew(xmlopt)))
+@@ -11775,6 +11799,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
+                 if (!vhost_path && (tmp = virXMLPropString(cur, "vhost")))
+                     vhost_path = virFileSanitizePath(tmp);
+                 VIR_FREE(tmp);
++            } else if (virXMLNodeNameEqual(cur, "teaming") &&
++                       !teamingType && !teamingPersistent) {
++                teamingType = virXMLPropString(cur, "type");
++                teamingPersistent =  virXMLPropString(cur, "persistent");
+             }
+         }
+         cur = cur->next;
+@@ -12296,6 +12324,19 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
+         }
+     }
+ 
++    if (teamingType) {
++        int tmpTeaming;
++
++        if ((tmpTeaming = virDomainNetTeamingTypeFromString(teamingType)) <= 0) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                           _("unknown teaming type '%s'"),
++                           teamingType);
++            goto error;
++        }
++        def->teaming.type = tmpTeaming;
++    }
++    def->teaming.persistent = g_steal_pointer(&teamingPersistent);
++
+     rv = virXPathULong("string(./tune/sndbuf)", ctxt, &def->tune.sndbuf);
+     if (rv >= 0) {
+         def->tune.sndbuf_specified = true;
+@@ -25741,6 +25782,12 @@ virDomainNetDefFormat(virBufferPtr buf,
+         virBufferAddLit(buf,   "</tune>\n");
+     }
+ 
++    if (def->teaming.type != VIR_DOMAIN_NET_TEAMING_TYPE_NONE) {
++        virBufferAsprintf(buf, "<teaming type='%s'",
++                          virDomainNetTeamingTypeToString(def->teaming.type));
++        virBufferEscapeString(buf, " persistent='%s'", def->teaming.persistent);
++        virBufferAddLit(buf, "/>\n");
++    }
+     if (def->linkstate) {
+         virBufferAsprintf(buf, "<link state='%s'/>\n",
+                           virDomainNetInterfaceLinkStateTypeToString(def->linkstate));
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index 6ae89fa498..ee8eb3ddc0 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -884,6 +884,15 @@ typedef enum {
+     VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST
+ } virDomainNetVirtioTxModeType;
+ 
++/* the type of teaming device */
++typedef enum {
++    VIR_DOMAIN_NET_TEAMING_TYPE_NONE,
++    VIR_DOMAIN_NET_TEAMING_TYPE_PERSISTENT,
++    VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT,
++
++    VIR_DOMAIN_NET_TEAMING_TYPE_LAST
++} virDomainNetTeamingType;
++
+ /* link interface states */
+ typedef enum {
+         VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT = 0, /* Default link state (up) */
+@@ -958,6 +967,10 @@ struct _virDomainNetDef {
+         char *tap;
+         char *vhost;
+     } backend;
++    struct {
++        virDomainNetTeamingType type;
++        char *persistent; /* alias name of persistent device */
++    } teaming;
+     union {
+         virDomainChrSourceDefPtr vhostuser;
+         struct {
+@@ -3425,6 +3438,7 @@ VIR_ENUM_DECL(virDomainFSModel);
+ VIR_ENUM_DECL(virDomainNet);
+ VIR_ENUM_DECL(virDomainNetBackend);
+ VIR_ENUM_DECL(virDomainNetVirtioTxMode);
++VIR_ENUM_DECL(virDomainNetTeaming);
+ VIR_ENUM_DECL(virDomainNetInterfaceLinkState);
+ VIR_ENUM_DECL(virDomainNetModel);
+ VIR_ENUM_DECL(virDomainChrDevice);
+diff --git a/tests/qemuxml2argvdata/net-virtio-teaming-network.xml b/tests/qemuxml2argvdata/net-virtio-teaming-network.xml
+new file mode 100644
+index 0000000000..edab52f3a1
+--- /dev/null
++++ b/tests/qemuxml2argvdata/net-virtio-teaming-network.xml
+@@ -0,0 +1,37 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219100</memory>
++  <currentMemory unit='KiB'>219100</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='i686' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <disk type='block' device='disk'>
++      <source dev='/dev/HostVG/QEMUGuest1'/>
++      <target dev='hda' bus='ide'/>
++    </disk>
++    <controller type='usb' index='0'/>
++    <interface type='network'>
++      <mac address='00:11:22:33:44:55'/>
++      <source network='mybridge'/>
++      <model type='virtio'/>
++      <teaming type='persistent'/>
++      <alias name='ua-backup0'/>
++    </interface>
++    <interface type='network'>
++      <mac address='00:11:22:33:44:55'/>
++      <source network='myhostdevpool'/>
++      <model type='virtio'/>
++      <teaming type='transient' persistent='ua-backup0'/>
++    </interface>
++    <memballoon model='virtio'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvdata/net-virtio-teaming.xml b/tests/qemuxml2argvdata/net-virtio-teaming.xml
+new file mode 100644
+index 0000000000..830ce28524
+--- /dev/null
++++ b/tests/qemuxml2argvdata/net-virtio-teaming.xml
+@@ -0,0 +1,50 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219100</memory>
++  <currentMemory unit='KiB'>219100</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='i686' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <disk type='block' device='disk'>
++      <source dev='/dev/HostVG/QEMUGuest1'/>
++      <target dev='hda' bus='ide'/>
++    </disk>
++    <controller type='usb' index='0'/>
++    <interface type='user'>
++      <mac address='00:11:22:33:44:55'/>
++      <model type='virtio'/>
++      <teaming type='persistent'/>
++      <alias name='ua-backup0'/>
++    </interface>
++    <interface type='user'>
++      <mac address='66:44:33:22:11:00'/>
++      <model type='virtio'/>
++      <teaming type='persistent'/>
++      <alias name='ua-backup1'/>
++    </interface>
++    <interface type='hostdev' managed='yes'>
++      <mac address='00:11:22:33:44:55'/>
++      <source>
++        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
++      </source>
++      <teaming type='transient' persistent='ua-backup0'/>
++    </interface>
++    <interface type='hostdev' managed='yes'>
++      <mac address='66:44:33:22:11:00'/>
++      <source>
++        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x2'/>
++      </source>
++      <teaming type='transient' persistent='ua-backup1'/>
++    </interface>
++    <memballoon model='virtio'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml b/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml
+new file mode 100644
+index 0000000000..e0dbeafe02
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml
+@@ -0,0 +1,51 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219100</memory>
++  <currentMemory unit='KiB'>219100</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='i686' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <disk type='block' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source dev='/dev/HostVG/QEMUGuest1'/>
++      <target dev='hda' bus='ide'/>
++      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
++    </disk>
++    <controller type='usb' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <controller type='ide' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
++    </controller>
++    <interface type='network'>
++      <mac address='00:11:22:33:44:55'/>
++      <source network='mybridge'/>
++      <model type='virtio'/>
++      <teaming type='persistent'/>
++      <alias name='ua-backup0'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </interface>
++    <interface type='network'>
++      <mac address='00:11:22:33:44:55'/>
++      <source network='myhostdevpool'/>
++      <model type='virtio'/>
++      <teaming type='transient' persistent='ua-backup0'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
++    </interface>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='virtio'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
++    </memballoon>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmloutdata/net-virtio-teaming.xml b/tests/qemuxml2xmloutdata/net-virtio-teaming.xml
+new file mode 100644
+index 0000000000..5a5695794a
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/net-virtio-teaming.xml
+@@ -0,0 +1,66 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219100</memory>
++  <currentMemory unit='KiB'>219100</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='i686' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <disk type='block' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source dev='/dev/HostVG/QEMUGuest1'/>
++      <target dev='hda' bus='ide'/>
++      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
++    </disk>
++    <controller type='usb' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <controller type='ide' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
++    </controller>
++    <interface type='user'>
++      <mac address='00:11:22:33:44:55'/>
++      <model type='virtio'/>
++      <teaming type='persistent'/>
++      <alias name='ua-backup0'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </interface>
++    <interface type='user'>
++      <mac address='66:44:33:22:11:00'/>
++      <model type='virtio'/>
++      <teaming type='persistent'/>
++      <alias name='ua-backup1'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
++    </interface>
++    <interface type='hostdev' managed='yes'>
++      <mac address='00:11:22:33:44:55'/>
++      <source>
++        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
++      </source>
++      <teaming type='transient' persistent='ua-backup0'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
++    </interface>
++    <interface type='hostdev' managed='yes'>
++      <mac address='66:44:33:22:11:00'/>
++      <source>
++        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x2'/>
++      </source>
++      <teaming type='transient' persistent='ua-backup1'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
++    </interface>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='virtio'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
++    </memballoon>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index 3cefc64833..e54c540ef6 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -451,6 +451,12 @@ mymain(void)
+     DO_TEST("net-eth-unmanaged-tap", NONE);
+     DO_TEST("net-virtio-network-portgroup", NONE);
+     DO_TEST("net-virtio-rxtxqueuesize", NONE);
++    DO_TEST("net-virtio-teaming",
++            QEMU_CAPS_VIRTIO_NET_FAILOVER,
++            QEMU_CAPS_DEVICE_VFIO_PCI);
++    DO_TEST("net-virtio-teaming-network",
++            QEMU_CAPS_VIRTIO_NET_FAILOVER,
++            QEMU_CAPS_DEVICE_VFIO_PCI);
+     DO_TEST("net-hostdev", NONE);
+     DO_TEST("net-hostdev-bootorder", NONE);
+     DO_TEST("net-hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-conf-qemu-add-virtiofs-fsdriver-type.patch b/SOURCES/libvirt-conf-qemu-add-virtiofs-fsdriver-type.patch
new file mode 100644
index 0000000..edad185
--- /dev/null
+++ b/SOURCES/libvirt-conf-qemu-add-virtiofs-fsdriver-type.patch
@@ -0,0 +1,327 @@
+From 2fce649fb569ab21c224f387456c996428f8a251 Mon Sep 17 00:00:00 2001
+Message-Id: <2fce649fb569ab21c224f387456c996428f8a251@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:41 +0100
+Subject: [PATCH] conf: qemu: add virtiofs fsdriver type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduce a new 'virtiofs' driver type for filesystem.
+
+<filesystem type='mount' accessmode='passthrough'>
+  <driver type='virtiofs'/>
+  <source dir='/path'/>
+  <target dir='mount_tag'>
+  <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+</filesystem>
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit ecc6ad6b90ad674a903c95d2a637f8b1b5833be2)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <abe26807f06ed14b2be3cbd098461afc307e88e3.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ docs/formatdomain.html.in                     | 12 ++-
+ docs/schemas/domaincommon.rng                 |  6 ++
+ src/conf/domain_conf.c                        |  1 +
+ src/conf/domain_conf.h                        |  1 +
+ src/qemu/qemu_command.c                       |  4 +
+ src/qemu/qemu_domain.c                        |  4 +
+ src/qemu/qemu_domain_address.c                |  4 +
+ .../vhost-user-fs-fd-memory.xml               | 39 ++++++++++
+ .../vhost-user-fs-hugepages.xml               | 74 +++++++++++++++++++
+ .../vhost-user-fs-fd-memory.x86_64-latest.xml |  1 +
+ .../vhost-user-fs-hugepages.x86_64-latest.xml |  1 +
+ tests/qemuxml2xmltest.c                       |  3 +
+ 12 files changed, 149 insertions(+), 1 deletion(-)
+ create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml
+ create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml
+ create mode 120000 tests/qemuxml2xmloutdata/vhost-user-fs-fd-memory.x86_64-latest.xml
+ create mode 120000 tests/qemuxml2xmloutdata/vhost-user-fs-hugepages.x86_64-latest.xml
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 50914a5207..337ab01316 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -3935,6 +3935,11 @@
+     &lt;target dir='/import/from/host'/&gt;
+     &lt;readonly/&gt;
+   &lt;/filesystem&gt;
++  &lt;filesystem type='mount' accessmode='passthrough'&gt;
++      &lt;driver type='virtiofs'/&gt;
++      &lt;source dir='/path'/&gt;
++      &lt;target dir='mount_tag'/&gt;
++  &lt;/filesystem&gt;
+   ...
+ &lt;/devices&gt;
+ ...</pre>
+@@ -3963,6 +3968,9 @@
+         while the value <code>immediate</code> means that a host writeback
+         is immediately triggered for all pages touched during a guest file
+         write operation <span class="since">(since 0.9.10)</span>.
++        <span class="since">Since 6.2.0</span>, <code>type='virtiofs'</code>
++        is also supported. Using virtiofs requires setting up shared memory,
++        see the guide: <a href="kbase/virtiofs.html">Virtio-FS</a>
+         </dd>
+         <dt><code>template</code></dt>
+         <dd>
+@@ -3998,7 +4006,9 @@
+       The filesystem element has an optional attribute <code>accessmode</code>
+       which specifies the security mode for accessing the source
+       <span class="since">(since 0.8.5)</span>. Currently this only works
+-      with <code>type='mount'</code> for the QEMU/KVM driver. The possible
++      with <code>type='mount'</code> for the QEMU/KVM driver.
++      For driver type <code>virtiofs</code>, only <code>passthrough</code> is
++      supported. For other driver types, the possible
+       values are:
+ 
+         <dl>
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index bfd8786ea8..5a9291b443 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -2645,6 +2645,12 @@
+           </optional>
+           <ref name='virtioOptions'/>
+         </group>
++        <group>
++          <attribute name="type">
++            <value>virtiofs</value>
++          </attribute>
++          <ref name='virtioOptions'/>
++        </group>
+         <empty/>
+       </choice>
+     </element>
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 990c5bcc1e..31d4828802 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -476,6 +476,7 @@ VIR_ENUM_IMPL(virDomainFSDriver,
+               "loop",
+               "nbd",
+               "ploop",
++              "virtiofs",
+ );
+ 
+ VIR_ENUM_IMPL(virDomainFSAccessMode,
+diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
+index ef2c1b80f7..921cc42a57 100644
+--- a/src/conf/domain_conf.h
++++ b/src/conf/domain_conf.h
+@@ -771,6 +771,7 @@ typedef enum {
+     VIR_DOMAIN_FS_DRIVER_TYPE_LOOP,
+     VIR_DOMAIN_FS_DRIVER_TYPE_NBD,
+     VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP,
++    VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS,
+ 
+     VIR_DOMAIN_FS_DRIVER_TYPE_LAST
+ } virDomainFSDriverType;
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 252809a8d7..7fdf58f067 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -2695,6 +2695,10 @@ qemuBuildFilesystemCommandLine(virCommandPtr cmd,
+                 return -1;
+             break;
+ 
++        case VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS:
++            /* TODO: vhost-user-fs-pci */
++            break;
++
+         case VIR_DOMAIN_FS_DRIVER_TYPE_LOOP:
+         case VIR_DOMAIN_FS_DRIVER_TYPE_NBD:
+         case VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP:
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index ed35260712..402b079b09 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -8361,6 +8361,10 @@ qemuDomainDeviceDefValidateFS(virDomainFSDefPtr fs,
+                        _("Filesystem driver type not supported"));
+         return -1;
+ 
++    case VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS:
++        /* TODO: vhost-user-fs-pci */
++        return 0;
++
+     case VIR_DOMAIN_FS_DRIVER_TYPE_LAST:
+     default:
+         virReportEnumRangeError(virDomainFSDriverType, fs->fsdriver);
+diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
+index 9e3bcc434d..3c6ac62ff5 100644
+--- a/src/qemu/qemu_domain_address.c
++++ b/src/qemu/qemu_domain_address.c
+@@ -690,6 +690,10 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
+             }
+             break;
+ 
++        case VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS:
++            /* vhost-user-fs-pci */
++            return virtioFlags;
++
+         case VIR_DOMAIN_FS_DRIVER_TYPE_LOOP:
+         case VIR_DOMAIN_FS_DRIVER_TYPE_NBD:
+         case VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP:
+diff --git a/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml
+new file mode 100644
+index 0000000000..a6b6279fb8
+--- /dev/null
++++ b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.xml
+@@ -0,0 +1,39 @@
++<domain type='kvm'>
++  <name>guest</name>
++  <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid>
++  <memory unit='KiB'>14680064</memory>
++  <currentMemory unit='KiB'>14680064</currentMemory>
++  <memoryBacking>
++    <source type='file'/>
++    <access mode='shared'/>
++  </memoryBacking>
++  <vcpu placement='static'>2</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <cpu mode='custom' match='exact' check='none'>
++    <model fallback='forbid'>qemu64</model>
++    <numa>
++      <cell id='0' cpus='0-1' memory='14680064' unit='KiB' memAccess='shared'/>
++    </numa>
++  </cpu>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <controller type='usb' index='0' model='none'/>
++    <controller type='pci' index='0' model='pci-root'/>
++    <filesystem type='mount' accessmode='passthrough'>
++      <driver type='virtiofs'/>
++      <source dir='/path'/>
++      <target dir='mount_tag'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
++    </filesystem>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml b/tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml
+new file mode 100644
+index 0000000000..70df7b890d
+--- /dev/null
++++ b/tests/qemuxml2argvdata/vhost-user-fs-hugepages.xml
+@@ -0,0 +1,74 @@
++<domain type='qemu'>
++  <name>guest</name>
++  <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid>
++  <memory unit='KiB'>4194304</memory>
++  <currentMemory unit='KiB'>4194304</currentMemory>
++  <memoryBacking>
++    <hugepages>
++      <page size='2048' unit='KiB'/>
++    </hugepages>
++    <access mode='shared'/>
++  </memoryBacking>
++  <vcpu placement='static'>2</vcpu>
++  <os>
++    <type arch='x86_64' machine='q35'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <features>
++    <acpi/>
++    <apic/>
++  </features>
++  <cpu mode='custom' match='exact' check='none'>
++    <model fallback='forbid'>qemu64</model>
++    <numa>
++      <cell id='0' cpus='0-1' memory='2097152' unit='KiB' memAccess='shared'/>
++    </numa>
++  </cpu>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <disk type='file' device='disk'>
++      <driver name='qemu' type='qcow2'/>
++      <source file='/var/lib/libvirt/images/guest.qcow2'/>
++      <target dev='vda' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
++    </disk>
++    <controller type='usb' index='0' model='none'/>
++    <controller type='sata' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pcie-root'/>
++    <controller type='pci' index='1' model='pcie-root-port'>
++      <model name='pcie-root-port'/>
++      <target chassis='1' port='0x8'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
++    </controller>
++    <controller type='pci' index='2' model='pcie-root-port'>
++      <model name='pcie-root-port'/>
++      <target chassis='2' port='0x9'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
++    </controller>
++    <controller type='pci' index='3' model='pcie-root-port'>
++      <model name='pcie-root-port'/>
++      <target chassis='3' port='0xa'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='4' model='pcie-root-port'>
++      <model name='pcie-root-port'/>
++      <target chassis='4' port='0xb'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/>
++    </controller>
++    <filesystem type='mount' accessmode='passthrough'>
++      <driver type='virtiofs'/>
++      <source dir='/path'/>
++      <target dir='mount_tag'/>
++      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
++    </filesystem>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmloutdata/vhost-user-fs-fd-memory.x86_64-latest.xml b/tests/qemuxml2xmloutdata/vhost-user-fs-fd-memory.x86_64-latest.xml
+new file mode 120000
+index 0000000000..fbc552ef94
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/vhost-user-fs-fd-memory.x86_64-latest.xml
+@@ -0,0 +1 @@
++../qemuxml2argvdata/vhost-user-fs-fd-memory.xml
+\ No newline at end of file
+diff --git a/tests/qemuxml2xmloutdata/vhost-user-fs-hugepages.x86_64-latest.xml b/tests/qemuxml2xmloutdata/vhost-user-fs-hugepages.x86_64-latest.xml
+new file mode 120000
+index 0000000000..0c0f05b254
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/vhost-user-fs-hugepages.x86_64-latest.xml
+@@ -0,0 +1 @@
++../qemuxml2argvdata/vhost-user-fs-hugepages.xml
+\ No newline at end of file
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index d58259587b..f77f59fa3c 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -1428,6 +1428,9 @@ mymain(void)
+     DO_TEST("vhost-vsock-ccw-auto", QEMU_CAPS_DEVICE_VHOST_VSOCK,
+             QEMU_CAPS_CCW);
+ 
++    DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory");
++    DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages");
++
+     DO_TEST("riscv64-virt",
+             QEMU_CAPS_DEVICE_VIRTIO_MMIO);
+     DO_TEST("riscv64-virt-pci",
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-conf-remove-unused-virCapabilitiesSetHostCPU-method.patch b/SOURCES/libvirt-conf-remove-unused-virCapabilitiesSetHostCPU-method.patch
new file mode 100644
index 0000000..c2f8d2f
--- /dev/null
+++ b/SOURCES/libvirt-conf-remove-unused-virCapabilitiesSetHostCPU-method.patch
@@ -0,0 +1,88 @@
+From 6ece5388a7fb7fc3c703cd1bc9e214ad411451d8 Mon Sep 17 00:00:00 2001
+Message-Id: <6ece5388a7fb7fc3c703cd1bc9e214ad411451d8@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 3 Feb 2020 18:07:23 +0000
+Subject: [PATCH] conf: remove unused virCapabilitiesSetHostCPU method
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 2ce9474c2a6ba3df4977068dcee35d3fa5468749)
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785207
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785211
+Message-Id: <20200203180726.2203691-3-berrange@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/capabilities.c  | 21 ---------------------
+ src/conf/capabilities.h  |  6 ------
+ src/libvirt_private.syms |  1 -
+ 3 files changed, 28 deletions(-)
+
+diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
+index 9a39858280..bf1d9936ed 100644
+--- a/src/conf/capabilities.c
++++ b/src/conf/capabilities.c
+@@ -368,27 +368,6 @@ virCapabilitiesHostNUMAAddCell(virCapsHostNUMAPtr caps,
+     g_ptr_array_add(caps->cells, cell);
+ }
+ 
+-
+-/**
+- * virCapabilitiesSetHostCPU:
+- * @caps: capabilities to extend
+- * @cpu: CPU definition
+- *
+- * Sets host CPU specification
+- */
+-int
+-virCapabilitiesSetHostCPU(virCapsPtr caps,
+-                          virCPUDefPtr cpu)
+-{
+-    if (cpu == NULL)
+-        return -1;
+-
+-    caps->host.cpu = cpu;
+-
+-    return 0;
+-}
+-
+-
+ /**
+  * virCapabilitiesAllocMachines:
+  * @machines: machine variants for emulator ('pc', or 'isapc', etc)
+diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
+index f604e7b95e..4a49e94aa5 100644
+--- a/src/conf/capabilities.h
++++ b/src/conf/capabilities.h
+@@ -258,12 +258,6 @@ virCapabilitiesHostNUMAAddCell(virCapsHostNUMAPtr caps,
+                                int npageinfo,
+                                virCapsHostNUMACellPageInfoPtr pageinfo);
+ 
+-
+-int
+-virCapabilitiesSetHostCPU(virCapsPtr caps,
+-                          virCPUDefPtr cpu);
+-
+-
+ virCapsGuestMachinePtr *
+ virCapabilitiesAllocMachines(const char *const *names,
+                              int nnames);
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index b97906b852..afa7d4fcae 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -77,7 +77,6 @@ virCapabilitiesHostSecModelAddBaseLabel;
+ virCapabilitiesInitCaches;
+ virCapabilitiesInitPages;
+ virCapabilitiesNew;
+-virCapabilitiesSetHostCPU;
+ virCapabilitiesSetNetPrefix;
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-conf-rename-namespace-property-of-struct-_virStorageSourceNVMeDef.patch b/SOURCES/libvirt-conf-rename-namespace-property-of-struct-_virStorageSourceNVMeDef.patch
new file mode 100644
index 0000000..dce9fb3
--- /dev/null
+++ b/SOURCES/libvirt-conf-rename-namespace-property-of-struct-_virStorageSourceNVMeDef.patch
@@ -0,0 +1,144 @@
+From 9b070e02e7b5bb95728a1fcdc8b7dfaaacc5f30a Mon Sep 17 00:00:00 2001
+Message-Id: <9b070e02e7b5bb95728a1fcdc8b7dfaaacc5f30a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:25:55 +0100
+Subject: [PATCH] conf: rename 'namespace' property of struct
+ _virStorageSourceNVMeDef
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+While 'namespace' is not a reserved word in C, it is in C++. Our
+compilers are happy with it but syntax-hilighting in some editors
+hilights is as a keyword. Rename it to prevent confusion.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 5793b8baa75747860f6ba97470969047e60c8579)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <bfe6cf10a95868ae56a91f362a1ea50667754027.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c    | 12 ++++++------
+ src/qemu/qemu_block.c     |  2 +-
+ src/util/virhostdev.c     |  2 +-
+ src/util/virstoragefile.c |  4 ++--
+ src/util/virstoragefile.h |  2 +-
+ 5 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 8aec85e83c..1e8518139c 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -6054,7 +6054,7 @@ virDomainDiskDefValidate(const virDomainDef *def,
+ 
+     if (disk->src->type == VIR_STORAGE_TYPE_NVME) {
+         /* NVMe namespaces start from 1 */
+-        if (disk->src->nvme->namespace == 0) {
++        if (disk->src->nvme->namespc == 0) {
+             virReportError(VIR_ERR_XML_ERROR, "%s",
+                            _("NVMe namespace can't be zero"));
+             return -1;
+@@ -9433,7 +9433,7 @@ virDomainDiskSourceNVMeParse(xmlNodePtr node,
+ {
+     g_autoptr(virStorageSourceNVMeDef) nvme = NULL;
+     g_autofree char *type = NULL;
+-    g_autofree char *namespace = NULL;
++    g_autofree char *namespc = NULL;
+     g_autofree char *managed = NULL;
+     xmlNodePtr address;
+ 
+@@ -9452,16 +9452,16 @@ virDomainDiskSourceNVMeParse(xmlNodePtr node,
+         return -1;
+     }
+ 
+-    if (!(namespace = virXMLPropString(node, "namespace"))) {
++    if (!(namespc = virXMLPropString(node, "namespace"))) {
+         virReportError(VIR_ERR_XML_ERROR, "%s",
+                        _("missing 'namespace' attribute to disk source"));
+         return -1;
+     }
+ 
+-    if (virStrToLong_ull(namespace, NULL, 10, &nvme->namespace) < 0) {
++    if (virStrToLong_ull(namespc, NULL, 10, &nvme->namespc) < 0) {
+         virReportError(VIR_ERR_XML_ERROR,
+                        _("malformed namespace '%s'"),
+-                       namespace);
++                       namespc);
+         return -1;
+     }
+ 
+@@ -24444,7 +24444,7 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf,
+     virBufferAddLit(attrBuf, " type='pci'");
+     virBufferAsprintf(attrBuf, " managed='%s'",
+                       virTristateBoolTypeToString(nvme->managed));
+-    virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespace);
++    virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespc);
+     virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false);
+ }
+ 
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 73cb5ba4bc..5697d4fc73 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1008,7 +1008,7 @@ qemuBlockStorageSourceGetNVMeProps(virStorageSourcePtr src)
+     ignore_value(virJSONValueObjectCreate(&ret,
+                                           "s:driver", "nvme",
+                                           "s:device", pciAddr,
+-                                          "U:namespace", nvme->namespace,
++                                          "U:namespace", nvme->namespc,
+                                           NULL));
+     return ret;
+ }
+diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
+index 9b4ea30216..9596482146 100644
+--- a/src/util/virhostdev.c
++++ b/src/util/virhostdev.c
+@@ -2256,7 +2256,7 @@ virHostdevGetNVMeDeviceList(virNVMeDeviceListPtr nvmeDevices,
+             continue;
+ 
+         if (!(dev = virNVMeDeviceNew(&srcNVMe->pciAddr,
+-                                     srcNVMe->namespace,
++                                     srcNVMe->namespc,
+                                      srcNVMe->managed)))
+             return -1;
+ 
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index fa37840532..2e54620139 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2052,7 +2052,7 @@ virStorageSourceNVMeDefCopy(const virStorageSourceNVMeDef *src)
+ 
+     ret = g_new0(virStorageSourceNVMeDef, 1);
+ 
+-    ret->namespace = src->namespace;
++    ret->namespc = src->namespc;
+     ret->managed = src->managed;
+     virPCIDeviceAddressCopy(&ret->pciAddr, &src->pciAddr);
+     return ret;
+@@ -2069,7 +2069,7 @@ virStorageSourceNVMeDefIsEqual(const virStorageSourceNVMeDef *a,
+     if (!a || !b)
+         return false;
+ 
+-    if (a->namespace != b->namespace ||
++    if (a->namespc != b->namespc ||
+         a->managed != b->managed ||
+         !virPCIDeviceAddressEqual(&a->pciAddr, &b->pciAddr))
+         return false;
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index c1430cadd1..0230f44652 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -246,7 +246,7 @@ struct _virStorageSourceInitiatorDef {
+ typedef struct _virStorageSourceNVMeDef virStorageSourceNVMeDef;
+ typedef virStorageSourceNVMeDef *virStorageSourceNVMeDefPtr;
+ struct _virStorageSourceNVMeDef {
+-    unsigned long long namespace;
++    unsigned long long namespc;
+     int managed; /* enum virTristateBool */
+     virPCIDeviceAddress pciAddr;
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-conf-use-virXMLFormatElement-in-virDomainFSDefFormat.patch b/SOURCES/libvirt-conf-use-virXMLFormatElement-in-virDomainFSDefFormat.patch
new file mode 100644
index 0000000..3e5d5df
--- /dev/null
+++ b/SOURCES/libvirt-conf-use-virXMLFormatElement-in-virDomainFSDefFormat.patch
@@ -0,0 +1,70 @@
+From d77f180068dab8747f5e2c098a9c59213ce19108 Mon Sep 17 00:00:00 2001
+Message-Id: <d77f180068dab8747f5e2c098a9c59213ce19108@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:29 +0100
+Subject: [PATCH] conf: use virXMLFormatElement in virDomainFSDefFormat
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use the virXMLFormatElement helper to format the driver element
+to simplify adding further sub-elements.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 3efdbae5bf054d1a2bdc98fdccff0273abe54c88)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <966ad0eebcb1ae5f20f59fc6cc84008bbfa6426f.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/conf/domain_conf.c | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 8a5f14d6cb..88117187c8 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -24991,7 +24991,7 @@ virDomainFSDefFormat(virBufferPtr buf,
+     const char *fsdriver = virDomainFSDriverTypeToString(def->fsdriver);
+     const char *wrpolicy = virDomainFSWrpolicyTypeToString(def->wrpolicy);
+     const char *src = def->src->path;
+-    g_auto(virBuffer) driverBuf = VIR_BUFFER_INITIALIZER;
++    g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
+ 
+     if (!type) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+@@ -25016,25 +25016,21 @@ virDomainFSDefFormat(virBufferPtr buf,
+ 
+     virBufferAdjustIndent(buf, 2);
+     if (def->fsdriver) {
+-        virBufferAsprintf(&driverBuf, " type='%s'", fsdriver);
++        virBufferAsprintf(&driverAttrBuf, " type='%s'", fsdriver);
+ 
+         if (def->format)
+-            virBufferAsprintf(&driverBuf, " format='%s'",
++            virBufferAsprintf(&driverAttrBuf, " format='%s'",
+                               virStorageFileFormatTypeToString(def->format));
+ 
+         /* Don't generate anything if wrpolicy is set to default */
+         if (def->wrpolicy)
+-            virBufferAsprintf(&driverBuf, " wrpolicy='%s'", wrpolicy);
++            virBufferAsprintf(&driverAttrBuf, " wrpolicy='%s'", wrpolicy);
+ 
+     }
+ 
+-    virDomainVirtioOptionsFormat(&driverBuf, def->virtio);
++    virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio);
+ 
+-    if (virBufferUse(&driverBuf)) {
+-        virBufferAddLit(buf, "<driver");
+-        virBufferAddBuffer(buf, &driverBuf);
+-        virBufferAddLit(buf, "/>\n");
+-    }
++    virXMLFormatElement(buf, "driver", &driverAttrBuf, NULL);
+ 
+     switch (def->type) {
+     case VIR_DOMAIN_FS_TYPE_MOUNT:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-cpu.c-Check-properly-for-virCapabilitiesGetNodeInfo-retval.patch b/SOURCES/libvirt-cpu.c-Check-properly-for-virCapabilitiesGetNodeInfo-retval.patch
new file mode 100644
index 0000000..df7e1a6
--- /dev/null
+++ b/SOURCES/libvirt-cpu.c-Check-properly-for-virCapabilitiesGetNodeInfo-retval.patch
@@ -0,0 +1,41 @@
+From 4b8dbdb81eb6a755dc58b359e65b769ee1dc3f86 Mon Sep 17 00:00:00 2001
+Message-Id: <4b8dbdb81eb6a755dc58b359e65b769ee1dc3f86@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 24 Jan 2020 15:05:49 +0100
+Subject: [PATCH] cpu.c: Check properly for virCapabilitiesGetNodeInfo() retval
+
+The virCapabilitiesGetNodeInfo() function has the usual return
+value semantics for integeres: a negative value means an error,
+zero or a positive value means success. However, the function
+call done in virCPUProbeHost() doesn't check for the return value
+accordingly.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 609acf1f5d5d666148355719346c8ee05f911e33)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1794691
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <033f07f79bc9fa26f669c83f9aa790bfaef25b93.1579874719.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu/cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
+index a2ae5b8c07..d99466472b 100644
+--- a/src/cpu/cpu.c
++++ b/src/cpu/cpu.c
+@@ -455,7 +455,7 @@ virCPUProbeHost(virArch arch)
+ {
+     virNodeInfo nodeinfo;
+ 
+-    if (virCapabilitiesGetNodeInfo(&nodeinfo))
++    if (virCapabilitiesGetNodeInfo(&nodeinfo) < 0)
+         return NULL;
+ 
+     return virCPUGetHost(arch, VIR_CPU_TYPE_HOST, &nodeinfo, NULL);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-cpu_conf-Format-vendor_id-for-host-model-CPUs.patch b/SOURCES/libvirt-cpu_conf-Format-vendor_id-for-host-model-CPUs.patch
new file mode 100644
index 0000000..e088020
--- /dev/null
+++ b/SOURCES/libvirt-cpu_conf-Format-vendor_id-for-host-model-CPUs.patch
@@ -0,0 +1,80 @@
+From 37b27a297ecb87e65f41c212aaabde7311b042d6 Mon Sep 17 00:00:00 2001
+Message-Id: <37b27a297ecb87e65f41c212aaabde7311b042d6@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 20 Feb 2020 09:08:05 +0100
+Subject: [PATCH] cpu_conf: Format vendor_id for host-model CPUs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In commit v5.9.0-400-gaf8e39921a I removed printing model's fallback and
+vendor_id attributes when no model is specified. However, vendor_id
+makes sense even without a specific CPU model (for host-model CPUs).
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804549
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 0905f222f1bfd9d741e94a8d653e05bb174846d3)
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <0b46ae9e26d1c7dbaa7f2dd58fd1156db237a853.1582186015.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/cpu_conf.c                                | 14 +++++++++-----
+ tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml |  4 +++-
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
+index 837d77581c..1a2948ce11 100644
+--- a/src/conf/cpu_conf.c
++++ b/src/conf/cpu_conf.c
+@@ -791,10 +791,10 @@ virCPUDefFormatBuf(virBufferPtr buf,
+         return -1;
+     }
+ 
+-    if (formatModel && def->model) {
++    if (formatModel && (def->model || def->vendor_id)) {
+         virBufferAddLit(buf, "<model");
+ 
+-        if (def->type == VIR_CPU_TYPE_GUEST) {
++        if (def->type == VIR_CPU_TYPE_GUEST && def->model) {
+             const char *fallback;
+ 
+             fallback = virCPUFallbackTypeToString(def->fallback);
+@@ -805,11 +805,15 @@ virCPUDefFormatBuf(virBufferPtr buf,
+                 return -1;
+             }
+             virBufferAsprintf(buf, " fallback='%s'", fallback);
+-            if (def->vendor_id)
+-                virBufferEscapeString(buf, " vendor_id='%s'", def->vendor_id);
+         }
+ 
+-        virBufferEscapeString(buf, ">%s</model>\n", def->model);
++        if (def->type == VIR_CPU_TYPE_GUEST)
++            virBufferEscapeString(buf, " vendor_id='%s'", def->vendor_id);
++
++        if (def->model)
++            virBufferEscapeString(buf, ">%s</model>\n", def->model);
++        else
++            virBufferAddLit(buf, "/>\n");
+     }
+ 
+     if (formatModel && def->vendor)
+diff --git a/tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml b/tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml
+index d2447ccd10..2a7d0246cc 100644
+--- a/tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml
++++ b/tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml
+@@ -8,7 +8,9 @@
+     <type arch='x86_64' machine='pc'>hvm</type>
+     <boot dev='network'/>
+   </os>
+-  <cpu mode='host-model' check='partial'/>
++  <cpu mode='host-model' check='partial'>
++    <model vendor_id='Libvirt QEMU'/>
++  </cpu>
+   <clock offset='utc'/>
+   <on_poweroff>destroy</on_poweroff>
+   <on_reboot>restart</on_reboot>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-docs-Document-the-new-slices-sub-element-of-disk-s-source.patch b/SOURCES/libvirt-docs-Document-the-new-slices-sub-element-of-disk-s-source.patch
new file mode 100644
index 0000000..349ee96
--- /dev/null
+++ b/SOURCES/libvirt-docs-Document-the-new-slices-sub-element-of-disk-s-source.patch
@@ -0,0 +1,100 @@
+From 0f126297ca984aa2ef145e2a703fff3dc31c53db Mon Sep 17 00:00:00 2001
+Message-Id: <0f126297ca984aa2ef145e2a703fff3dc31c53db@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:19 +0100
+Subject: [PATCH] docs: Document the new <slices> sub-element of disk's
+ <source>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We are going to add support for specifying offset and size attributes
+which will allow controling where the image and where the guest data
+itself starts in the source of the disk. This will be represented by
+a <slices> element filled with either a <slice type='storage'> for the
+offset of the image format data.
+
+Add the XML documentation and RNG schema.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 44f0f76890c6b53a893ffc370836794d74317c34)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <9f5488f2e0e5b6d7df386fa428f7779346cbcff4.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in     | 13 +++++++++++++
+ docs/schemas/domaincommon.rng | 19 +++++++++++++++++++
+ 2 files changed, 32 insertions(+)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index ec48ed77a5..5dbb8b59cf 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -2878,6 +2878,9 @@
+   &lt;disk type='block' device='lun'&gt;
+     &lt;driver name='qemu' type='raw'/&gt;
+     &lt;source dev='/dev/sda'&gt;
++      &lt;slices&gt;
++        &lt;slice type='storage' offset='12345' size='123'/&gt;
++      &lt;/slices&gt;
+       &lt;reservations managed='no'&gt;
+         &lt;source type='unix' path='/path/to/qemu-pr-helper' mode='client'/&gt;
+       &lt;/reservations&gt;
+@@ -3360,6 +3363,16 @@
+             controller.
+             <span class="since">Since 6.0.0</span>
+           </dd>
++          <dt><code>slices</code></dt>
++          <dd>The <code>slices</code> element using its <code>slice</code>
++            sub-elements allows configuring offset and size of either the
++            location of the image format (<code>slice type='storage'</code>)
++            inside the storage source or the guest data inside the image format
++            container (future expansion).
++
++            The <code>offset</code> and <code>size</code> values are in bytes.
++            <span class="since">Since 6.1.0</span>
++          </dd>
+         </dl>
+ 
+         <p>
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 19476a2735..38aef19e89 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1596,12 +1596,31 @@
+     </optional>
+   </define>
+ 
++  <define name="diskSourceSlice">
++    <attribute name='offset'>
++      <ref name="positiveInteger"/>
++    </attribute>
++    <attribute name='size'>
++      <ref name="positiveInteger"/>
++    </attribute>
++  </define>
++
+   <define name="diskSourceCommon">
+     <optional>
+       <attribute name="index">
+         <ref name="positiveInteger"/>
+       </attribute>
+     </optional>
++    <optional>
++      <element name='slices'>
++        <element name='slice'>
++          <attribute name='type'>
++            <value>storage</value>
++          </attribute>
++          <ref name="diskSourceSlice"/>
++        </element>
++      </element>
++    </optional>
+   </define>
+ 
+   <define name="diskSource">
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-docs-List-the-armvtimer-timer-among-all-others.patch b/SOURCES/libvirt-docs-List-the-armvtimer-timer-among-all-others.patch
new file mode 100644
index 0000000..e55ca95
--- /dev/null
+++ b/SOURCES/libvirt-docs-List-the-armvtimer-timer-among-all-others.patch
@@ -0,0 +1,42 @@
+From 5cef3caf8b82a15405eb7d08c96c346451cab7f7 Mon Sep 17 00:00:00 2001
+Message-Id: <5cef3caf8b82a15405eb7d08c96c346451cab7f7@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 14:50:34 +0100
+Subject: [PATCH] docs: List the armvtimer timer among all others
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 1d742a8772848a72667e1e5e0fa0841abf0af647)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214135034.719753-1-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 98a811bd09..2b6a3fb921 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -2466,9 +2466,9 @@
+             "platform" (currently unsupported),
+             "hpet" (libxl, xen, qemu), "kvmclock" (qemu),
+             "pit" (qemu), "rtc" (qemu), "tsc" (libxl, qemu -
+-            <span class="since">since 3.2.0</span>)
+-            or "hypervclock"
+-            (qemu - <span class="since">since 1.2.2</span>).
++            <span class="since">since 3.2.0</span>), "hypervclock"
++            (qemu - <span class="since">since 1.2.2</span>) or
++            "armvtimer" (qemu - <span class="since">since 6.1.0</span>).
+ 
+             The <code>hypervclock</code> timer adds support for the
+             reference time counter and the reference page for iTSC
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-docs-add-virtiofs-kbase.patch b/SOURCES/libvirt-docs-add-virtiofs-kbase.patch
new file mode 100644
index 0000000..99e20ba
--- /dev/null
+++ b/SOURCES/libvirt-docs-add-virtiofs-kbase.patch
@@ -0,0 +1,198 @@
+From ee1081b3b87179b5b9ed6a1d14694962fa04a5fd Mon Sep 17 00:00:00 2001
+Message-Id: <ee1081b3b87179b5b9ed6a1d14694962fa04a5fd@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:40 +0100
+Subject: [PATCH] docs: add virtiofs kbase
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a document describing the usage of virtiofs.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit aecf1f5d702ad710aed99a688f38f05cc304b03a)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+
+Conflicts: * downstream is missing the link to qemu-passthrough-security
+  docs/kbase.html.in
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <a037a8c8db2e3be9a54467859b700a9d7ab15429.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ docs/kbase.html.in      |   3 +
+ docs/kbase/virtiofs.rst | 147 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 150 insertions(+)
+ create mode 100644 docs/kbase/virtiofs.rst
+
+diff --git a/docs/kbase.html.in b/docs/kbase.html.in
+index c156414c41..7d6caf3cb1 100644
+--- a/docs/kbase.html.in
++++ b/docs/kbase.html.in
+@@ -29,6 +29,9 @@
+         <dt><a href="kbase/backing_chains.html">Backing chain management</a></dt>
+         <dd>Explanation of how disk backing chain specification impacts libvirt's
+           behaviour and basic troubleshooting steps of disk problems.</dd>
++
++        <dt><a href="kbase/virtiofs.html">Virtio-FS</a></dt>
++        <dd>Share a filesystem between the guest and the host</dd>
+       </dl>
+     </div>
+ 
+diff --git a/docs/kbase/virtiofs.rst b/docs/kbase/virtiofs.rst
+new file mode 100644
+index 0000000000..68fbafcf37
+--- /dev/null
++++ b/docs/kbase/virtiofs.rst
+@@ -0,0 +1,147 @@
++============================
++Sharing files with Virtio-FS
++============================
++
++.. contents::
++
++=========
++Virtio-FS
++=========
++
++Virtio-FS is a shared file system that lets virtual machines access
++a directory tree on the host. Unlike existing approaches, it
++is designed to offer local file system semantics and performance.
++
++See https://virtio-fs.gitlab.io/
++
++==========
++Host setup
++==========
++
++The host-side virtiofsd daemon, like other vhost-user backed devices,
++requires shared memory between the host and the guest. As of QEMU 4.2, this
++requires specifying a NUMA topology for the guest and explicitly specifying
++a memory backend. Multiple options are available:
++
++Either of the following:
++
++* Use file-backed memory
++
++  Configure the directory where the files backing the memory will be stored
++  with the ``memory_backing_dir`` option in ``/etc/libvirt/qemu.conf``
++
++  ::
++
++    # This directory is used for memoryBacking source if configured as file.
++    # NOTE: big files will be stored here
++    memory_backing_dir = "/dev/shm/"
++
++* Use hugepage-backed memory
++
++  Make sure there are enough huge pages allocated for the requested guest memory.
++  For example, for one guest with 2 GiB of RAM backed by 2 MiB hugepages:
++
++  ::
++
++      # virsh allocpages 2M 1024
++
++===========
++Guest setup
++===========
++
++#. Specify the NUMA topology
++
++   in the domain XML of the guest.
++   For the simplest one-node topology for a guest with 2GiB of RAM and 8 vCPUs:
++
++   ::
++
++      <domain>
++        ...
++        <cpu ...>
++          <numa>
++            <cell id='0' cpus='0-7' memory='2' unit='GiB' memAccess='shared'/>
++          </numa>
++        </cpu>
++       ...
++      </domain>
++
++   Note that the CPU element might already be specified and only one is allowed.
++
++#. Specify the memory backend
++
++   Either of the following:
++
++   * File-backed memory
++
++     ::
++
++        <domain>
++          ...
++          <memoryBacking>
++            <access mode='shared'/>
++          </memoryBacking>
++          ...
++        </domain>
++
++     This will create a file in the directory specified in ``qemu.conf``
++
++   * Hugepage-backed memory
++
++     ::
++
++        <domain>
++          ...
++          <memoryBacking>
++            <hugepages>
++              <page size='2' unit='M'/>
++            </hugepages>
++            <access mode='shared'/>
++          </memoryBacking>
++          ...
++        </domain>
++
++#. Add the ``vhost-user-fs`` QEMU device via the ``filesystem`` element
++
++   ::
++
++      <domain>
++        ...
++        <devices>
++          ...
++          <filesystem type='mount' accessmode='passthrough'>
++            <driver type='virtiofs'/>
++            <source dir='/path'/>
++            <target dir='mount_tag'/>
++          </filesystem>
++          ...
++        </devices>
++      </domain>
++
++   Note that despite its name, the ``target dir`` is actually a mount tag and does
++   not have to correspond to the desired mount point in the guest.
++
++   So far, ``passthrough`` is the only supported access mode and it requires
++   running the ``virtiofsd`` daemon as root.
++
++#. Boot the guest and mount the filesystem
++
++   ::
++
++      guest# mount -t virtiofs mount_tag /mnt/mount/path
++
++   Note: this requires virtiofs support in the guest kernel (Linux v5.4 or later)
++
++===================
++Optional parameters
++===================
++
++More optional elements can be specified
++
++::
++
++  <driver type='virtiofs' queue='1024'/>
++  <binary path='/usr/libexec/virtiofsd' xattr='on'>
++    <cache mode='always'/>
++    <lock posix_lock='on' flock='on'/>
++  </binary>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-docs-document-interface-subelement-teaming.patch b/SOURCES/libvirt-docs-document-interface-subelement-teaming.patch
new file mode 100644
index 0000000..9271d56
--- /dev/null
+++ b/SOURCES/libvirt-docs-document-interface-subelement-teaming.patch
@@ -0,0 +1,180 @@
+From a7ad591f6a6b86b24b1ed030cc9b1ca5b3bf4346 Mon Sep 17 00:00:00 2001
+Message-Id: <a7ad591f6a6b86b24b1ed030cc9b1ca5b3bf4346@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Thu, 30 Jan 2020 14:12:44 -0500
+Subject: [PATCH] docs: document <interface> subelement <teaming>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit f0f34056ab26eaa9f903a51cd1fa155088fd640f)
+
+Conflicts:
+   docs/news.xml - feature is in release 6.1.0 upstream, but
+      that release doesn't exist downstream.
+
+https://bugzilla.redhat.com/1693587
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20200130191244.24174-7-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/formatdomain.html.in | 101 ++++++++++++++++++++++++++++++++++++++
+ docs/news.xml             |  28 +++++++++++
+ 2 files changed, 129 insertions(+)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 4db9c292b7..98a811bd09 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -5873,6 +5873,107 @@
+ &lt;/devices&gt;
+ ...</pre>
+ 
++    <h5><a id="elementsTeaming">Teaming a virtio/hostdev NIC pair</a></h5>
++
++    <p>
++      <span class="since">Since 6.1.0 (QEMU and KVM only, requires
++        QEMU 4.2.0 or newer axnd a guest virtio-net driver supporting
++        the "failover" feature, such as the one included in Linux
++        kernel 4.18 and newer)
++      </span>
++      The <code>&lt;teaming&gt;</code> element of two interfaces can
++      be used to connect them as a team/bond device in the guest
++      (assuming proper support in the hypervisor and the guest
++      network driver).
++    </p>
++
++<pre>
++...
++&lt;devices&gt;
++  &lt;interface type='network'&gt;
++    &lt;source network='mybridge'/&gt;
++    &lt;mac address='00:11:22:33:44:55'/&gt;
++    &lt;model type='virtio'/&gt;
++    &lt;teaming type='persistent'/&gt;
++    &lt;alias name='ua-backup0'/&gt;
++  &lt;/interface&gt;
++  &lt;interface type='network'&gt;
++    &lt;source network='hostdev-pool'/&gt;
++    &lt;mac address='00:11:22:33:44:55'/&gt;
++    &lt;model type='virtio'/&gt;
++    &lt;teaming type='transient' persistent='ua-backup0'/&gt;
++  &lt;/interface&gt;
++&lt;/devices&gt;
++...</pre>
++
++    <p>
++      The <code>&lt;teaming&gt;</code> element required
++      attribute <code>type</code> will be set to
++      either <code>"persistent"</code> to indicate a device that
++      should always be present in the domain,
++      or <code>"transient"</code> to indicate a device that may
++      periodically be removed, then later re-added to the domain. When
++      type="transient", there should be a second attribute
++      to <code>&lt;teaming&gt;</code> called <code>"persistent"</code>
++      - this attribute should be set to the alias name of the other
++      device in the pair (the one that has <code>&lt;teaming
++      type="persistent'/&gt;</code>).
++    </p>
++    <p>
++      In the particular case of QEMU,
++      libvirt's <code>&lt;teaming&gt;</code> element is used to setup
++      a virtio-net "failover" device pair. For this setup, the
++      persistent device must be an interface with <code>&lt;model
++      type="virtio"/&gt;</code>, and the transient device must
++      be <code>&lt;interface type='hostdev'/&gt;</code>
++      (or <code>&lt;interface type='network'/&gt;</code> where the
++      referenced network defines a pool of SRIOV VFs). The guest will
++      then have a simple network team/bond device made of the virtio
++      NIC + hostdev NIC pair. In this configuration, the
++      higher-performing hostdev NIC will normally be preferred for all
++      network traffic, but when the domain is migrated, QEMU will
++      automatically unplug the VF from the guest, and then hotplug a
++      similar device once migration is completed; while migration is
++      taking place, network traffic will use the virtio NIC. (Of
++      course the emulated virtio NIC and the hostdev NIC must be
++      connected to the same subnet for bonding to work properly).
++    </p>
++    <p>
++      NB1: Since you must know the alias name of the virtio NIC when
++      configuring the hostdev NIC, it will need to be manually set in
++      the virtio NIC's configuration (as with all other manually set
++      alias names, this means it must start with "ua-").
++    </p>
++    <p>
++      NB2: Currently the only implementation of the guest OS
++      virtio-net driver supporting virtio-net failover requires that
++      the MAC addresses of the virtio and hostdev NIC must
++      match. Since that may not always be a requirement in the future,
++      libvirt doesn't enforce this limitation - it is up to the
++      person/management application that is creating the configuration
++      to assure the MAC addresses of the two devices match.
++    </p>
++    <p>
++      NB3: Since the PCI addresses of the SRIOV VFs on the hosts that
++      are the source and destination of the migration will almost
++      certainly be different, either higher level management software
++      will need to modify the <code>&lt;source&gt;</code> of the
++      hostdev NIC (<code>&lt;interface type='hostdev'&gt;</code>) at
++      the start of migration, or (a simpler solution) the
++      configuration will need to use a libvirt "hostdev" virtual
++      network that maintains a pool of such devices, as is implied in
++      the example's use of the libvirt network named "hostdev-pool" -
++      as long as the hostdev network pools on both hosts have the same
++      name, libvirt itself will take care of allocating an appropriate
++      device on both ends of the migration. Similarly the XML for the
++      virtio interface must also either work correctly unmodified on
++      both the source and destination of the migration (e.g. by
++      connecting to the same bridge device on both hosts, or by using
++      the same virtual network), or the management software must
++      properly modify the interface XML during migration so that the
++      virtio device remains connected to the same network segment
++      before and after migration.
++    </p>
+ 
+     <h5><a id="elementsNICSMulticast">Multicast tunnel</a></h5>
+ 
+diff --git a/docs/news.xml b/docs/news.xml
+index 731f010297..408ffc8518 100644
+--- a/docs/news.xml
++++ b/docs/news.xml
+@@ -65,6 +65,34 @@
+       </change>
+     </section>
+     <section title="New features">
++      <change>
++        <summary>
++          support for virtio+hostdev NIC &lt;teaming&gt;
++        </summary>
++        <description>
++          QEMU 4.2.0 and later, combined with a sufficiently recent
++          guest virtio-net driver (e.g. the driver included in Linux
++          kernel 4.18 and later), supports setting up a simple network
++          bond device comprised of one virtio emulated NIC and one
++          hostdev NIC (which must be an SRIOV VF). (in QEMU, this is
++          known as the "virtio failover" feature). The allure of this
++          setup is that the bond will always favor the hostdev device,
++          providing better performance, until the guest is migrated -
++          at that time QEMU will automatically unplug the hostdev NIC
++          and the bond will send all traffic via the virtio NIC until
++          migration is completed, then QEMU on the destination side
++          will hotplug a new hostdev NIC and the bond will switch back
++          to using the hostdev for network traffic. The result is that
++          guests desiring the extra performance of a hostdev NIC are
++          now migratable without network downtime (performance is just
++          degraded during migration) and without requiring a
++          complicated bonding configuration in the guest OS network
++          config and complicated unplug/replug logic in the management
++          application on the host - it can instead all be accomplished
++          in libvirt with the interface &lt;teaming&gt; subelement
++          "type" and "persistent" attributes.
++        </description>
++      </change>
+       <change>
+         <summary>
+           new PCI hostdev address type: unassigned
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-docs-domaincaps-Mention-VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA.patch b/SOURCES/libvirt-docs-domaincaps-Mention-VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA.patch
new file mode 100644
index 0000000..d98867b
--- /dev/null
+++ b/SOURCES/libvirt-docs-domaincaps-Mention-VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA.patch
@@ -0,0 +1,43 @@
+From 6a852bbf144600e756877ae98736e214a8e8d0cb Mon Sep 17 00:00:00 2001
+Message-Id: <6a852bbf144600e756877ae98736e214a8e8d0cb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:28 +0100
+Subject: [PATCH] docs: domaincaps: Mention
+ VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The flag for the virDomainUndefine API is supported even if we report
+that <backup supported='no'/>. Mention it in the docs.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit 7d7e7e2c197782ce06525b0a63cd43e452c3a711)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <bfb56ef76cee8e5e3698df9d7deceb93e5c83b97.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomaincaps.html.in | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
+index 6bf7a1c17a..2ac8632c69 100644
+--- a/docs/formatdomaincaps.html.in
++++ b/docs/formatdomaincaps.html.in
+@@ -565,7 +565,10 @@
+ 
+     <p>Reports whether the hypervisor supports the backup, checkpoint, and
+     related features. (<code>virDomainBackupBegin</code>,
+-    <code>virDomainCheckpointCreateXML</code> etc).
++    <code>virDomainCheckpointCreateXML</code> etc). The presence of the
++    <code>backup</code> element even if <code>supported='no'</code> implies that
++    the <code>VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA</code> flag for
++    <code>virDomainUndefine</code> is supported.
+     </p>
+ 
+     <h4><a id="elementsSEV">SEV capabilities</a></h4>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-docs-fix-a-typo.patch b/SOURCES/libvirt-docs-fix-a-typo.patch
new file mode 100644
index 0000000..9394ba7
--- /dev/null
+++ b/SOURCES/libvirt-docs-fix-a-typo.patch
@@ -0,0 +1,38 @@
+From afd2a8af9d8cb356dcff17791371f4794be368d2 Mon Sep 17 00:00:00 2001
+Message-Id: <afd2a8af9d8cb356dcff17791371f4794be368d2@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 21 Feb 2020 14:32:10 +0100
+Subject: [PATCH] docs: fix a typo
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+s/axnd/and/
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Fixes: f0f34056ab26eaa9f903a51cd1fa155088fd640f
+(cherry picked from commit 5b63cb5abff09882feda8e333285259aecc8e9e8)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1805742
+Message-Id: <f5919e9de65a7f593862ddcf1fc50b6f0b7e5bc0.1582291906.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/formatdomain.html.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 5dbb8b59cf..50914a5207 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -5891,7 +5891,7 @@
+ 
+     <p>
+       <span class="since">Since 6.1.0 (QEMU and KVM only, requires
+-        QEMU 4.2.0 or newer axnd a guest virtio-net driver supporting
++        QEMU 4.2.0 or newer and a guest virtio-net driver supporting
+         the "failover" feature, such as the one included in Linux
+         kernel 4.18 and newer)
+       </span>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-docs-formatdomain-Close-source-on-one-of-disk-examples.patch b/SOURCES/libvirt-docs-formatdomain-Close-source-on-one-of-disk-examples.patch
new file mode 100644
index 0000000..8fb7ca2
--- /dev/null
+++ b/SOURCES/libvirt-docs-formatdomain-Close-source-on-one-of-disk-examples.patch
@@ -0,0 +1,35 @@
+From 1a2f74b8b9e507b17d49a3060d29910facba9d89 Mon Sep 17 00:00:00 2001
+Message-Id: <1a2f74b8b9e507b17d49a3060d29910facba9d89@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:13 +0100
+Subject: [PATCH] docs: formatdomain: Close <source> on one of disk examples
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4e93c47576e4c9c37b34fc50707bee97e66d6a19)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <8da0026666677c92084e46f242a48e5248a226e6.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 2b6a3fb921..ec48ed77a5 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -2881,6 +2881,7 @@
+       &lt;reservations managed='no'&gt;
+         &lt;source type='unix' path='/path/to/qemu-pr-helper' mode='client'/&gt;
+       &lt;/reservations&gt;
++    &lt;/source&gt;
+     &lt;target dev='sda' bus='scsi'/&gt;
+     &lt;address type='drive' controller='0' bus='0' target='3' unit='0'/&gt;
+   &lt;/disk&gt;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-docs-formatdomain-Mention-missing-protocols.patch b/SOURCES/libvirt-docs-formatdomain-Mention-missing-protocols.patch
new file mode 100644
index 0000000..57b6daa
--- /dev/null
+++ b/SOURCES/libvirt-docs-formatdomain-Mention-missing-protocols.patch
@@ -0,0 +1,45 @@
+From d03688c61e7609b22770f5fa6228431edfc45945 Mon Sep 17 00:00:00 2001
+Message-Id: <d03688c61e7609b22770f5fa6228431edfc45945@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:43 +0200
+Subject: [PATCH] docs: formatdomain: Mention missing protocols
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+http, https, ftp, ftps, and tftp were not mentioned in the
+documentation. Note that 'ssh' is still omitted as it's used only
+internally.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit b24281c93405d6e3efb6edb3e7abff31628966b8)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <ed3aac8a1ddcf415808dc9104ce7638344c09523.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/formatdomain.html.in | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 2b8f9eabc2..143db21d4d 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -3086,10 +3086,11 @@
+               <dd>
+               The <code>protocol</code> attribute specifies the protocol to
+               access to the requested image. Possible values are "nbd",
+-              "iscsi", "rbd", "sheepdog", "gluster" or "vxhs".
++              "iscsi", "rbd", "sheepdog", "gluster", "vxhs", "http", "https",
++              "ftp", ftps", or "tftp".
+ 
+-              <p>If the <code>protocol</code> attribute is "rbd", "sheepdog",
+-              "gluster", or "vxhs", an additional attribute <code>name</code>
++              <p>For any <code>protocol</code> other than <code>nbd</code>
++              an additional attribute <code>name</code>
+               is mandatory to specify which volume/image will be used.
+               </p>
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-docs-reduce-excessive-spacing-in-ToC-for-RST-files.patch b/SOURCES/libvirt-docs-reduce-excessive-spacing-in-ToC-for-RST-files.patch
new file mode 100644
index 0000000..3f17419
--- /dev/null
+++ b/SOURCES/libvirt-docs-reduce-excessive-spacing-in-ToC-for-RST-files.patch
@@ -0,0 +1,39 @@
+From f62a2308cc4b92842363d1cc714c101983374857 Mon Sep 17 00:00:00 2001
+Message-Id: <f62a2308cc4b92842363d1cc714c101983374857@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:33 +0100
+Subject: [PATCH] docs: reduce excessive spacing in ToC for RST files
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The table of contents in the RST based files uses <p> tags inside the
+<li>, which results in 1em's worth of spacing above & below each
+entry. This results in way too much whitespace in the ToC.
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4be5a2f0c2c6f1236828592d8cb9ca5dc6f9df10)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <7d1090688b1ea9a76e46416d461784318b5cb8d4.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ docs/libvirt.css | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/docs/libvirt.css b/docs/libvirt.css
+index 2fe123395c..18e55dac59 100644
+--- a/docs/libvirt.css
++++ b/docs/libvirt.css
+@@ -579,3 +579,7 @@ ul.news-section-content li dl dd {
+     font-family: monospace;
+     background: #eeeeee;
+ }
++
++.contents li p {
++    margin: 2px;
++}
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-docs-render-class-literal-with-monospace-font.patch b/SOURCES/libvirt-docs-render-class-literal-with-monospace-font.patch
new file mode 100644
index 0000000..912fc93
--- /dev/null
+++ b/SOURCES/libvirt-docs-render-class-literal-with-monospace-font.patch
@@ -0,0 +1,41 @@
+From 20fafe768fcaa5aef96d5d77e1209f46e48228e0 Mon Sep 17 00:00:00 2001
+Message-Id: <20fafe768fcaa5aef96d5d77e1209f46e48228e0@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:32 +0100
+Subject: [PATCH] docs: render class="literal" with monospace font
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When using ``....`` in RST, this results in <span class="literal">...</span>
+instead of <code>...</code>. We thus need an extra rule to render it
+with a monospace font. Colouring a light gray also helps the text
+stand out a little more and matches background of <pre> blocks.
+
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 039787c71a2bee6e60ddf5cb0515c0cdb85dd20b)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <72f7f14e62e058c436303fdeed68986f435b9011.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ docs/libvirt.css | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/docs/libvirt.css b/docs/libvirt.css
+index d2e1842b62..2fe123395c 100644
+--- a/docs/libvirt.css
++++ b/docs/libvirt.css
+@@ -574,3 +574,8 @@ ul.news-section-content li dl dd {
+     margin-top: 0.5em;
+     margin-bottom: 0.5em;
+ }
++
++.literal, code {
++    font-family: monospace;
++    background: #eeeeee;
++}
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-hostcpu-add-support-for-reporting-die_id-in-NUMA-topology.patch b/SOURCES/libvirt-hostcpu-add-support-for-reporting-die_id-in-NUMA-topology.patch
new file mode 100644
index 0000000..2866b6b
--- /dev/null
+++ b/SOURCES/libvirt-hostcpu-add-support-for-reporting-die_id-in-NUMA-topology.patch
@@ -0,0 +1,519 @@
+From 15b2ac591a1c024ecf92a7e40d22eed6e59684b8 Mon Sep 17 00:00:00 2001
+Message-Id: <15b2ac591a1c024ecf92a7e40d22eed6e59684b8@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 3 Feb 2020 18:07:25 +0000
+Subject: [PATCH] hostcpu: add support for reporting die_id in NUMA topology
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Update the host CPU code to report the die_id in the NUMA topology
+capabilities. On systems with multiple dies, this fixes the bug
+where CPU cores can't be distinguished:
+
+ <cpus num='12'>
+   <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
+   <cpu id='1' socket_id='0' core_id='1' siblings='1'/>
+   <cpu id='2' socket_id='0' core_id='0' siblings='2'/>
+   <cpu id='3' socket_id='0' core_id='1' siblings='3'/>
+ </cpus>
+
+Notice how core_id is repeated within the scope of the same socket_id.
+
+It now reports
+
+ <cpus num='12'>
+   <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
+   <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
+   <cpu id='2' socket_id='0' die_id='1' core_id='0' siblings='2'/>
+   <cpu id='3' socket_id='0' die_id='1' core_id='1' siblings='3'/>
+ </cpus>
+
+So core_id is now unique within a (socket_id, die_id) pair.
+
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 7b79ee2f78bbf2af76df2f6466919e19ae05aeeb)
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785211
+Message-Id: <20200203180726.2203691-5-berrange@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/schemas/capability.rng                   |  3 ++
+ src/conf/capabilities.c                       |  5 ++-
+ src/conf/capabilities.h                       |  1 +
+ src/libvirt_linux.syms                        |  1 +
+ src/util/virhostcpu.c                         | 16 ++++++++++
+ src/util/virhostcpu.h                         |  1 +
+ .../vircaps2xmldata/vircaps-aarch64-basic.xml | 32 +++++++++----------
+ .../vircaps2xmldata/vircaps-x86_64-basic.xml  | 32 +++++++++----------
+ .../vircaps2xmldata/vircaps-x86_64-caches.xml | 16 +++++-----
+ .../vircaps-x86_64-resctrl-cdp.xml            | 24 +++++++-------
+ .../vircaps-x86_64-resctrl-cmt.xml            | 24 +++++++-------
+ .../vircaps-x86_64-resctrl-fake-feature.xml   | 24 +++++++-------
+ .../vircaps-x86_64-resctrl-skx-twocaches.xml  |  2 +-
+ .../vircaps-x86_64-resctrl-skx.xml            |  2 +-
+ .../vircaps-x86_64-resctrl.xml                | 24 +++++++-------
+ 15 files changed, 116 insertions(+), 91 deletions(-)
+
+diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng
+index 91ee523116..031c55bf20 100644
+--- a/docs/schemas/capability.rng
++++ b/docs/schemas/capability.rng
+@@ -265,6 +265,9 @@
+         <attribute name='socket_id'>
+           <ref name='unsignedInt'/>
+         </attribute>
++        <attribute name='die_id'>
++          <ref name='unsignedInt'/>
++        </attribute>
+         <attribute name='core_id'>
+           <ref name='unsignedInt'/>
+         </attribute>
+diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
+index bf1d9936ed..4bbc79334e 100644
+--- a/src/conf/capabilities.c
++++ b/src/conf/capabilities.c
+@@ -874,8 +874,9 @@ virCapabilitiesHostNUMAFormat(virCapsHostNUMAPtr caps,
+                     return -1;
+ 
+                 virBufferAsprintf(buf,
+-                                  " socket_id='%d' core_id='%d' siblings='%s'",
++                                  " socket_id='%d' die_id='%d' core_id='%d' siblings='%s'",
+                                   cell->cpus[j].socket_id,
++                                  cell->cpus[j].die_id,
+                                   cell->cpus[j].core_id,
+                                   siblings);
+                 VIR_FREE(siblings);
+@@ -1463,6 +1464,7 @@ virCapabilitiesFillCPUInfo(int cpu_id G_GNUC_UNUSED,
+     cpu->id = cpu_id;
+ 
+     if (virHostCPUGetSocket(cpu_id, &cpu->socket_id) < 0 ||
++        virHostCPUGetDie(cpu_id, &cpu->die_id) < 0 ||
+         virHostCPUGetCore(cpu_id, &cpu->core_id) < 0)
+         return -1;
+ 
+@@ -1591,6 +1593,7 @@ virCapabilitiesHostNUMAInitFake(virCapsHostNUMAPtr caps)
+                         goto error;
+                     if (tmp) {
+                         cpus[cid].id = id;
++                        cpus[cid].die_id = 0;
+                         cpus[cid].socket_id = s;
+                         cpus[cid].core_id = c;
+                         if (!(cpus[cid].siblings = virBitmapNew(ncpus)))
+diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
+index 4a49e94aa5..75f29666c9 100644
+--- a/src/conf/capabilities.h
++++ b/src/conf/capabilities.h
+@@ -88,6 +88,7 @@ struct _virCapsGuest {
+ struct _virCapsHostNUMACellCPU {
+     unsigned int id;
+     unsigned int socket_id;
++    unsigned int die_id;
+     unsigned int core_id;
+     virBitmapPtr siblings;
+ };
+diff --git a/src/libvirt_linux.syms b/src/libvirt_linux.syms
+index 5fa2c790ef..55649ae39c 100644
+--- a/src/libvirt_linux.syms
++++ b/src/libvirt_linux.syms
+@@ -4,6 +4,7 @@
+ 
+ # util/virhostcpu.h
+ virHostCPUGetCore;
++virHostCPUGetDie;
+ virHostCPUGetInfoPopulateLinux;
+ virHostCPUGetSiblingsList;
+ virHostCPUGetSocket;
+diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
+index 256976cce1..09c959cd25 100644
+--- a/src/util/virhostcpu.c
++++ b/src/util/virhostcpu.c
+@@ -218,6 +218,22 @@ virHostCPUGetSocket(unsigned int cpu, unsigned int *socket)
+     return 0;
+ }
+ 
++int
++virHostCPUGetDie(unsigned int cpu, unsigned int *die)
++{
++    int ret = virFileReadValueUint(die,
++                                   "%s/cpu/cpu%u/topology/die_id",
++                                   SYSFS_SYSTEM_PATH, cpu);
++
++    /* If the file is not there, it's 0 */
++    if (ret == -2)
++        *die = 0;
++    else if (ret < 0)
++        return -1;
++
++    return 0;
++}
++
+ int
+ virHostCPUGetCore(unsigned int cpu, unsigned int *core)
+ {
+diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
+index d95d380d4a..9be2e51a38 100644
+--- a/src/util/virhostcpu.h
++++ b/src/util/virhostcpu.h
+@@ -65,6 +65,7 @@ int virHostCPUStatsAssign(virNodeCPUStatsPtr param,
+ 
+ #ifdef __linux__
+ int virHostCPUGetSocket(unsigned int cpu, unsigned int *socket);
++int virHostCPUGetDie(unsigned int cpu, unsigned int *die);
+ int virHostCPUGetCore(unsigned int cpu, unsigned int *core);
+ 
+ virBitmapPtr virHostCPUGetSiblingsList(unsigned int cpu);
+diff --git a/tests/vircaps2xmldata/vircaps-aarch64-basic.xml b/tests/vircaps2xmldata/vircaps-aarch64-basic.xml
+index 50466f9162..0a04052c40 100644
+--- a/tests/vircaps2xmldata/vircaps-aarch64-basic.xml
++++ b/tests/vircaps2xmldata/vircaps-aarch64-basic.xml
+@@ -16,10 +16,10 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='4'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
+-            <cpu id='1' socket_id='0' core_id='1' siblings='1'/>
+-            <cpu id='2' socket_id='0' core_id='2' siblings='2'/>
+-            <cpu id='3' socket_id='0' core_id='3' siblings='3'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
++            <cpu id='2' socket_id='0' die_id='0' core_id='2' siblings='2'/>
++            <cpu id='3' socket_id='0' die_id='0' core_id='3' siblings='3'/>
+           </cpus>
+         </cell>
+         <cell id='1'>
+@@ -28,10 +28,10 @@
+           <pages unit='KiB' size='2048'>6144</pages>
+           <pages unit='KiB' size='1048576'>8192</pages>
+           <cpus num='4'>
+-            <cpu id='4' socket_id='1' core_id='4' siblings='4'/>
+-            <cpu id='5' socket_id='1' core_id='5' siblings='5'/>
+-            <cpu id='6' socket_id='1' core_id='6' siblings='6'/>
+-            <cpu id='7' socket_id='1' core_id='7' siblings='7'/>
++            <cpu id='4' socket_id='1' die_id='0' core_id='4' siblings='4'/>
++            <cpu id='5' socket_id='1' die_id='0' core_id='5' siblings='5'/>
++            <cpu id='6' socket_id='1' die_id='0' core_id='6' siblings='6'/>
++            <cpu id='7' socket_id='1' die_id='0' core_id='7' siblings='7'/>
+           </cpus>
+         </cell>
+         <cell id='2'>
+@@ -40,10 +40,10 @@
+           <pages unit='KiB' size='2048'>8192</pages>
+           <pages unit='KiB' size='1048576'>10240</pages>
+           <cpus num='4'>
+-            <cpu id='8' socket_id='2' core_id='8' siblings='8'/>
+-            <cpu id='9' socket_id='2' core_id='9' siblings='9'/>
+-            <cpu id='10' socket_id='2' core_id='10' siblings='10'/>
+-            <cpu id='11' socket_id='2' core_id='11' siblings='11'/>
++            <cpu id='8' socket_id='2' die_id='0' core_id='8' siblings='8'/>
++            <cpu id='9' socket_id='2' die_id='0' core_id='9' siblings='9'/>
++            <cpu id='10' socket_id='2' die_id='0' core_id='10' siblings='10'/>
++            <cpu id='11' socket_id='2' die_id='0' core_id='11' siblings='11'/>
+           </cpus>
+         </cell>
+         <cell id='3'>
+@@ -52,10 +52,10 @@
+           <pages unit='KiB' size='2048'>10240</pages>
+           <pages unit='KiB' size='1048576'>12288</pages>
+           <cpus num='4'>
+-            <cpu id='12' socket_id='3' core_id='12' siblings='12'/>
+-            <cpu id='13' socket_id='3' core_id='13' siblings='13'/>
+-            <cpu id='14' socket_id='3' core_id='14' siblings='14'/>
+-            <cpu id='15' socket_id='3' core_id='15' siblings='15'/>
++            <cpu id='12' socket_id='3' die_id='0' core_id='12' siblings='12'/>
++            <cpu id='13' socket_id='3' die_id='0' core_id='13' siblings='13'/>
++            <cpu id='14' socket_id='3' die_id='0' core_id='14' siblings='14'/>
++            <cpu id='15' socket_id='3' die_id='0' core_id='15' siblings='15'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-basic.xml b/tests/vircaps2xmldata/vircaps-x86_64-basic.xml
+index e7be6def3e..4da09f889c 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-basic.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-basic.xml
+@@ -14,10 +14,10 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='4'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
+-            <cpu id='1' socket_id='0' core_id='1' siblings='1'/>
+-            <cpu id='2' socket_id='0' core_id='2' siblings='2'/>
+-            <cpu id='3' socket_id='0' core_id='3' siblings='3'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
++            <cpu id='2' socket_id='0' die_id='0' core_id='2' siblings='2'/>
++            <cpu id='3' socket_id='0' die_id='0' core_id='3' siblings='3'/>
+           </cpus>
+         </cell>
+         <cell id='1'>
+@@ -26,10 +26,10 @@
+           <pages unit='KiB' size='2048'>6144</pages>
+           <pages unit='KiB' size='1048576'>8192</pages>
+           <cpus num='4'>
+-            <cpu id='4' socket_id='1' core_id='4' siblings='4'/>
+-            <cpu id='5' socket_id='1' core_id='5' siblings='5'/>
+-            <cpu id='6' socket_id='1' core_id='6' siblings='6'/>
+-            <cpu id='7' socket_id='1' core_id='7' siblings='7'/>
++            <cpu id='4' socket_id='1' die_id='0' core_id='4' siblings='4'/>
++            <cpu id='5' socket_id='1' die_id='0' core_id='5' siblings='5'/>
++            <cpu id='6' socket_id='1' die_id='0' core_id='6' siblings='6'/>
++            <cpu id='7' socket_id='1' die_id='0' core_id='7' siblings='7'/>
+           </cpus>
+         </cell>
+         <cell id='2'>
+@@ -38,10 +38,10 @@
+           <pages unit='KiB' size='2048'>8192</pages>
+           <pages unit='KiB' size='1048576'>10240</pages>
+           <cpus num='4'>
+-            <cpu id='8' socket_id='2' core_id='8' siblings='8'/>
+-            <cpu id='9' socket_id='2' core_id='9' siblings='9'/>
+-            <cpu id='10' socket_id='2' core_id='10' siblings='10'/>
+-            <cpu id='11' socket_id='2' core_id='11' siblings='11'/>
++            <cpu id='8' socket_id='2' die_id='0' core_id='8' siblings='8'/>
++            <cpu id='9' socket_id='2' die_id='0' core_id='9' siblings='9'/>
++            <cpu id='10' socket_id='2' die_id='0' core_id='10' siblings='10'/>
++            <cpu id='11' socket_id='2' die_id='0' core_id='11' siblings='11'/>
+           </cpus>
+         </cell>
+         <cell id='3'>
+@@ -50,10 +50,10 @@
+           <pages unit='KiB' size='2048'>10240</pages>
+           <pages unit='KiB' size='1048576'>12288</pages>
+           <cpus num='4'>
+-            <cpu id='12' socket_id='3' core_id='12' siblings='12'/>
+-            <cpu id='13' socket_id='3' core_id='13' siblings='13'/>
+-            <cpu id='14' socket_id='3' core_id='14' siblings='14'/>
+-            <cpu id='15' socket_id='3' core_id='15' siblings='15'/>
++            <cpu id='12' socket_id='3' die_id='0' core_id='12' siblings='12'/>
++            <cpu id='13' socket_id='3' die_id='0' core_id='13' siblings='13'/>
++            <cpu id='14' socket_id='3' die_id='0' core_id='14' siblings='14'/>
++            <cpu id='15' socket_id='3' die_id='0' core_id='15' siblings='15'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-caches.xml b/tests/vircaps2xmldata/vircaps-x86_64-caches.xml
+index ca671a1640..28f00c0a90 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-caches.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-caches.xml
+@@ -17,14 +17,14 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='8'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0,4'/>
+-            <cpu id='1' socket_id='0' core_id='1' siblings='1,5'/>
+-            <cpu id='2' socket_id='0' core_id='2' siblings='2,6'/>
+-            <cpu id='3' socket_id='0' core_id='3' siblings='3,7'/>
+-            <cpu id='4' socket_id='0' core_id='0' siblings='0,4'/>
+-            <cpu id='5' socket_id='0' core_id='1' siblings='1,5'/>
+-            <cpu id='6' socket_id='0' core_id='2' siblings='2,6'/>
+-            <cpu id='7' socket_id='0' core_id='3' siblings='3,7'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0,4'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1,5'/>
++            <cpu id='2' socket_id='0' die_id='0' core_id='2' siblings='2,6'/>
++            <cpu id='3' socket_id='0' die_id='0' core_id='3' siblings='3,7'/>
++            <cpu id='4' socket_id='0' die_id='0' core_id='0' siblings='0,4'/>
++            <cpu id='5' socket_id='0' die_id='0' core_id='1' siblings='1,5'/>
++            <cpu id='6' socket_id='0' die_id='0' core_id='2' siblings='2,6'/>
++            <cpu id='7' socket_id='0' die_id='0' core_id='3' siblings='3,7'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml
+index 1d3df318c5..ee26fe9464 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml
+@@ -17,12 +17,12 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='6'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
+-            <cpu id='1' socket_id='0' core_id='1' siblings='1'/>
+-            <cpu id='2' socket_id='0' core_id='2' siblings='2'/>
+-            <cpu id='3' socket_id='0' core_id='3' siblings='3'/>
+-            <cpu id='4' socket_id='0' core_id='4' siblings='4'/>
+-            <cpu id='5' socket_id='0' core_id='5' siblings='5'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
++            <cpu id='2' socket_id='0' die_id='0' core_id='2' siblings='2'/>
++            <cpu id='3' socket_id='0' die_id='0' core_id='3' siblings='3'/>
++            <cpu id='4' socket_id='0' die_id='0' core_id='4' siblings='4'/>
++            <cpu id='5' socket_id='0' die_id='0' core_id='5' siblings='5'/>
+           </cpus>
+         </cell>
+         <cell id='1'>
+@@ -31,12 +31,12 @@
+           <pages unit='KiB' size='2048'>6144</pages>
+           <pages unit='KiB' size='1048576'>8192</pages>
+           <cpus num='6'>
+-            <cpu id='6' socket_id='1' core_id='0' siblings='6'/>
+-            <cpu id='7' socket_id='1' core_id='1' siblings='7'/>
+-            <cpu id='8' socket_id='1' core_id='2' siblings='8'/>
+-            <cpu id='9' socket_id='1' core_id='3' siblings='9'/>
+-            <cpu id='10' socket_id='1' core_id='4' siblings='10'/>
+-            <cpu id='11' socket_id='1' core_id='5' siblings='11'/>
++            <cpu id='6' socket_id='1' die_id='0' core_id='0' siblings='6'/>
++            <cpu id='7' socket_id='1' die_id='0' core_id='1' siblings='7'/>
++            <cpu id='8' socket_id='1' die_id='0' core_id='2' siblings='8'/>
++            <cpu id='9' socket_id='1' die_id='0' core_id='3' siblings='9'/>
++            <cpu id='10' socket_id='1' die_id='0' core_id='4' siblings='10'/>
++            <cpu id='11' socket_id='1' die_id='0' core_id='5' siblings='11'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml
+index 6a8cd0e909..acdd97ec58 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml
+@@ -17,12 +17,12 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='6'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
+-            <cpu id='1' socket_id='0' core_id='1' siblings='1'/>
+-            <cpu id='2' socket_id='0' core_id='2' siblings='2'/>
+-            <cpu id='3' socket_id='0' core_id='3' siblings='3'/>
+-            <cpu id='4' socket_id='0' core_id='4' siblings='4'/>
+-            <cpu id='5' socket_id='0' core_id='5' siblings='5'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
++            <cpu id='2' socket_id='0' die_id='0' core_id='2' siblings='2'/>
++            <cpu id='3' socket_id='0' die_id='0' core_id='3' siblings='3'/>
++            <cpu id='4' socket_id='0' die_id='0' core_id='4' siblings='4'/>
++            <cpu id='5' socket_id='0' die_id='0' core_id='5' siblings='5'/>
+           </cpus>
+         </cell>
+         <cell id='1'>
+@@ -31,12 +31,12 @@
+           <pages unit='KiB' size='2048'>6144</pages>
+           <pages unit='KiB' size='1048576'>8192</pages>
+           <cpus num='6'>
+-            <cpu id='6' socket_id='1' core_id='0' siblings='6'/>
+-            <cpu id='7' socket_id='1' core_id='1' siblings='7'/>
+-            <cpu id='8' socket_id='1' core_id='2' siblings='8'/>
+-            <cpu id='9' socket_id='1' core_id='3' siblings='9'/>
+-            <cpu id='10' socket_id='1' core_id='4' siblings='10'/>
+-            <cpu id='11' socket_id='1' core_id='5' siblings='11'/>
++            <cpu id='6' socket_id='1' die_id='0' core_id='0' siblings='6'/>
++            <cpu id='7' socket_id='1' die_id='0' core_id='1' siblings='7'/>
++            <cpu id='8' socket_id='1' die_id='0' core_id='2' siblings='8'/>
++            <cpu id='9' socket_id='1' die_id='0' core_id='3' siblings='9'/>
++            <cpu id='10' socket_id='1' die_id='0' core_id='4' siblings='10'/>
++            <cpu id='11' socket_id='1' die_id='0' core_id='5' siblings='11'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml
+index 4e46ead616..5f3678e072 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml
+@@ -17,12 +17,12 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='6'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
+-            <cpu id='1' socket_id='0' core_id='1' siblings='1'/>
+-            <cpu id='2' socket_id='0' core_id='2' siblings='2'/>
+-            <cpu id='3' socket_id='0' core_id='3' siblings='3'/>
+-            <cpu id='4' socket_id='0' core_id='4' siblings='4'/>
+-            <cpu id='5' socket_id='0' core_id='5' siblings='5'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
++            <cpu id='2' socket_id='0' die_id='0' core_id='2' siblings='2'/>
++            <cpu id='3' socket_id='0' die_id='0' core_id='3' siblings='3'/>
++            <cpu id='4' socket_id='0' die_id='0' core_id='4' siblings='4'/>
++            <cpu id='5' socket_id='0' die_id='0' core_id='5' siblings='5'/>
+           </cpus>
+         </cell>
+         <cell id='1'>
+@@ -31,12 +31,12 @@
+           <pages unit='KiB' size='2048'>6144</pages>
+           <pages unit='KiB' size='1048576'>8192</pages>
+           <cpus num='6'>
+-            <cpu id='6' socket_id='1' core_id='0' siblings='6'/>
+-            <cpu id='7' socket_id='1' core_id='1' siblings='7'/>
+-            <cpu id='8' socket_id='1' core_id='2' siblings='8'/>
+-            <cpu id='9' socket_id='1' core_id='3' siblings='9'/>
+-            <cpu id='10' socket_id='1' core_id='4' siblings='10'/>
+-            <cpu id='11' socket_id='1' core_id='5' siblings='11'/>
++            <cpu id='6' socket_id='1' die_id='0' core_id='0' siblings='6'/>
++            <cpu id='7' socket_id='1' die_id='0' core_id='1' siblings='7'/>
++            <cpu id='8' socket_id='1' die_id='0' core_id='2' siblings='8'/>
++            <cpu id='9' socket_id='1' die_id='0' core_id='3' siblings='9'/>
++            <cpu id='10' socket_id='1' die_id='0' core_id='4' siblings='10'/>
++            <cpu id='11' socket_id='1' die_id='0' core_id='5' siblings='11'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml
+index 44c1042afe..6769bd0591 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml
+@@ -17,7 +17,7 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='1'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml
+index 8382a26c7a..bc52480905 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml
+@@ -17,7 +17,7 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='1'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
+           </cpus>
+         </cell>
+       </cells>
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml
+index a27b3e247e..c386edd4b0 100644
+--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml
++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml
+@@ -17,12 +17,12 @@
+           <pages unit='KiB' size='2048'>4096</pages>
+           <pages unit='KiB' size='1048576'>6144</pages>
+           <cpus num='6'>
+-            <cpu id='0' socket_id='0' core_id='0' siblings='0'/>
+-            <cpu id='1' socket_id='0' core_id='1' siblings='1'/>
+-            <cpu id='2' socket_id='0' core_id='2' siblings='2'/>
+-            <cpu id='3' socket_id='0' core_id='3' siblings='3'/>
+-            <cpu id='4' socket_id='0' core_id='4' siblings='4'/>
+-            <cpu id='5' socket_id='0' core_id='5' siblings='5'/>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
++            <cpu id='2' socket_id='0' die_id='0' core_id='2' siblings='2'/>
++            <cpu id='3' socket_id='0' die_id='0' core_id='3' siblings='3'/>
++            <cpu id='4' socket_id='0' die_id='0' core_id='4' siblings='4'/>
++            <cpu id='5' socket_id='0' die_id='0' core_id='5' siblings='5'/>
+           </cpus>
+         </cell>
+         <cell id='1'>
+@@ -31,12 +31,12 @@
+           <pages unit='KiB' size='2048'>6144</pages>
+           <pages unit='KiB' size='1048576'>8192</pages>
+           <cpus num='6'>
+-            <cpu id='6' socket_id='1' core_id='0' siblings='6'/>
+-            <cpu id='7' socket_id='1' core_id='1' siblings='7'/>
+-            <cpu id='8' socket_id='1' core_id='2' siblings='8'/>
+-            <cpu id='9' socket_id='1' core_id='3' siblings='9'/>
+-            <cpu id='10' socket_id='1' core_id='4' siblings='10'/>
+-            <cpu id='11' socket_id='1' core_id='5' siblings='11'/>
++            <cpu id='6' socket_id='1' die_id='0' core_id='0' siblings='6'/>
++            <cpu id='7' socket_id='1' die_id='0' core_id='1' siblings='7'/>
++            <cpu id='8' socket_id='1' die_id='0' core_id='2' siblings='8'/>
++            <cpu id='9' socket_id='1' die_id='0' core_id='3' siblings='9'/>
++            <cpu id='10' socket_id='1' die_id='0' core_id='4' siblings='10'/>
++            <cpu id='11' socket_id='1' die_id='0' core_id='5' siblings='11'/>
+           </cpus>
+         </cell>
+       </cells>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-kbase-backing_chains-Add-steps-how-to-securely-probe-image-format.patch b/SOURCES/libvirt-kbase-backing_chains-Add-steps-how-to-securely-probe-image-format.patch
new file mode 100644
index 0000000..942f80c
--- /dev/null
+++ b/SOURCES/libvirt-kbase-backing_chains-Add-steps-how-to-securely-probe-image-format.patch
@@ -0,0 +1,54 @@
+From 9146b5849b0dfc2ee59eea09712cc7f5f88c88f2 Mon Sep 17 00:00:00 2001
+Message-Id: <9146b5849b0dfc2ee59eea09712cc7f5f88c88f2@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:45 +0100
+Subject: [PATCH] kbase: backing_chains: Add steps how to securely probe image
+ format
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We document steps how to fix images if they are rejected for missing
+the 'backing file format' field. Document also how to securely probe
+the image format if it's unknown.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 82d5b762f11b50abb710c751251f28d4325a4c91)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <039ebfe436c361b067ef73a7c0bb16db1e410044.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/kbase/backing_chains.rst | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/docs/kbase/backing_chains.rst b/docs/kbase/backing_chains.rst
+index 12ed6253ac..af848ccb14 100644
+--- a/docs/kbase/backing_chains.rst
++++ b/docs/kbase/backing_chains.rst
+@@ -176,6 +176,21 @@ properly. ``$BACKING_IMAGE_PATH`` should be specified as a full absolute path.
+ If relative referencing of the backing image is desired, the path must be
+ relative to the location of image described by ``$IMAGE_PATH``.
+ 
++**Important:** If the ``$BACKING_IMAGE_FORMAT`` is not known it can be queried
++using ``qemu-img info $BACKING_IMAGE_PATH`` and looking for the ``file format:``
++field, but for security reasons should be used *only* if at least one of the
++following criteria is met:
++
++- ``file format`` is ``raw``
++- ``backing file`` is NOT present
++- ``backing file`` is present AND is correct/trusted
++
++Note that the last criteria may require manual inspection and thus should not
++be scripted unless the trust for the image can be expressed programatically.
++
++Also note that the above steps may need to be repeated recursively for any
++subsequent backing images.
++
+ Missing images reported after after moving disk images into a different path
+ ----------------------------------------------------------------------------
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-kbase-backing_chains-Clarify-some-aspects-of-image-probing.patch b/SOURCES/libvirt-kbase-backing_chains-Clarify-some-aspects-of-image-probing.patch
new file mode 100644
index 0000000..12428cc
--- /dev/null
+++ b/SOURCES/libvirt-kbase-backing_chains-Clarify-some-aspects-of-image-probing.patch
@@ -0,0 +1,70 @@
+From 2256db09e8b86b58be3c86b1575d64d7a9f5d05c Mon Sep 17 00:00:00 2001
+Message-Id: <2256db09e8b86b58be3c86b1575d64d7a9f5d05c@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:44 +0100
+Subject: [PATCH] kbase: backing_chains: Clarify some aspects of image probing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit d552b93448e253552c7e53a1240132c9763d2b24)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <b44052c081a18bec62762ab2a7358abd0e914a3a.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/kbase/backing_chains.rst | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/docs/kbase/backing_chains.rst b/docs/kbase/backing_chains.rst
+index 3b3f0583e5..12ed6253ac 100644
+--- a/docs/kbase/backing_chains.rst
++++ b/docs/kbase/backing_chains.rst
+@@ -46,14 +46,17 @@ system used on the host so that the hypervisor can access the files and possibly
+ also directly to configure the hypervisor to use the appropriate images. Thus
+ it's important to properly setup the formats and paths of the backing images.
+ 
++Any externally created image should always use the -F switch of ``qemu-img``
++to specify the format of the backing file to avoid probing.
++
+ Image detection caveats
+ -----------------------
+ 
+ Detection of the backing chain requires libvirt to read and understand the
+ ``backing file`` field recorded in the image metadata and also being able to
+ recurse and read the backing file. Due to security implications libvirt
+-will not attempt to detect the format of the backing image if the image metadata
+-doesn't contain it.
++will refuse to use backing images of any image whose format was not specified
++explicitly in the XML or the overlay image itself.
+ 
+ Libvirt also might lack support for a network disk storage technology and thus
+ may be unable to visit and detect backing chains on such storage. This may
+@@ -104,6 +107,8 @@ Note that it's also possible to partially specify the chain in the XML but omit
+ the terminating element. This will result into probing from the last specified
+ ``<backingStore>``
+ 
++Any image specified explicitly will not be probed for backing file or format.
++
+ 
+ Manual image creation
+ =====================
+@@ -113,6 +118,13 @@ them properly so that they work with libvirt as expected. The created disk
+ images must contain the format of the backing image in the metadata. This
+ means that the **-F** parameter of ``qemu-img`` must always be used.
+ 
++::
++
++  qemu-img -f qcow2 -F qcow2 -b /path/to/backing /path/to/overlay
++
++Note that if '/path/to/backing' is relative the path is considered relative to
++the location of '/path/to/overlay'.
++
+ Troubleshooting
+ ===============
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Add-support-for-slices-of-type-storage.patch b/SOURCES/libvirt-qemu-Add-support-for-slices-of-type-storage.patch
new file mode 100644
index 0000000..76ccfc3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Add-support-for-slices-of-type-storage.patch
@@ -0,0 +1,231 @@
+From 9d2cbc9ca4405fcf11e5796414af0038eb7c7f9e Mon Sep 17 00:00:00 2001
+Message-Id: <9d2cbc9ca4405fcf11e5796414af0038eb7c7f9e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:24 +0100
+Subject: [PATCH] qemu: Add support for slices of type 'storage'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Implement support for the slice of type 'storage' which allows to set
+the offset and size which modifies where qemu should look for the start
+of the format container inside the image.
+
+Since slicing is done using the 'raw' driver we need to add another
+layer into the blockdev tree if there's any non-raw image format driver
+used to access the data.
+
+This patch adds the blockdev integration and setup of the image data so
+that we can use the slices for any backing image.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 0e644e6e47a48830dc10b090a999d4ba2e7d5394)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <1f8e63abfd1836f1df91f54cf2c018a7d5047825.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c    | 68 +++++++++++++++++++++++++++++++++++++++-
+ src/qemu/qemu_block.h    |  4 +++
+ src/qemu/qemu_blockjob.c |  1 +
+ src/qemu/qemu_command.c  |  8 +++++
+ src/qemu/qemu_domain.c   |  4 +++
+ 5 files changed, 84 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 387a2db2e6..5bd5c955a4 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1423,11 +1423,16 @@ qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src,
+                                        virStorageSourcePtr backingStore)
+ {
+     g_autoptr(virJSONValue) props = NULL;
++    const char *storagenode = src->nodestorage;
++
++    if (src->sliceStorage &&
++        src->format != VIR_STORAGE_FILE_RAW)
++        storagenode = src->sliceStorage->nodename;
+ 
+     if (!(props = qemuBlockStorageSourceGetBlockdevFormatProps(src)))
+         return NULL;
+ 
+-    if (virJSONValueObjectAppendString(props, "file", src->nodestorage) < 0)
++    if (virJSONValueObjectAppendString(props, "file", storagenode) < 0)
+         return NULL;
+ 
+     if (backingStore) {
+@@ -1456,6 +1461,32 @@ qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src,
+ }
+ 
+ 
++static virJSONValuePtr
++qemuBlockStorageSourceGetBlockdevStorageSliceProps(virStorageSourcePtr src)
++{
++    g_autoptr(virJSONValue) props = NULL;
++
++    if (qemuBlockNodeNameValidate(src->sliceStorage->nodename) < 0)
++        return NULL;
++
++    if (virJSONValueObjectCreate(&props,
++                                 "s:driver", "raw",
++                                 "s:node-name", src->sliceStorage->nodename,
++                                 "U:offset", src->sliceStorage->offset,
++                                 "U:size", src->sliceStorage->size,
++                                 "s:file", src->nodestorage,
++                                 "b:auto-read-only", true,
++                                 "s:discard", "unmap",
++                                 NULL) < 0)
++        return NULL;
++
++    if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, props) < 0)
++        return NULL;
++
++    return g_steal_pointer(&props);
++}
++
++
+ void
+ qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
+ {
+@@ -1463,6 +1494,7 @@ qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
+         return;
+ 
+     virJSONValueFree(data->storageProps);
++    virJSONValueFree(data->storageSliceProps);
+     virJSONValueFree(data->formatProps);
+     virJSONValueFree(data->prmgrProps);
+     virJSONValueFree(data->authsecretProps);
+@@ -1513,6 +1545,13 @@ qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src,
+     data->storageNodeName = src->nodestorage;
+     data->formatNodeName = src->nodeformat;
+ 
++    if (src->sliceStorage && src->format != VIR_STORAGE_FILE_RAW) {
++        if (!(data->storageSliceProps = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src)))
++            return NULL;
++
++        data->storageSliceNodeName = src->sliceStorage->nodename;
++    }
++
+     return g_steal_pointer(&data);
+ }
+ 
+@@ -1581,6 +1620,21 @@ qemuBlockStorageSourceAttachApplyFormat(qemuMonitorPtr mon,
+ }
+ 
+ 
++static int
++qemuBlockStorageSourceAttachApplyStorageSlice(qemuMonitorPtr mon,
++                                              qemuBlockStorageSourceAttachDataPtr data)
++{
++    if (data->storageSliceProps) {
++        if (qemuMonitorBlockdevAdd(mon, &data->storageSliceProps) < 0)
++            return -1;
++
++        data->storageSliceAttached = true;
++    }
++
++    return 0;
++}
++
++
+ /**
+  * qemuBlockStorageSourceAttachApply:
+  * @mon: monitor object
+@@ -1600,6 +1654,7 @@ qemuBlockStorageSourceAttachApply(qemuMonitorPtr mon,
+ {
+     if (qemuBlockStorageSourceAttachApplyStorageDeps(mon, data) < 0 ||
+         qemuBlockStorageSourceAttachApplyStorage(mon, data) < 0 ||
++        qemuBlockStorageSourceAttachApplyStorageSlice(mon, data) < 0 ||
+         qemuBlockStorageSourceAttachApplyFormatDeps(mon, data) < 0 ||
+         qemuBlockStorageSourceAttachApplyFormat(mon, data) < 0)
+         return -1;
+@@ -1642,6 +1697,9 @@ qemuBlockStorageSourceAttachRollback(qemuMonitorPtr mon,
+     if (data->formatAttached)
+         ignore_value(qemuMonitorBlockdevDel(mon, data->formatNodeName));
+ 
++    if (data->storageSliceAttached)
++        ignore_value(qemuMonitorBlockdevDel(mon, data->storageSliceNodeName));
++
+     if (data->storageAttached)
+         ignore_value(qemuMonitorBlockdevDel(mon, data->storageNodeName));
+ 
+@@ -1689,6 +1747,14 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
+         data->formatAttached = true;
+         data->storageNodeName = src->nodestorage;
+         data->storageAttached = true;
++
++        /* 'raw' format doesn't need the extra 'raw' layer when slicing, thus
++         * the nodename is NULL */
++        if (src->sliceStorage &&
++            src->sliceStorage->nodename) {
++            data->storageSliceNodeName = src->sliceStorage->nodename;
++            data->storageSliceAttached = true;
++        }
+     }
+ 
+     if (src->pr &&
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index a816190bb7..eab0128d5d 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -82,6 +82,10 @@ struct qemuBlockStorageSourceAttachData {
+     const char *storageNodeName;
+     bool storageAttached;
+ 
++    virJSONValuePtr storageSliceProps;
++    const char *storageSliceNodeName;
++    bool storageSliceAttached;
++
+     virJSONValuePtr formatProps;
+     const char *formatNodeName;
+     bool formatAttached;
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index 6b59bbeb2c..71df0d1ab2 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -1316,6 +1316,7 @@ qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver,
+     backend->formatAttached = false;
+     if (job->data.create.storage) {
+         backend->storageAttached = false;
++        backend->storageSliceAttached = false;
+         VIR_FREE(backend->encryptsecretAlias);
+     }
+ 
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 1a5142d472..252809a8d7 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -2427,6 +2427,14 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd,
+         VIR_FREE(tmp);
+     }
+ 
++    if (data->storageSliceProps) {
++        if (!(tmp = virJSONValueToString(data->storageSliceProps, false)))
++            return -1;
++
++        virCommandAddArgList(cmd, "-blockdev", tmp, NULL);
++        VIR_FREE(tmp);
++    }
++
+     if (data->formatProps) {
+         if (!(tmp = virJSONValueToString(data->formatProps, false)))
+             return -1;
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 948bf3011c..0baa80582c 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -16444,6 +16444,10 @@ qemuDomainPrepareStorageSourceBlockdev(virDomainDiskDefPtr disk,
+     src->nodestorage = g_strdup_printf("libvirt-%u-storage", src->id);
+     src->nodeformat = g_strdup_printf("libvirt-%u-format", src->id);
+ 
++    if (src->sliceStorage &&
++        src->format != VIR_STORAGE_FILE_RAW)
++        src->sliceStorage->nodename = g_strdup_printf("libvirt-%u-slice-sto", src->id);
++
+     if (qemuDomainValidateStorageSource(src, priv->qemuCaps) < 0)
+         return -1;
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Add-the-QEMU_CAPS_CPU_KVM_NO_ADJVTIME-capability.patch b/SOURCES/libvirt-qemu-Add-the-QEMU_CAPS_CPU_KVM_NO_ADJVTIME-capability.patch
new file mode 100644
index 0000000..65106cf
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Add-the-QEMU_CAPS_CPU_KVM_NO_ADJVTIME-capability.patch
@@ -0,0 +1,82 @@
+From 694540f2c93ccee78e203c5fe92be5e1a05a2281 Mon Sep 17 00:00:00 2001
+Message-Id: <694540f2c93ccee78e203c5fe92be5e1a05a2281@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 13:12:34 +0100
+Subject: [PATCH] qemu: Add the QEMU_CAPS_CPU_KVM_NO_ADJVTIME capability
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We will use this capability to detect whether the QEMU binary
+supports the kvm-no-adjvtime CPU feature.
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 204e2306e582524b46c4e26e1f0aa354aa50d006)
+
+Conflicts:
+
+  * src/qemu/qemu_capabilities.c
+    src/qemu/qemu_capabilities.h
+
+    + tpm-spapr has not been backported
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214121237.623948-4-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_capabilities.c                      | 2 ++
+ src/qemu/qemu_capabilities.h                      | 1 +
+ tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml | 1 +
+ 3 files changed, 4 insertions(+)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 10c17323be..6912a6f72b 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -557,6 +557,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
+ 
+               /* 350 */
+               "virtio-net.failover",
++              "cpu.kvm-no-adjvtime",
+     );
+ 
+ 
+@@ -1557,6 +1558,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMemoryBackendMemfd[]
+ 
+ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMaxCPU[] = {
+     { "unavailable-features", QEMU_CAPS_CPU_UNAVAILABLE_FEATURES },
++    { "kvm-no-adjvtime", QEMU_CAPS_CPU_KVM_NO_ADJVTIME },
+ };
+ 
+ static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index 6ab0eabd3f..4ccb0c55bc 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -538,6 +538,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+ 
+     /* 350 */
+     QEMU_CAPS_VIRTIO_NET_FAILOVER, /* virtio-net-*.failover */
++    QEMU_CAPS_CPU_KVM_NO_ADJVTIME, /* cpu.kvm-no-adjvtime */
+ 
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+index 6b365dd75d..e871ba528e 100644
+--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+@@ -178,6 +178,7 @@
+   <flag name='drive-nvme'/>
+   <flag name='smp-dies'/>
+   <flag name='virtio-net.failover'/>
++  <flag name='cpu.kvm-no-adjvtime'/>
+   <version>4002050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>61700241</microcodeVersion>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Create-multipath-targets-for-PRs.patch b/SOURCES/libvirt-qemu-Create-multipath-targets-for-PRs.patch
new file mode 100644
index 0000000..b122893
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Create-multipath-targets-for-PRs.patch
@@ -0,0 +1,399 @@
+From 73c83c67608896704bfeb55b7f973f3e5ee12c96 Mon Sep 17 00:00:00 2001
+Message-Id: <73c83c67608896704bfeb55b7f973f3e5ee12c96@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Tue, 17 Mar 2020 16:08:02 +0100
+Subject: [PATCH] qemu: Create multipath targets for PRs
+
+If a disk has persistent reservations enabled, qemu-pr-helper
+might open not only /dev/mapper/control but also individual
+targets of the multipath device. We are already querying for them
+in CGroups, but now we have to create them in the namespace too.
+This was brought up in [1].
+
+1: https://bugzilla.redhat.com/show_bug.cgi?id=1711045#c61
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Tested-by: Lin Ma <LMa@suse.com>
+Reviewed-by: Jim Fehlig <jfehlig@suse.com>
+(cherry picked from commit a30078cb832646177defd256e77c632905f1e6d0)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1814157
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+
+Conflicts:
+src/qemu/qemu_domain.c: There are two conflicts. The first one is
+in the first hunk because 7e0d11be5b0 is not backported. The
+second conflict is in the third hunk and it is because
+db780004a9d and friends which switches the code over to use
+autofree and drops needless cleanup labels are not backported.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <7a59996bd80955551d37f775e8d682649b1f4a45.1584457667.git.mprivozn@redhat.com>
+Acked-by: Peter Krempa <pkrempa@redhat.com>
+---
+ src/qemu/qemu_domain.c                        | 64 ++++++++++------
+ src/util/virdevmapper.h                       |  4 +-
+ src/util/virutil.h                            |  2 +-
+ tests/qemuhotplugmock.c                       | 75 +++++++++++++++++++
+ tests/qemuhotplugtest.c                       | 13 ++++
+ .../qemuhotplug-disk-scsi-multipath.xml       |  8 ++
+ ...uhotplug-base-live+disk-scsi-multipath.xml | 62 +++++++++++++++
+ 7 files changed, 204 insertions(+), 24 deletions(-)
+ create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml
+ create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipath.xml
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index a273aefa6b..36a63449b2 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -62,6 +62,7 @@
+ #include "virdomainsnapshotobjlist.h"
+ #include "virdomaincheckpointobjlist.h"
+ #include "backup_conf.h"
++#include "virdevmapper.h"
+ 
+ #ifdef MAJOR_IN_MKDEV
+ # include <sys/mkdev.h>
+@@ -14866,6 +14867,9 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
+     int ret = -1;
+ 
+     for (next = disk->src; virStorageSourceIsBacking(next); next = next->backingStore) {
++        VIR_AUTOSTRINGLIST targetPaths = NULL;
++        size_t i;
++
+         if (next->type == VIR_STORAGE_TYPE_NVME) {
+             g_autofree char *nvmePath = NULL;
+ 
+@@ -14884,6 +14888,19 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
+ 
+             if (qemuDomainCreateDevice(next->path, data, false) < 0)
+                 goto cleanup;
++
++            if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
++                errno != ENOSYS && errno != EBADF) {
++                virReportSystemError(errno,
++                                     _("Unable to get devmapper targets for %s"),
++                                     next->path);
++                goto cleanup;
++            }
++
++            for (i = 0; targetPaths && targetPaths[i]; i++) {
++                if (qemuDomainCreateDevice(targetPaths[i], data, false) < 0)
++                    goto cleanup;
++            }
+         }
+     }
+ 
+@@ -15910,21 +15927,19 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
+                              virStorageSourcePtr src)
+ {
+     virStorageSourcePtr next;
+-    char **paths = NULL;
++    VIR_AUTOSTRINGLIST paths = NULL;
+     size_t npaths = 0;
+     bool hasNVMe = false;
+-    g_autofree char *dmPath = NULL;
+-    g_autofree char *vfioPath = NULL;
+-    int ret = -1;
+ 
+     for (next = src; virStorageSourceIsBacking(next); next = next->backingStore) {
++        VIR_AUTOSTRINGLIST targetPaths = NULL;
+         g_autofree char *tmpPath = NULL;
+ 
+         if (next->type == VIR_STORAGE_TYPE_NVME) {
+             hasNVMe = true;
+ 
+             if (!(tmpPath = virPCIDeviceAddressGetIOMMUGroupDev(&next->nvme->pciAddr)))
+-                goto cleanup;
++                return -1;
+         } else {
+             if (virStorageSourceIsEmpty(next) ||
+                 !virStorageSourceIsLocalStorage(next)) {
+@@ -15935,30 +15950,35 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
+             tmpPath = g_strdup(next->path);
+         }
+ 
+-        if (VIR_APPEND_ELEMENT(paths, npaths, tmpPath) < 0)
+-            goto cleanup;
++        if (virStringListAdd(&paths, tmpPath) < 0)
++            return -1;
++
++        if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
++            errno != ENOSYS && errno != EBADF) {
++            virReportSystemError(errno,
++                                 _("Unable to get devmapper targets for %s"),
++                                 next->path);
++            return -1;
++        }
++
++        if (virStringListMerge(&paths, &targetPaths) < 0)
++            return -1;
+     }
+ 
+     /* qemu-pr-helper might require access to /dev/mapper/control. */
+-    if (src->pr) {
+-        dmPath = g_strdup(QEMU_DEVICE_MAPPER_CONTROL_PATH);
+-        if (VIR_APPEND_ELEMENT_COPY(paths, npaths, dmPath) < 0)
+-            goto cleanup;
+-    }
++    if (src->pr &&
++        virStringListAdd(&paths, QEMU_DEVICE_MAPPER_CONTROL_PATH) < 0)
++        return -1;
+ 
+-    if (hasNVMe) {
+-        vfioPath = g_strdup(QEMU_DEV_VFIO);
+-        if (VIR_APPEND_ELEMENT(paths, npaths, vfioPath) < 0)
+-            goto cleanup;
+-    }
++    if (hasNVMe &&
++        virStringListAdd(&paths, QEMU_DEV_VFIO) < 0)
++        return -1;
+ 
++    npaths = virStringListLength((const char **) paths);
+     if (qemuDomainNamespaceMknodPaths(vm, (const char **) paths, npaths) < 0)
+-        goto cleanup;
++        return -1;
+ 
+-    ret = 0;
+- cleanup:
+-    virStringListFreeCount(paths, npaths);
+-    return ret;
++    return 0;
+ }
+ 
+ 
+diff --git a/src/util/virdevmapper.h b/src/util/virdevmapper.h
+index e576d2bf7e..87bbc63cfd 100644
+--- a/src/util/virdevmapper.h
++++ b/src/util/virdevmapper.h
+@@ -20,6 +20,8 @@
+ 
+ #pragma once
+ 
++#include "internal.h"
++
+ int
+ virDevMapperGetTargets(const char *path,
+-                       char ***devPaths);
++                       char ***devPaths) G_GNUC_NO_INLINE;
+diff --git a/src/util/virutil.h b/src/util/virutil.h
+index a2530e21b5..58c45a6447 100644
+--- a/src/util/virutil.h
++++ b/src/util/virutil.h
+@@ -122,7 +122,7 @@ bool virValidateWWN(const char *wwn);
+ 
+ int virGetDeviceID(const char *path,
+                    int *maj,
+-                   int *min);
++                   int *min) G_GNUC_NO_INLINE;
+ int virSetDeviceUnprivSGIO(const char *path,
+                            int unpriv_sgio);
+ int virGetDeviceUnprivSGIO(const char *path,
+diff --git a/tests/qemuhotplugmock.c b/tests/qemuhotplugmock.c
+index 43a9d79051..8e5b07788d 100644
+--- a/tests/qemuhotplugmock.c
++++ b/tests/qemuhotplugmock.c
+@@ -19,7 +19,24 @@
+ #include <config.h>
+ 
+ #include "qemu/qemu_hotplug.h"
++#include "qemu/qemu_process.h"
+ #include "conf/domain_conf.h"
++#include "virdevmapper.h"
++#include "virutil.h"
++#include "virmock.h"
++
++static int (*real_virGetDeviceID)(const char *path, int *maj, int *min);
++static bool (*real_virFileExists)(const char *path);
++
++static void
++init_syms(void)
++{
++    if (real_virFileExists)
++        return;
++
++    VIR_MOCK_REAL_INIT(virGetDeviceID);
++    VIR_MOCK_REAL_INIT(virFileExists);
++}
+ 
+ unsigned long long
+ qemuDomainGetUnplugTimeout(virDomainObjPtr vm G_GNUC_UNUSED)
+@@ -31,3 +48,61 @@ qemuDomainGetUnplugTimeout(virDomainObjPtr vm G_GNUC_UNUSED)
+         return 200;
+     return 100;
+ }
++
++
++int
++virDevMapperGetTargets(const char *path,
++                       char ***devPaths)
++{
++    *devPaths = NULL;
++
++    if (STREQ(path, "/dev/mapper/virt")) {
++        *devPaths = g_new(char *, 4);
++        (*devPaths)[0] = g_strdup("/dev/block/8:0");  /* /dev/sda */
++        (*devPaths)[1] = g_strdup("/dev/block/8:16"); /* /dev/sdb */
++        (*devPaths)[2] = g_strdup("/dev/block/8:32"); /* /dev/sdc */
++        (*devPaths)[3] = NULL;
++    }
++
++    return 0;
++}
++
++
++int
++virGetDeviceID(const char *path, int *maj, int *min)
++{
++    init_syms();
++
++    if (STREQ(path, "/dev/mapper/virt")) {
++        *maj = 254;
++        *min = 0;
++        return 0;
++    }
++
++    return real_virGetDeviceID(path, maj, min);
++}
++
++
++bool
++virFileExists(const char *path)
++{
++    init_syms();
++
++    if (STREQ(path, "/dev/mapper/virt"))
++        return true;
++
++    return real_virFileExists(path);
++}
++
++
++int
++qemuProcessStartManagedPRDaemon(virDomainObjPtr vm G_GNUC_UNUSED)
++{
++    return 0;
++}
++
++
++void
++qemuProcessKillManagedPRDaemon(virDomainObjPtr vm G_GNUC_UNUSED)
++{
++}
+diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
+index a60c8d1c93..2105c70ca8 100644
+--- a/tests/qemuhotplugtest.c
++++ b/tests/qemuhotplugtest.c
+@@ -87,6 +87,8 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt,
+     virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_VNC);
+     virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE);
+     virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE);
++    virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_PR_MANAGER_HELPER);
++    virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SCSI_BLOCK);
+ 
+     if (qemuTestCapsCacheInsert(driver.qemuCapsCache, priv->qemuCaps) < 0)
+         return -1;
+@@ -743,6 +745,17 @@ mymain(void)
+                    "device_del", QMP_DEVICE_DELETED("scsi3-0-5-6") QMP_OK,
+                    "human-monitor-command", HMP(""));
+ 
++    DO_TEST_ATTACH("base-live", "disk-scsi-multipath", false, true,
++                   "object-add", QMP_OK,
++                   "human-monitor-command", HMP("OK\\r\\n"),
++                   "device_add", QMP_OK);
++    DO_TEST_DETACH("base-live", "disk-scsi-multipath", true, true,
++                   "device_del", QMP_OK,
++                   "human-monitor-command", HMP(""));
++    DO_TEST_DETACH("base-live", "disk-scsi-multipath", false, false,
++                   "device_del", QMP_DEVICE_DELETED("scsi0-0-0-0") QMP_OK,
++                   "human-monitor-command", HMP(""));
++
+     DO_TEST_ATTACH("base-live", "qemu-agent", false, true,
+                    "chardev-add", QMP_OK,
+                    "device_add", QMP_OK);
+diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml b/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml
+new file mode 100644
+index 0000000000..5a6f955284
+--- /dev/null
++++ b/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml
+@@ -0,0 +1,8 @@
++<disk type='block' device='lun'>
++    <driver name='qemu' type='raw'/>
++    <source dev='/dev/mapper/virt'>
++        <reservations managed='yes'/>
++    </source>
++    <target dev='sda' bus='scsi'/>
++  <address type='drive' controller='0' bus='0' target='0' unit='0'/>
++</disk>
+diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipath.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipath.xml
+new file mode 100644
+index 0000000000..40af064d10
+--- /dev/null
++++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipath.xml
+@@ -0,0 +1,62 @@
++<domain type='kvm' id='7'>
++  <name>hotplug</name>
++  <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid>
++  <memory unit='KiB'>4194304</memory>
++  <currentMemory unit='KiB'>4194304</currentMemory>
++  <vcpu placement='static'>4</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <features>
++    <acpi/>
++    <apic/>
++    <pae/>
++  </features>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>restart</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <disk type='block' device='lun'>
++      <driver name='qemu' type='raw'/>
++      <source dev='/dev/mapper/virt'>
++        <reservations managed='yes'>
++          <source type='unix' path='/tmp/lib/domain-7-hotplug/pr-helper0.sock' mode='client'/>
++        </reservations>
++      </source>
++      <backingStore/>
++      <target dev='sda' bus='scsi'/>
++      <alias name='scsi0-0-0-0'/>
++      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
++    </disk>
++    <controller type='usb' index='0'>
++      <alias name='usb'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='ide' index='0'>
++      <alias name='ide'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
++    </controller>
++    <controller type='scsi' index='0' model='virtio-scsi'>
++      <alias name='scsi0'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'>
++      <alias name='pci'/>
++    </controller>
++    <controller type='virtio-serial' index='0'>
++      <alias name='virtio-serial0'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
++    </controller>
++    <input type='mouse' bus='ps2'>
++      <alias name='input0'/>
++    </input>
++    <input type='keyboard' bus='ps2'>
++      <alias name='input1'/>
++    </input>
++    <memballoon model='none'/>
++  </devices>
++  <seclabel type='none' model='none'/>
++</domain>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Don-t-crash-when-getting-targets-for-a-multipath.patch b/SOURCES/libvirt-qemu-Don-t-crash-when-getting-targets-for-a-multipath.patch
new file mode 100644
index 0000000..657264e
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Don-t-crash-when-getting-targets-for-a-multipath.patch
@@ -0,0 +1,84 @@
+From eb4cd7cd29f434bae7279b3166aac9f7eb2c2436 Mon Sep 17 00:00:00 2001
+Message-Id: <eb4cd7cd29f434bae7279b3166aac9f7eb2c2436@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Thu, 19 Mar 2020 19:46:43 +0100
+Subject: [PATCH] qemu: Don't crash when getting targets for a multipath
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In one of my previous commits I've introduced code that creates
+all devices for given (possible) multipath target. But I've made
+a mistake there - the code accesses 'next->path' without checking
+if the disk source is local. Note that the 'next->path' is
+NULL/doesn't make sense for VIR_STORAGE_TYPE_NVME.
+
+Fixes: a30078cb832646177defd256e77c632905f1e6d0
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1814947
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit aeb909bf9b4c3fa48d017475545df94f7c5d3b3a)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <3f21a46399486a42b8dd0fbbac25b75f4f6ac80a.1584643597.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 36a63449b2..3d31e176d1 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -15932,7 +15932,6 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
+     bool hasNVMe = false;
+ 
+     for (next = src; virStorageSourceIsBacking(next); next = next->backingStore) {
+-        VIR_AUTOSTRINGLIST targetPaths = NULL;
+         g_autofree char *tmpPath = NULL;
+ 
+         if (next->type == VIR_STORAGE_TYPE_NVME) {
+@@ -15941,6 +15940,8 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
+             if (!(tmpPath = virPCIDeviceAddressGetIOMMUGroupDev(&next->nvme->pciAddr)))
+                 return -1;
+         } else {
++            VIR_AUTOSTRINGLIST targetPaths = NULL;
++
+             if (virStorageSourceIsEmpty(next) ||
+                 !virStorageSourceIsLocalStorage(next)) {
+                 /* Not creating device. Just continue. */
+@@ -15948,20 +15949,20 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
+             }
+ 
+             tmpPath = g_strdup(next->path);
+-        }
+ 
+-        if (virStringListAdd(&paths, tmpPath) < 0)
+-            return -1;
++            if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
++                errno != ENOSYS && errno != EBADF) {
++                virReportSystemError(errno,
++                                     _("Unable to get devmapper targets for %s"),
++                                     next->path);
++                return -1;
++            }
+ 
+-        if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
+-            errno != ENOSYS && errno != EBADF) {
+-            virReportSystemError(errno,
+-                                 _("Unable to get devmapper targets for %s"),
+-                                 next->path);
+-            return -1;
++            if (virStringListMerge(&paths, &targetPaths) < 0)
++                return -1;
+         }
+ 
+-        if (virStringListMerge(&paths, &targetPaths) < 0)
++        if (virStringListAdd(&paths, tmpPath) < 0)
+             return -1;
+     }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Don-t-emit-SUSPENDED_POSTCOPY-event-on-destination.patch b/SOURCES/libvirt-qemu-Don-t-emit-SUSPENDED_POSTCOPY-event-on-destination.patch
new file mode 100644
index 0000000..2ec063b
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Don-t-emit-SUSPENDED_POSTCOPY-event-on-destination.patch
@@ -0,0 +1,53 @@
+From fcad662da8e472fc749a439d5bc2bdd30164d779 Mon Sep 17 00:00:00 2001
+Message-Id: <fcad662da8e472fc749a439d5bc2bdd30164d779@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 16 Jan 2020 19:57:53 +0100
+Subject: [PATCH] qemu: Don't emit SUSPENDED_POSTCOPY event on destination
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When pause-before-switchover QEMU capability is enabled, we get STOP
+event before MIGRATION event with postcopy-active state. To properly
+handle post-copy migration and emit correct events commit
+v4.10.0-rc1-4-geca9d21e6c added a hack to
+qemuProcessHandleMigrationStatus which translates the paused state
+reason to VIR_DOMAIN_PAUSED_POSTCOPY and emits
+VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY event when migration state changes
+to post-copy.
+
+However, the code was effective on both sides of migration resulting in
+a confusing VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY event on the destination
+host, where entering post-copy mode is already properly advertised by
+VIR_DOMAIN_EVENT_RESUMED_POSTCOPY event.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791458
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit bd04d63ad97c21b6955710e6473a502f49816a3c)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791886
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <9b32d5af0dd1d3bf7108abc426dc4d6ceeaa84f8.1579193220.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_process.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 4195042194..a7bbab9e56 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -1653,6 +1653,7 @@ qemuProcessHandleMigrationStatus(qemuMonitorPtr mon G_GNUC_UNUSED,
+     virDomainObjBroadcast(vm);
+ 
+     if (status == QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY &&
++        priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT &&
+         virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
+         reason == VIR_DOMAIN_PAUSED_MIGRATION) {
+         VIR_DEBUG("Correcting paused state reason for domain %s to %s",
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Don-t-store-disk-alias-in-qemuAgentDiskInfo.patch b/SOURCES/libvirt-qemu-Don-t-store-disk-alias-in-qemuAgentDiskInfo.patch
new file mode 100644
index 0000000..d5b4bf9
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Don-t-store-disk-alias-in-qemuAgentDiskInfo.patch
@@ -0,0 +1,192 @@
+From b4840a983e10b8cca99fa50ed3cf99af370a19c9 Mon Sep 17 00:00:00 2001
+Message-Id: <b4840a983e10b8cca99fa50ed3cf99af370a19c9@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Thu, 20 Feb 2020 10:52:25 -0600
+Subject: [PATCH] qemu: Don't store disk alias in qemuAgentDiskInfo
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The qemuAgentDiskInfo structure is filled with information received from
+the agent command response, except for the 'alias' field, which is
+retrieved from the vm definition. Limit this structure only to data that
+was received from the agent message.
+
+This is another intermediate step in moving the responsibility for
+searching the vmdef from qemu_agent.c to qemu_driver.c so that we can
+avoid holding an agent job and a normal job at the same time.
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 306b4cb070b8f57a22a261d1f097283f4ef84e65)
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1759566
+Message-Id: <20200220165227.11491-4-jjongsma@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_agent.c | 64 ++++++++++++++++++++++++-------------------
+ 1 file changed, 36 insertions(+), 28 deletions(-)
+
+diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
+index 077b5538de..4739faeed8 100644
+--- a/src/qemu/qemu_agent.c
++++ b/src/qemu/qemu_agent.c
+@@ -1847,7 +1847,6 @@ qemuAgentSetTime(qemuAgentPtr mon,
+ typedef struct _qemuAgentDiskInfo qemuAgentDiskInfo;
+ typedef qemuAgentDiskInfo *qemuAgentDiskInfoPtr;
+ struct _qemuAgentDiskInfo {
+-    char *alias;
+     char *serial;
+     virPCIDeviceAddress pci_controller;
+     char *bus_type;
+@@ -1876,7 +1875,6 @@ qemuAgentDiskInfoFree(qemuAgentDiskInfoPtr info)
+         return;
+ 
+     VIR_FREE(info->serial);
+-    VIR_FREE(info->alias);
+     VIR_FREE(info->bus_type);
+     VIR_FREE(info->devnode);
+     VIR_FREE(info);
+@@ -1902,7 +1900,8 @@ qemuAgentFSInfoFree(qemuAgentFSInfoPtr info)
+ }
+ 
+ static virDomainFSInfoPtr
+-qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent)
++qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent,
++                        virDomainDefPtr vmdef)
+ {
+     virDomainFSInfoPtr ret = NULL;
+     size_t i;
+@@ -1920,8 +1919,19 @@ qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent)
+ 
+     ret->ndevAlias = agent->ndisks;
+ 
+-    for (i = 0; i < ret->ndevAlias; i++)
+-        ret->devAlias[i] = g_strdup(agent->disks[i]->alias);
++    for (i = 0; i < ret->ndevAlias; i++) {
++        qemuAgentDiskInfoPtr agentdisk = agent->disks[i];
++        virDomainDiskDefPtr diskDef;
++
++        if (!(diskDef = virDomainDiskByAddress(vmdef,
++                                               &agentdisk->pci_controller,
++                                               agentdisk->bus,
++                                               agentdisk->target,
++                                               agentdisk->unit)))
++            continue;
++
++        ret->devAlias[i] = g_strdup(diskDef->dst);
++    }
+ 
+     return ret;
+ 
+@@ -1932,8 +1942,7 @@ qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent)
+ 
+ static int
+ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+-                            qemuAgentFSInfoPtr fsinfo,
+-                            virDomainDefPtr vmdef)
++                            qemuAgentFSInfoPtr fsinfo)
+ {
+     size_t ndisks;
+     size_t i;
+@@ -1956,7 +1965,6 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+         virJSONValuePtr jsondisk = virJSONValueArrayGet(jsondisks, i);
+         virJSONValuePtr pci;
+         qemuAgentDiskInfoPtr disk;
+-        virDomainDiskDefPtr diskDef;
+         const char *val;
+ 
+         if (!jsondisk) {
+@@ -2007,14 +2015,6 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+         GET_DISK_ADDR(pci, &disk->pci_controller.function, "function");
+ 
+ #undef GET_DISK_ADDR
+-        if (!(diskDef = virDomainDiskByAddress(vmdef,
+-                                               &disk->pci_controller,
+-                                               disk->bus,
+-                                               disk->target,
+-                                               disk->unit)))
+-            continue;
+-
+-        disk->alias = g_strdup(diskDef->dst);
+     }
+ 
+     return 0;
+@@ -2026,8 +2026,7 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+  */
+ static int
+ qemuAgentGetFSInfoInternal(qemuAgentPtr mon,
+-                           qemuAgentFSInfoPtr **info,
+-                           virDomainDefPtr vmdef)
++                           qemuAgentFSInfoPtr **info)
+ {
+     size_t i;
+     int ret = -1;
+@@ -2143,7 +2142,7 @@ qemuAgentGetFSInfoInternal(qemuAgentPtr mon,
+             goto cleanup;
+         }
+ 
+-        if (qemuAgentGetFSInfoFillDisks(disk, info_ret[i], vmdef) < 0)
++        if (qemuAgentGetFSInfoFillDisks(disk, info_ret[i]) < 0)
+             goto cleanup;
+     }
+ 
+@@ -2173,14 +2172,14 @@ qemuAgentGetFSInfo(qemuAgentPtr mon,
+     size_t i;
+     int nfs;
+ 
+-    nfs = qemuAgentGetFSInfoInternal(mon, &agentinfo, vmdef);
++    nfs = qemuAgentGetFSInfoInternal(mon, &agentinfo);
+     if (nfs < 0)
+         return ret;
+     if (VIR_ALLOC_N(info_ret, nfs) < 0)
+         goto cleanup;
+ 
+     for (i = 0; i < nfs; i++) {
+-        if (!(info_ret[i] = qemuAgentFSInfoToPublic(agentinfo[i])))
++        if (!(info_ret[i] = qemuAgentFSInfoToPublic(agentinfo[i], vmdef)))
+             goto cleanup;
+     }
+ 
+@@ -2215,7 +2214,7 @@ qemuAgentGetFSInfoParams(qemuAgentPtr mon,
+     size_t i, j;
+     int nfs;
+ 
+-    if ((nfs = qemuAgentGetFSInfoInternal(mon, &fsinfo, vmdef)) < 0)
++    if ((nfs = qemuAgentGetFSInfoInternal(mon, &fsinfo)) < 0)
+         return nfs;
+ 
+     if (virTypedParamsAddUInt(params, nparams, maxparams,
+@@ -2262,13 +2261,22 @@ qemuAgentGetFSInfoParams(qemuAgentPtr mon,
+                                   param_name, fsinfo[i]->ndisks) < 0)
+             goto cleanup;
+         for (j = 0; j < fsinfo[i]->ndisks; j++) {
++            virDomainDiskDefPtr diskdef = NULL;
+             qemuAgentDiskInfoPtr d = fsinfo[i]->disks[j];
+-            g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                       "fs.%zu.disk.%zu.alias", i, j);
+-            if (d->alias &&
+-                virTypedParamsAddString(params, nparams, maxparams,
+-                                        param_name, d->alias) < 0)
+-                goto cleanup;
++            /* match the disk to the target in the vm definition */
++            diskdef = virDomainDiskByAddress(vmdef,
++                                             &d->pci_controller,
++                                             d->bus,
++                                             d->target,
++                                             d->unit);
++            if (diskdef) {
++                g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                           "fs.%zu.disk.%zu.alias", i, j);
++                if (diskdef->dst &&
++                    virTypedParamsAddString(params, nparams, maxparams,
++                                            param_name, diskdef->dst) < 0)
++                    goto cleanup;
++            }
+ 
+             g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                        "fs.%zu.disk.%zu.serial", i, j);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Don-t-take-double-pointer-in-qemuDomainSecretInfoFree.patch b/SOURCES/libvirt-qemu-Don-t-take-double-pointer-in-qemuDomainSecretInfoFree.patch
new file mode 100644
index 0000000..c319883
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Don-t-take-double-pointer-in-qemuDomainSecretInfoFree.patch
@@ -0,0 +1,161 @@
+From bcc3726dae87335a533565c6d679434fa69fe75e Mon Sep 17 00:00:00 2001
+Message-Id: <bcc3726dae87335a533565c6d679434fa69fe75e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:41 +0100
+Subject: [PATCH] qemu: Don't take double pointer in qemuDomainSecretInfoFree
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Using a double pointer prevents the function from being used as the
+automatic cleanup function for the given type.
+
+Remove the double pointer use by replacing the calls with
+g_clear_pointer which ensures that the pointer is cleared.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 38bc76bcc1e1bccb7f3265e15b60b0f6f8fe6dfa)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <56ebeda94754aab81a682202f26c1dc158ac063a.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c           | 30 +++++++++++++-----------------
+ src/qemu/qemu_domain.h           |  2 +-
+ src/qemu/qemu_migration_params.c |  2 +-
+ 3 files changed, 15 insertions(+), 19 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 14bab896bc..b77488026a 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1106,14 +1106,10 @@ qemuDomainSecretInfoClear(qemuDomainSecretInfoPtr secinfo,
+ 
+ 
+ void
+-qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr *secinfo)
++qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr secinfo)
+ {
+-    if (!*secinfo)
+-        return;
+-
+-    qemuDomainSecretInfoClear(*secinfo, false);
+-
+-    VIR_FREE(*secinfo);
++    qemuDomainSecretInfoClear(secinfo, false);
++    g_free(secinfo);
+ }
+ 
+ 
+@@ -1203,8 +1199,8 @@ qemuDomainStorageSourcePrivateDispose(void *obj)
+ {
+     qemuDomainStorageSourcePrivatePtr priv = obj;
+ 
+-    qemuDomainSecretInfoFree(&priv->secinfo);
+-    qemuDomainSecretInfoFree(&priv->encinfo);
++    g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree);
++    g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree);
+ }
+ 
+ 
+@@ -1283,7 +1279,7 @@ qemuDomainChrSourcePrivateDispose(void *obj)
+ {
+     qemuDomainChrSourcePrivatePtr priv = obj;
+ 
+-    qemuDomainSecretInfoFree(&priv->secinfo);
++    g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree);
+ }
+ 
+ 
+@@ -1362,7 +1358,7 @@ qemuDomainGraphicsPrivateDispose(void *obj)
+     qemuDomainGraphicsPrivatePtr priv = obj;
+ 
+     VIR_FREE(priv->tlsAlias);
+-    qemuDomainSecretInfoFree(&priv->secinfo);
++    g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree);
+ }
+ 
+ 
+@@ -1642,7 +1638,7 @@ qemuDomainSecretInfoNewPlain(virSecretUsageType usageType,
+         return NULL;
+ 
+     if (qemuDomainSecretPlainSetup(secinfo, usageType, username, lookupDef) < 0) {
+-        qemuDomainSecretInfoFree(&secinfo);
++        g_clear_pointer(&secinfo, qemuDomainSecretInfoFree);
+         return NULL;
+     }
+ 
+@@ -1685,7 +1681,7 @@ qemuDomainSecretInfoNew(qemuDomainObjPrivatePtr priv,
+ 
+     if (qemuDomainSecretAESSetup(priv, secinfo, srcAlias, usageType, username,
+                                  lookupDef, isLuks) < 0) {
+-        qemuDomainSecretInfoFree(&secinfo);
++        g_clear_pointer(&secinfo, qemuDomainSecretInfoFree);
+         return NULL;
+     }
+ 
+@@ -1847,7 +1843,7 @@ qemuDomainSecretHostdevDestroy(virDomainHostdevDefPtr hostdev)
+         if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
+             srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(iscsisrc->src);
+             if (srcPriv && srcPriv->secinfo)
+-                qemuDomainSecretInfoFree(&srcPriv->secinfo);
++                g_clear_pointer(&srcPriv->secinfo, qemuDomainSecretInfoFree);
+         }
+     }
+ }
+@@ -1891,7 +1887,7 @@ qemuDomainSecretChardevDestroy(virDomainChrSourceDefPtr dev)
+     if (!chrSourcePriv || !chrSourcePriv->secinfo)
+         return;
+ 
+-    qemuDomainSecretInfoFree(&chrSourcePriv->secinfo);
++    g_clear_pointer(&chrSourcePriv->secinfo, qemuDomainSecretInfoFree);
+ }
+ 
+ 
+@@ -1947,7 +1943,7 @@ qemuDomainSecretGraphicsDestroy(virDomainGraphicsDefPtr graphics)
+         return;
+ 
+     VIR_FREE(gfxPriv->tlsAlias);
+-    qemuDomainSecretInfoFree(&gfxPriv->secinfo);
++    g_clear_pointer(&gfxPriv->secinfo, qemuDomainSecretInfoFree);
+ }
+ 
+ 
+@@ -2307,7 +2303,7 @@ qemuDomainObjPrivateFree(void *data)
+     }
+     VIR_FREE(priv->cleanupCallbacks);
+ 
+-    qemuDomainSecretInfoFree(&priv->migSecinfo);
++    g_clear_pointer(&priv->migSecinfo, qemuDomainSecretInfoFree);
+     qemuDomainMasterKeyFree(priv);
+ 
+     virHashFree(priv->blockjobs);
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index 9d143b575d..89a967efd7 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -1032,7 +1032,7 @@ void qemuDomainMasterKeyRemove(qemuDomainObjPrivatePtr priv);
+ 
+ bool qemuDomainSupportsEncryptedSecret(qemuDomainObjPrivatePtr priv);
+ 
+-void qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr *secinfo)
++void qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr secinfo)
+     ATTRIBUTE_NONNULL(1);
+ 
+ void qemuDomainSecretInfoDestroy(qemuDomainSecretInfoPtr secinfo);
+diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
+index 45acf8cda2..f61796713f 100644
+--- a/src/qemu/qemu_migration_params.c
++++ b/src/qemu/qemu_migration_params.c
+@@ -1090,7 +1090,7 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver,
+     secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false);
+ 
+     qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias);
+-    qemuDomainSecretInfoFree(&QEMU_DOMAIN_PRIVATE(vm)->migSecinfo);
++    g_clear_pointer(&QEMU_DOMAIN_PRIVATE(vm)->migSecinfo, qemuDomainSecretInfoFree);
+ 
+     VIR_FREE(tlsAlias);
+     VIR_FREE(secAlias);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Fix-value-of-device-argument-for-block-commit.patch b/SOURCES/libvirt-qemu-Fix-value-of-device-argument-for-block-commit.patch
new file mode 100644
index 0000000..b06fd40
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Fix-value-of-device-argument-for-block-commit.patch
@@ -0,0 +1,43 @@
+From 287db7fde2511199afa62af511acff4b00607c11 Mon Sep 17 00:00:00 2001
+Message-Id: <287db7fde2511199afa62af511acff4b00607c11@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:39 +0100
+Subject: [PATCH] qemu: Fix value of 'device' argument for block-commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When using blockdev configurations the 'device' argument of
+'blockdev-commit' must correspond to the topmost node in the block node
+graph. Libvirt didn't do this properly in case when 'copy_on_read'
+option was enabled on the disk.
+
+Use qemuDomainDiskGetTopNodename to fix it when calling block-commit.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 69908db0f62444e51bb8aae157b5ae48f45e2fe4)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1792195
+Message-Id: <0e7223fc993570a108cd849e9d65c476b2294d99.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 6a209ccb75..e651c9e819 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -18815,7 +18815,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
+         jobname = job->name;
+         nodetop = topSource->nodeformat;
+         nodebase = baseSource->nodeformat;
+-        device = disk->src->nodeformat;
++        device = qemuDomainDiskGetTopNodename(disk);
+         if (!backingPath && top_parent &&
+             !(backingPath = qemuBlockGetBackingStoreString(baseSource)))
+             goto endjob;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Fix-value-of-device-argument-for-blockdev-mirror.patch b/SOURCES/libvirt-qemu-Fix-value-of-device-argument-for-blockdev-mirror.patch
new file mode 100644
index 0000000..adc881f
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Fix-value-of-device-argument-for-blockdev-mirror.patch
@@ -0,0 +1,58 @@
+From 3959e3ef365e95ee4f5e68eb1ab189d6e8cb189d Mon Sep 17 00:00:00 2001
+Message-Id: <3959e3ef365e95ee4f5e68eb1ab189d6e8cb189d@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:38 +0100
+Subject: [PATCH] qemu: Fix value of 'device' argument for blockdev-mirror
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When using blockdev configurations the 'device' argument of
+'blockdev-mirror' must correspond to the topmost node in the block node
+graph. Libvirt didn't do this properly in case when 'copy_on_read'
+option was enabled on the disk.
+
+Use qemuDomainDiskGetTopNodename to fix it for the blockdev-mirror calls
+in qemuDomainBlockCopy and the non-shared-storage migration.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit e3137539a9c4af25ab085506d5467ec0847b0ecc)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1792195
+Message-Id: <1b3e7edbec684588424e78ed5009bfcb0ce7e183.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c    | 2 +-
+ src/qemu/qemu_migration.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 83f24d7231..6a209ccb75 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -18388,7 +18388,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
+ 
+     if (blockdev) {
+         ret = qemuMonitorBlockdevMirror(priv->mon, job->name, true,
+-                                        disk->src->nodeformat,
++                                        qemuDomainDiskGetTopNodename(disk),
+                                         mirror->nodeformat, bandwidth,
+                                         granularity, buf_size, mirror_shallow);
+     } else {
+diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
+index b56ccbdc3c..03f058051d 100644
+--- a/src/qemu/qemu_migration.c
++++ b/src/qemu/qemu_migration.c
+@@ -931,7 +931,7 @@ qemuMigrationSrcNBDStorageCopyOne(virQEMUDriverPtr driver,
+ 
+     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) {
+         jobname = diskAlias;
+-        sourcename = disk->src->nodeformat;
++        sourcename = qemuDomainDiskGetTopNodename(disk);
+         persistjob = true;
+     } else {
+         jobname = NULL;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Format-the-armvtimer-timer-on-the-command-line.patch b/SOURCES/libvirt-qemu-Format-the-armvtimer-timer-on-the-command-line.patch
new file mode 100644
index 0000000..f0618b8
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Format-the-armvtimer-timer-on-the-command-line.patch
@@ -0,0 +1,52 @@
+From b9acfbcad6181babba50384741e0c30d6d0cc534 Mon Sep 17 00:00:00 2001
+Message-Id: <b9acfbcad6181babba50384741e0c30d6d0cc534@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 13:12:37 +0100
+Subject: [PATCH] qemu: Format the armvtimer timer on the command line
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Its behavior is controlled by a KVM-specific CPU feature.
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 7c4bc108a9bd7bda1543131d232e2ccee92a9e43)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214121237.623948-7-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_command.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index e1e19e0fcc..1a5142d472 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -6633,6 +6633,19 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
+                 virBufferAsprintf(&buf, ",tsc-frequency=%lu", timer->frequency);
+             break;
+         case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
++            switch (timer->tickpolicy) {
++            case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
++                virBufferAddLit(&buf, ",kvm-no-adjvtime=off");
++                break;
++            case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
++                virBufferAddLit(&buf, ",kvm-no-adjvtime=on");
++                break;
++            case -1:
++            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
++            case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
++                break;
++            }
++            break;
+         case VIR_DOMAIN_TIMER_NAME_PLATFORM:
+         case VIR_DOMAIN_TIMER_NAME_PIT:
+         case VIR_DOMAIN_TIMER_NAME_RTC:
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Handle-hotplug-and-commandline-for-secret-objects-for-http-cookies.patch b/SOURCES/libvirt-qemu-Handle-hotplug-and-commandline-for-secret-objects-for-http-cookies.patch
new file mode 100644
index 0000000..7a3ea28
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Handle-hotplug-and-commandline-for-secret-objects-for-http-cookies.patch
@@ -0,0 +1,117 @@
+From 45181b943720b46caf3263c2edbc5c0427870369 Mon Sep 17 00:00:00 2001
+Message-Id: <45181b943720b46caf3263c2edbc5c0427870369@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:04 +0100
+Subject: [PATCH] qemu: Handle hotplug and commandline for secret objects for
+ http cookies
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Implement both commandline support and hotplug by adding the http cookie
+handling to 'qemuBlockStorageSourceAttachData' handling functions for
+it.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit b512935b17d991dcdd1a14e39e5f13ca828bd416)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <40869b86260516bd56253a39e5dfb54519e5313e.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c   | 13 +++++++++++++
+ src/qemu/qemu_block.h   |  3 +++
+ src/qemu/qemu_command.c |  5 +++++
+ 3 files changed, 21 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index e60975a142..f07420b6e2 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1499,11 +1499,13 @@ qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
+     virJSONValueFree(data->formatProps);
+     virJSONValueFree(data->prmgrProps);
+     virJSONValueFree(data->authsecretProps);
++    virJSONValueFree(data->httpcookiesecretProps);
+     virJSONValueFree(data->encryptsecretProps);
+     virJSONValueFree(data->tlsProps);
+     VIR_FREE(data->tlsAlias);
+     VIR_FREE(data->authsecretAlias);
+     VIR_FREE(data->encryptsecretAlias);
++    VIR_FREE(data->httpcookiesecretAlias);
+     VIR_FREE(data->driveCmd);
+     VIR_FREE(data->driveAlias);
+     VIR_FREE(data);
+@@ -1570,6 +1572,11 @@ qemuBlockStorageSourceAttachApplyStorageDeps(qemuMonitorPtr mon,
+                              &data->authsecretAlias) < 0)
+         return -1;
+ 
++    if (data->httpcookiesecretProps &&
++        qemuMonitorAddObject(mon, &data->httpcookiesecretProps,
++                             &data->httpcookiesecretAlias) < 0)
++        return -1;
++
+     if (data->tlsProps &&
+         qemuMonitorAddObject(mon, &data->tlsProps, &data->tlsAlias) < 0)
+         return -1;
+@@ -1713,6 +1720,9 @@ qemuBlockStorageSourceAttachRollback(qemuMonitorPtr mon,
+     if (data->encryptsecretAlias)
+         ignore_value(qemuMonitorDelObject(mon, data->encryptsecretAlias));
+ 
++    if (data->httpcookiesecretAlias)
++        ignore_value(qemuMonitorDelObject(mon, data->httpcookiesecretAlias));
++
+     if (data->tlsAlias)
+         ignore_value(qemuMonitorDelObject(mon, data->tlsAlias));
+ 
+@@ -1768,6 +1778,9 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
+ 
+         if (srcpriv->encinfo && srcpriv->encinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_AES)
+             data->encryptsecretAlias = g_strdup(srcpriv->encinfo->s.aes.alias);
++
++        if (srcpriv->httpcookie)
++            data->httpcookiesecretAlias = g_strdup(srcpriv->httpcookie->s.aes.alias);
+     }
+ 
+     return g_steal_pointer(&data);
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index eab0128d5d..197f5dae97 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -100,6 +100,9 @@ struct qemuBlockStorageSourceAttachData {
+     virJSONValuePtr encryptsecretProps;
+     char *encryptsecretAlias;
+ 
++    virJSONValuePtr httpcookiesecretProps;
++    char *httpcookiesecretAlias;
++
+     virJSONValuePtr tlsProps;
+     char *tlsAlias;
+ };
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index fc5366d88d..de97504ce1 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -2413,6 +2413,7 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd,
+     if (qemuBuildObjectCommandline(cmd, data->prmgrProps) < 0 ||
+         qemuBuildObjectCommandline(cmd, data->authsecretProps) < 0 ||
+         qemuBuildObjectCommandline(cmd, data->encryptsecretProps) < 0 ||
++        qemuBuildObjectCommandline(cmd, data->httpcookiesecretProps) < 0 ||
+         qemuBuildObjectCommandline(cmd, data->tlsProps) < 0)
+         return -1;
+ 
+@@ -10349,6 +10350,10 @@ qemuBuildStorageSourceAttachPrepareCommon(virStorageSourcePtr src,
+         if (srcpriv->encinfo &&
+             qemuBuildSecretInfoProps(srcpriv->encinfo, &data->encryptsecretProps) < 0)
+             return -1;
++
++        if (srcpriv->httpcookie &&
++            qemuBuildSecretInfoProps(srcpriv->httpcookie, &data->httpcookiesecretProps) < 0)
++            return -1;
+     }
+ 
+     if (src->haveTLS == VIR_TRISTATE_BOOL_YES &&
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Introduce-another-helper-for-creating-alias-for-a-secret-object.patch b/SOURCES/libvirt-qemu-Introduce-another-helper-for-creating-alias-for-a-secret-object.patch
new file mode 100644
index 0000000..2effaf8
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Introduce-another-helper-for-creating-alias-for-a-secret-object.patch
@@ -0,0 +1,70 @@
+From 2ca069dae766b266e12f1feb9f9ca9d3f2deb7bb Mon Sep 17 00:00:00 2001
+Message-Id: <2ca069dae766b266e12f1feb9f9ca9d3f2deb7bb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:49 +0100
+Subject: [PATCH] qemu: Introduce another helper for creating alias for a
+ 'secret' object
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+qemuAliasForSecret is meant as a replacement qemuDomainGetSecretAESAlias
+with saner API. The sub-type we are creating the alias for is passed in
+as a string rather than the unflexible 'isLuks' boolean.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit bb2a81df21710ed8258854e0dc2b3c2e923831f2)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <fe8144c851d9e849617ae66b99a8605e75697809.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_alias.c | 17 +++++++++++++++++
+ src/qemu/qemu_alias.h |  3 +++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
+index 93bdcb7548..50ad054c6c 100644
+--- a/src/qemu/qemu_alias.c
++++ b/src/qemu/qemu_alias.c
+@@ -792,6 +792,23 @@ qemuDomainGetSecretAESAlias(const char *srcalias,
+ }
+ 
+ 
++/* qemuAliasForSecret:
++ * @parentalias: alias of the parent object
++ * @obj: optional sub-object of the parent device the secret is for
++ *
++ * Generate alias for a secret object used by @parentalias device or one of
++ * the dependencies of the device described by @obj.
++ */
++char *
++qemuAliasForSecret(const char *parentalias,
++                   const char *obj)
++{
++    if (obj)
++        return g_strdup_printf("%s-%s-secret0", parentalias, obj);
++    else
++        return g_strdup_printf("%s-secret0", parentalias);
++}
++
+ /* qemuAliasTLSObjFromSrcAlias
+  * @srcAlias: Pointer to a source alias string
+  *
+diff --git a/src/qemu/qemu_alias.h b/src/qemu/qemu_alias.h
+index ae2fce16bc..645956d024 100644
+--- a/src/qemu/qemu_alias.h
++++ b/src/qemu/qemu_alias.h
+@@ -86,6 +86,9 @@ char *qemuDomainGetMasterKeyAlias(void);
+ char *qemuDomainGetSecretAESAlias(const char *srcalias,
+                                   bool isLuks);
+ 
++char *qemuAliasForSecret(const char *parentalias,
++                         const char *obj);
++
+ char *qemuAliasTLSObjFromSrcAlias(const char *srcAlias)
+     ATTRIBUTE_NONNULL(1);
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Pass-through-arguments-of-ssh-block-driver-used-by-libguestfs.patch b/SOURCES/libvirt-qemu-Pass-through-arguments-of-ssh-block-driver-used-by-libguestfs.patch
new file mode 100644
index 0000000..0734fd0
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Pass-through-arguments-of-ssh-block-driver-used-by-libguestfs.patch
@@ -0,0 +1,169 @@
+From 2c711c10712280bd4dae442bc68c8e38df3ab171 Mon Sep 17 00:00:00 2001
+Message-Id: <2c711c10712280bd4dae442bc68c8e38df3ab171@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:13 +0100
+Subject: [PATCH] qemu: Pass through arguments of 'ssh' block driver used by
+ libguestfs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We currently don't model the 'ssh' protocol properties properly and
+since it seems impossible for now (agent path passed via environment
+variable). To allow libguestfs to work as it used in pre-blockdev era we
+must carry the properties over to the command line. For this instance we
+just store it internally and format it back.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit d6db013c6e507fe45ebc07fa109e608cf7451b22)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <521e8b33432bfa847007866c631d6d6454f08ea3.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c                              | 10 ++++++++++
+ src/util/virstoragefile.c                          | 13 +++++++++++++
+ src/util/virstoragefile.h                          |  5 +++++
+ tests/qemublocktest.c                              |  1 +
+ .../jsontojson/ssh-passthrough-libguestfs-in.json  |  1 +
+ .../jsontojson/ssh-passthrough-libguestfs-out.json | 14 ++++++++++++++
+ 6 files changed, 44 insertions(+)
+ create mode 100644 tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-in.json
+ create mode 100644 tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-out.json
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index b077e2e02f..141059ae81 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -911,6 +911,7 @@ qemuBlockStorageSourceGetSshProps(virStorageSourcePtr src)
+     g_autoptr(virJSONValue) serverprops = NULL;
+     virJSONValuePtr ret = NULL;
+     const char *username = NULL;
++    g_autoptr(virJSONValue) host_key_check = NULL;
+ 
+     if (src->nhosts != 1) {
+         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+@@ -924,11 +925,20 @@ qemuBlockStorageSourceGetSshProps(virStorageSourcePtr src)
+ 
+     if (src->auth)
+         username = src->auth->username;
++    else if (src->ssh_user)
++        username = src->ssh_user;
++
++    if (src->ssh_host_key_check_disabled &&
++        virJSONValueObjectCreate(&host_key_check,
++                                 "s:mode", "none",
++                                 NULL) < 0)
++        return NULL;
+ 
+     if (virJSONValueObjectCreate(&ret,
+                                  "s:path", src->path,
+                                  "a:server", &serverprops,
+                                  "S:user", username,
++                                 "A:host-key-check", &host_key_check,
+                                  NULL) < 0)
+         return NULL;
+ 
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 9eca186e99..ce126f5cba 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2464,6 +2464,10 @@ virStorageSourceCopy(const virStorageSource *src,
+             return NULL;
+     }
+ 
++    /* ssh config passthrough for libguestfs */
++    def->ssh_host_key_check_disabled = src->ssh_host_key_check_disabled;
++    def->ssh_user = g_strdup(src->ssh_user);
++
+     return g_steal_pointer(&def);
+ }
+ 
+@@ -2705,6 +2709,8 @@ virStorageSourceClear(virStorageSourcePtr def)
+     VIR_FREE(def->tlsAlias);
+     VIR_FREE(def->tlsCertdir);
+ 
++    VIR_FREE(def->ssh_user);
++
+     virStorageSourceInitiatorClear(&def->initiator);
+ 
+     /* clear everything except the class header as the object APIs
+@@ -3635,6 +3641,8 @@ virStorageSourceParseBackingJSONSSH(virStorageSourcePtr src,
+     const char *path = virJSONValueObjectGetString(json, "path");
+     const char *host = virJSONValueObjectGetString(json, "host");
+     const char *port = virJSONValueObjectGetString(json, "port");
++    const char *user = virJSONValueObjectGetString(json, "user");
++    const char *host_key_check = virJSONValueObjectGetString(json, "host_key_check");
+     virJSONValuePtr server = virJSONValueObjectGetObject(json, "server");
+ 
+     if (!(host || server) || !path) {
+@@ -3665,6 +3673,11 @@ virStorageSourceParseBackingJSONSSH(virStorageSourcePtr src,
+             return -1;
+     }
+ 
++    /* these two are parsed just to be passed back as we don't model them yet */
++    src->ssh_user = g_strdup(user);
++    if (STREQ_NULLABLE(host_key_check, "no"))
++        src->ssh_host_key_check_disabled = true;
++
+     return 0;
+ }
+ 
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 1abdaf89ce..c1430cadd1 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -385,6 +385,11 @@ struct _virStorageSource {
+                        as a source for floppy drive */
+ 
+     bool hostcdrom; /* backing device is a cdrom */
++
++    /* passthrough variables for the ssh driver which we don't handle properly */
++    /* these must not be used apart from formatting the output JSON in the qemu driver */
++    char *ssh_user;
++    bool ssh_host_key_check_disabled;
+ };
+ 
+ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref);
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index d8bd811b4d..f48875e16d 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1132,6 +1132,7 @@ mymain(void)
+     jsontojsondata.schemaroot = qmp_schemaroot_x86_64_blockdev_add;
+ 
+     TEST_JSON_TO_JSON("curl-libguestfs");
++    TEST_JSON_TO_JSON("ssh-passthrough-libguestfs");
+ 
+ #define TEST_IMAGE_CREATE(testname, testbacking) \
+     do { \
+diff --git a/tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-in.json b/tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-in.json
+new file mode 100644
+index 0000000000..da8fedef07
+--- /dev/null
++++ b/tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-in.json
+@@ -0,0 +1 @@
++json:{"file.driver":"ssh","file.user":"testuser","file.host":"random.host","file.port":1234,"file.path":"somewhere/something","file.host_key_check":"no"}
+diff --git a/tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-out.json b/tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-out.json
+new file mode 100644
+index 0000000000..1f6032deb4
+--- /dev/null
++++ b/tests/qemublocktestdata/jsontojson/ssh-passthrough-libguestfs-out.json
+@@ -0,0 +1,14 @@
++{
++  "driver": "ssh",
++  "path": "somewhere/something",
++  "server": {
++    "host": "random.host",
++    "port": "22"
++  },
++  "user": "testuser",
++  "host-key-check": {
++    "mode": "none"
++  },
++  "auto-read-only": true,
++  "discard": "unmap"
++}
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Split-out-initialization-of-secrets-for-iscsi-hostdevs.patch b/SOURCES/libvirt-qemu-Split-out-initialization-of-secrets-for-iscsi-hostdevs.patch
new file mode 100644
index 0000000..dd245ad
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Split-out-initialization-of-secrets-for-iscsi-hostdevs.patch
@@ -0,0 +1,80 @@
+From 1c5d21527ce3cb5182434d206d589a85b1901b42 Mon Sep 17 00:00:00 2001
+Message-Id: <1c5d21527ce3cb5182434d206d589a85b1901b42@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:52 +0100
+Subject: [PATCH] qemu: Split out initialization of secrets for 'iscsi'
+ hostdevs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently we don't have infrastructure to remember the secret aliases
+for hostdevs. Since an upcoming patch is going to change aliases for
+the disks, initialize the iscsi hostdevs separately so that we can keep
+the alias. At the same time let's use qemuAliasForSecret instead of
+qemuDomainGetSecretAESAlias when unplugging the iscsi hostdev.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 740dd1a4e5ce81e5b0be855dd413dd7eec81ccd3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <f4157def83aa59b7432c6e0714d621ff5b2bed4a.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c  | 25 +++++++++++++++++++++++--
+ src/qemu/qemu_hotplug.c |  2 +-
+ 2 files changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 897e21726a..0047a1d316 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1848,8 +1848,29 @@ qemuDomainSecretHostdevPrepare(qemuDomainObjPrivatePtr priv,
+ 
+         if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI &&
+             src->auth) {
+-            if (qemuDomainSecretStorageSourcePrepare(priv, src,
+-                                                     hostdev->info->alias, NULL) < 0)
++            bool iscsiHasPS = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_ISCSI_PASSWORD_SECRET);
++            virSecretUsageType usageType = VIR_SECRET_USAGE_TYPE_ISCSI;
++            qemuDomainStorageSourcePrivatePtr srcPriv;
++
++            if (!(src->privateData = qemuDomainStorageSourcePrivateNew()))
++                return -1;
++
++            srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
++
++            if (!qemuDomainSupportsEncryptedSecret(priv) || !iscsiHasPS) {
++                srcPriv->secinfo = qemuDomainSecretInfoNewPlain(usageType,
++                                                                src->auth->username,
++                                                                &src->auth->seclookupdef);
++            } else {
++                srcPriv->secinfo = qemuDomainSecretAESSetupFromSecret(priv,
++                                                                      hostdev->info->alias,
++                                                                      usageType,
++                                                                      src->auth->username,
++                                                                      &src->auth->seclookupdef,
++                                                                      false);
++            }
++
++            if (!srcPriv->secinfo)
+                 return -1;
+         }
+     }
+diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
+index 12bc1f9dd5..a473bab3e1 100644
+--- a/src/qemu/qemu_hotplug.c
++++ b/src/qemu/qemu_hotplug.c
+@@ -4438,7 +4438,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
+         if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI &&
+             virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_ISCSI_PASSWORD_SECRET) &&
+             qemuDomainStorageSourceHasAuth(iscsisrc->src)) {
+-            if (!(objAlias = qemuDomainGetSecretAESAlias(hostdev->info->alias, false)))
++            if (!(objAlias = qemuAliasForSecret(hostdev->info->alias, NULL)))
+                 return -1;
+         }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Stop-domain-on-failed-restore.patch b/SOURCES/libvirt-qemu-Stop-domain-on-failed-restore.patch
new file mode 100644
index 0000000..fd54a23
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Stop-domain-on-failed-restore.patch
@@ -0,0 +1,107 @@
+From 84c5cad5921e96c6106cfd217de2064b64e1464f Mon Sep 17 00:00:00 2001
+Message-Id: <84c5cad5921e96c6106cfd217de2064b64e1464f@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Thu, 16 Jan 2020 10:03:54 +0100
+Subject: [PATCH] qemu: Stop domain on failed restore
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When resuming a domain from a save file, we read the domain XML
+from the file, add it onto our internal list of domains, start
+the qemu process, let it load the incoming migration stream and
+resume its vCPUs afterwards. If anything goes wrong, the domain
+object is removed from the list of domains and error is returned
+to the caller. However, the qemu process might be left behind -
+if resuming vCPUs fails (e.g. because qemu is unable to acquire
+write lock on a disk) then due to a bug the qemu process is not
+killed but the domain object is removed from the list.
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1718707
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 4c581527d431939a63be70c201b4ddab703cddbe)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <4048f92488a8b8c31c7a17a14b579840a9492328.1579165329.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index ce9b1772c1..217d873671 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -6800,7 +6800,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     int ret = -1;
+-    bool restored = false;
++    bool started = false;
+     virObjectEventPtr event;
+     VIR_AUTOCLOSE intermediatefd = -1;
+     g_autoptr(virCommand) cmd = NULL;
+@@ -6808,6 +6808,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+     virQEMUSaveHeaderPtr header = &data->header;
+     g_autoptr(qemuDomainSaveCookie) cookie = NULL;
++    int rc = 0;
+ 
+     if (virSaveCookieParseString(data->cookie, (virObjectPtr *)&cookie,
+                                  virDomainXMLOptionGetSaveCookie(driver->xmlopt)) < 0)
+@@ -6848,12 +6849,12 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+                          VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
+                          VIR_QEMU_PROCESS_START_PAUSED |
+                          VIR_QEMU_PROCESS_START_GEN_VMID) == 0)
+-        restored = true;
++        started = true;
+ 
+     if (intermediatefd != -1) {
+         virErrorPtr orig_err = NULL;
+ 
+-        if (!restored) {
++        if (!started) {
+             /* if there was an error setting up qemu, the intermediate
+              * process will wait forever to write to stdout, so we
+              * must manually kill it and ignore any error related to
+@@ -6864,21 +6865,17 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+             VIR_FORCE_CLOSE(*fd);
+         }
+ 
+-        if (virCommandWait(cmd, NULL) < 0) {
+-            qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, asyncJob, 0);
+-            restored = false;
+-        }
++        rc = virCommandWait(cmd, NULL);
+         VIR_DEBUG("Decompression binary stderr: %s", NULLSTR(errbuf));
+-
+         virErrorRestore(&orig_err);
+     }
+     if (VIR_CLOSE(*fd) < 0) {
+         virReportSystemError(errno, _("cannot close file: %s"), path);
+-        restored = false;
++        rc = -1;
+     }
+ 
+-    virDomainAuditStart(vm, "restored", restored);
+-    if (!restored)
++    virDomainAuditStart(vm, "restored", started);
++    if (!started || rc < 0)
+         goto cleanup;
+ 
+     /* qemuProcessStart doesn't unset the qemu error reporting infrastructure
+@@ -6918,6 +6915,10 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+     ret = 0;
+ 
+  cleanup:
++    if (ret < 0 && started) {
++        qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED,
++                        asyncJob, VIR_QEMU_PROCESS_STOP_MIGRATED);
++    }
+     if (qemuSecurityRestoreSavedStateLabel(driver, vm, path) < 0)
+         VIR_WARN("failed to restore save state label on %s", path);
+     return ret;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Tell-secdrivers-which-images-are-top-parent.patch b/SOURCES/libvirt-qemu-Tell-secdrivers-which-images-are-top-parent.patch
new file mode 100644
index 0000000..4e7ec99
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Tell-secdrivers-which-images-are-top-parent.patch
@@ -0,0 +1,312 @@
+From d9369eae049c780ebd130a13eedfaaf3586242eb Mon Sep 17 00:00:00 2001
+Message-Id: <d9369eae049c780ebd130a13eedfaaf3586242eb@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Mon, 9 Mar 2020 14:58:57 +0100
+Subject: [PATCH] qemu: Tell secdrivers which images are top parent
+
+When preparing images for block jobs we modify their seclabels so
+that QEMU can open them. However, as mentioned in the previous
+commit, secdrivers base some it their decisions whether the image
+they are working on is top of of the backing chain. Fortunately,
+in places where we call secdrivers we know this and the
+information can be passed to secdrivers.
+
+The problem is the following: after the first blockcommit from
+the base to one of the parents the XATTRs on the base image are
+not cleared and therefore the second attempt to do another
+blockcommit fails. This is caused by blockcommit code calling
+qemuSecuritySetImageLabel() over the base image, possibly
+multiple times (to ensure RW/RO access). A naive fix would be to
+call the restore function. But this is not possible, because that
+would deny QEMU the access to the base image.  Fortunately, we
+can use the fact that seclabels are remembered only for the top
+of the backing chain and not for the rest of the backing chain.
+And thanks to the previous commit we can tell secdrivers which
+images are top of the backing chain.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1803551
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 13eb6c14682004d0dc692554475125db0f161da7)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <a8d9171d9f88b325480c17969e074d62d3eeba3b.1583760062.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_backup.c     |  4 ++--
+ src/qemu/qemu_blockjob.c   |  6 ++++--
+ src/qemu/qemu_checkpoint.c |  6 ++++--
+ src/qemu/qemu_domain.c     | 24 ++++++++++++++++++++----
+ src/qemu/qemu_domain.h     |  3 ++-
+ src/qemu/qemu_driver.c     | 23 +++++++++++++++++------
+ src/qemu/qemu_process.c    |  2 +-
+ src/qemu/qemu_security.c   |  6 +++++-
+ src/qemu/qemu_security.h   |  3 ++-
+ 9 files changed, 57 insertions(+), 20 deletions(-)
+
+diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
+index 2cc6ff7a42..8b66ee8d1f 100644
+--- a/src/qemu/qemu_backup.c
++++ b/src/qemu/qemu_backup.c
+@@ -469,8 +469,8 @@ qemuBackupDiskPrepareOneStorage(virDomainObjPtr vm,
+         dd->created = true;
+     }
+ 
+-    if (qemuDomainStorageSourceAccessAllow(priv->driver, vm, dd->store, false,
+-                                           true) < 0)
++    if (qemuDomainStorageSourceAccessAllow(priv->driver, vm, dd->store,
++                                           false, true, true) < 0)
+         return -1;
+ 
+     dd->labelled = true;
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index 71df0d1ab2..e894e1634d 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -1105,9 +1105,11 @@ qemuBlockJobProcessEventCompletedCommit(virQEMUDriverPtr driver,
+         return;
+ 
+     /* revert access to images */
+-    qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.base, true, false);
++    qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.base,
++                                       true, false, false);
+     if (job->data.commit.topparent != job->disk->src)
+-        qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.topparent, true, false);
++        qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.topparent,
++                                           true, false, true);
+ 
+     baseparent->backingStore = NULL;
+     job->data.commit.topparent->backingStore = job->data.commit.base;
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index c06bfe6a21..fe54af74ec 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -298,7 +298,8 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+     for (next = reopenimages; next; next = next->next) {
+         virStorageSourcePtr src = next->data;
+ 
+-        if (qemuDomainStorageSourceAccessAllow(driver, vm, src, false, false) < 0)
++        if (qemuDomainStorageSourceAccessAllow(driver, vm, src,
++                                               false, false, false) < 0)
+             goto relabel;
+ 
+         relabelimages = g_slist_prepend(relabelimages, src);
+@@ -313,7 +314,8 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+     for (next = relabelimages; next; next = next->next) {
+         virStorageSourcePtr src = next->data;
+ 
+-        ignore_value(qemuDomainStorageSourceAccessAllow(driver, vm, src, true, false));
++        ignore_value(qemuDomainStorageSourceAccessAllow(driver, vm, src,
++                                                        true, false, false));
+     }
+ 
+     return rc;
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 3cbe7ef6e1..14bab896bc 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -11770,6 +11770,8 @@ typedef enum {
+     QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_SKIP_REVOKE = 1 << 4,
+     /* VM already has access to the source and we are just modifying it */
+     QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_MODIFY_ACCESS = 1 << 5,
++    /* whether the image is the top image of the backing chain (e.g. disk source) */
++    QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN_TOP = 1 << 6,
+ } qemuDomainStorageSourceAccessFlags;
+ 
+ 
+@@ -11847,6 +11849,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriverPtr driver,
+     bool force_ro = flags & QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_FORCE_READ_ONLY;
+     bool force_rw = flags & QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_FORCE_READ_WRITE;
+     bool revoke = flags & QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_REVOKE;
++    bool chain_top = flags & QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN_TOP;
+     int rc;
+     bool was_readonly = src->readonly;
+     bool revoke_cgroup = false;
+@@ -11893,7 +11896,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriverPtr driver,
+         revoke_namespace = true;
+     }
+ 
+-    if (qemuSecuritySetImageLabel(driver, vm, src, chain) < 0)
++    if (qemuSecuritySetImageLabel(driver, vm, src, chain, chain_top) < 0)
+         goto revoke;
+ 
+     revoke_label = true;
+@@ -11956,7 +11959,8 @@ qemuDomainStorageSourceChainAccessAllow(virQEMUDriverPtr driver,
+                                         virDomainObjPtr vm,
+                                         virStorageSourcePtr src)
+ {
+-    qemuDomainStorageSourceAccessFlags flags = QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN;
++    qemuDomainStorageSourceAccessFlags flags = QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN |
++                                               QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN_TOP;
+ 
+     return qemuDomainStorageSourceAccessModify(driver, vm, src, flags);
+ }
+@@ -11968,7 +11972,8 @@ qemuDomainStorageSourceChainAccessRevoke(virQEMUDriverPtr driver,
+                                          virStorageSourcePtr src)
+ {
+     qemuDomainStorageSourceAccessFlags flags = QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_REVOKE |
+-                                               QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN;
++                                               QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN |
++                                               QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN_TOP;
+ 
+     return qemuDomainStorageSourceAccessModify(driver, vm, src, flags);
+ }
+@@ -11998,6 +12003,7 @@ qemuDomainStorageSourceAccessRevoke(virQEMUDriverPtr driver,
+  * @elem: source structure to set access for
+  * @readonly: setup read-only access if true
+  * @newSource: @elem describes a storage source which @vm can't access yet
++ * @chainTop: @elem is top parent of backing chain
+  *
+  * Allow a VM access to a single element of a disk backing chain; this helper
+  * ensures that the lock manager, cgroup device controller, and security manager
+@@ -12005,13 +12011,20 @@ qemuDomainStorageSourceAccessRevoke(virQEMUDriverPtr driver,
+  *
+  * When modifying permissions of @elem which @vm can already access (is in the
+  * backing chain) @newSource needs to be set to false.
++ *
++ * The @chainTop flag must be set if the @elem image is the topmost image of a
++ * given backing chain or meant to become the topmost image (for e.g.
++ * snapshots, or blockcopy or even in the end for active layer block commit,
++ * where we discard the top of the backing chain so one of the intermediates
++ * (the base) becomes the top of the chain).
+  */
+ int
+ qemuDomainStorageSourceAccessAllow(virQEMUDriverPtr driver,
+                                    virDomainObjPtr vm,
+                                    virStorageSourcePtr elem,
+                                    bool readonly,
+-                                   bool newSource)
++                                   bool newSource,
++                                   bool chainTop)
+ {
+     qemuDomainStorageSourceAccessFlags flags = QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_SKIP_REVOKE;
+ 
+@@ -12023,6 +12036,9 @@ qemuDomainStorageSourceAccessAllow(virQEMUDriverPtr driver,
+     if (!newSource)
+         flags |= QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_MODIFY_ACCESS;
+ 
++    if (chainTop)
++        flags |= QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_CHAIN_TOP;
++
+     return qemuDomainStorageSourceAccessModify(driver, vm, elem, flags);
+ }
+ 
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index 83150e4e6d..9d143b575d 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -895,7 +895,8 @@ int qemuDomainStorageSourceAccessAllow(virQEMUDriverPtr driver,
+                                        virDomainObjPtr vm,
+                                        virStorageSourcePtr elem,
+                                        bool readonly,
+-                                       bool newSource);
++                                       bool newSource,
++                                       bool chainTop);
+ 
+ int qemuDomainPrepareStorageSourceBlockdev(virDomainDiskDefPtr disk,
+                                            virStorageSourcePtr src,
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index d346446444..26f100177b 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15467,7 +15467,8 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver,
+     }
+ 
+     /* set correct security, cgroup and locking options on the new image */
+-    if (qemuDomainStorageSourceAccessAllow(driver, vm, dd->src, false, true) < 0)
++    if (qemuDomainStorageSourceAccessAllow(driver, vm, dd->src,
++                                           false, true, true) < 0)
+         return -1;
+ 
+     dd->prepared = true;
+@@ -18815,11 +18816,19 @@ qemuDomainBlockCommit(virDomainPtr dom,
+      * operation succeeds, but doing that requires tracking the
+      * operation in XML across libvirtd restarts.  */
+     clean_access = true;
+-    if (qemuDomainStorageSourceAccessAllow(driver, vm, baseSource, false, false) < 0 ||
+-        (top_parent && top_parent != disk->src &&
+-         qemuDomainStorageSourceAccessAllow(driver, vm, top_parent, false, false) < 0))
++    if (qemuDomainStorageSourceAccessAllow(driver, vm, baseSource,
++                                           false, false, false) < 0)
+         goto endjob;
+ 
++    if (top_parent && top_parent != disk->src) {
++        /* While top_parent is topmost image, we don't need to remember its
++         * owner as it will be overwritten upon finishing the commit. Hence,
++         * pass chainTop = false. */
++        if (qemuDomainStorageSourceAccessAllow(driver, vm, top_parent,
++                                               false, false, false) < 0)
++            goto endjob;
++    }
++
+     if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
+                                           baseSource,
+                                           flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
+@@ -18877,9 +18886,11 @@ qemuDomainBlockCommit(virDomainPtr dom,
+         virErrorPtr orig_err;
+         virErrorPreserveLast(&orig_err);
+         /* Revert access to read-only, if possible.  */
+-        qemuDomainStorageSourceAccessAllow(driver, vm, baseSource, true, false);
++        qemuDomainStorageSourceAccessAllow(driver, vm, baseSource,
++                                           true, false, false);
+         if (top_parent && top_parent != disk->src)
+-            qemuDomainStorageSourceAccessAllow(driver, vm, top_parent, true, false);
++            qemuDomainStorageSourceAccessAllow(driver, vm, top_parent,
++                                               true, false, false);
+ 
+         virErrorRestore(&orig_err);
+     }
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 0476f18517..dffff04554 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -7823,7 +7823,7 @@ qemuProcessRefreshLegacyBlockjob(void *payload,
+                 (qemuDomainNamespaceSetupDisk(vm, disk->mirror) < 0 ||
+                  qemuSetupImageChainCgroup(vm, disk->mirror) < 0 ||
+                  qemuSecuritySetImageLabel(priv->driver, vm, disk->mirror,
+-                                           true) < 0))
++                                           true, true) < 0))
+                 goto cleanup;
+         }
+     }
+diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c
+index 2aa2b5b9c6..484fc34552 100644
+--- a/src/qemu/qemu_security.c
++++ b/src/qemu/qemu_security.c
+@@ -98,7 +98,8 @@ int
+ qemuSecuritySetImageLabel(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virStorageSourcePtr src,
+-                          bool backingChain)
++                          bool backingChain,
++                          bool chainTop)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     pid_t pid = -1;
+@@ -108,6 +109,9 @@ qemuSecuritySetImageLabel(virQEMUDriverPtr driver,
+     if (backingChain)
+         labelFlags |= VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN;
+ 
++    if (chainTop)
++        labelFlags |= VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
++
+     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
+         pid = vm->pid;
+ 
+diff --git a/src/qemu/qemu_security.h b/src/qemu/qemu_security.h
+index a8c648ece1..c8516005ac 100644
+--- a/src/qemu/qemu_security.h
++++ b/src/qemu/qemu_security.h
+@@ -36,7 +36,8 @@ void qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
+ int qemuSecuritySetImageLabel(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               virStorageSourcePtr src,
+-                              bool backingChain);
++                              bool backingChain,
++                              bool chainTop);
+ 
+ int qemuSecurityRestoreImageLabel(virQEMUDriverPtr driver,
+                                   virDomainObjPtr vm,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-Use-g_autoptr-for-qemuDomainSaveCookie.patch b/SOURCES/libvirt-qemu-Use-g_autoptr-for-qemuDomainSaveCookie.patch
new file mode 100644
index 0000000..b4ca4f7
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Use-g_autoptr-for-qemuDomainSaveCookie.patch
@@ -0,0 +1,146 @@
+From c5cdebd40024c33675f93b47732869c658204056 Mon Sep 17 00:00:00 2001
+Message-Id: <c5cdebd40024c33675f93b47732869c658204056@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Thu, 16 Jan 2020 10:03:53 +0100
+Subject: [PATCH] qemu: Use g_autoptr() for qemuDomainSaveCookie
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1718707
+
+(cherry picked from commit 3203ad6cfd617fb11d4bb47e514c370b6624641b)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <5e58b5853f9bd1a2b5109145afdad190071f5c44.1579165329.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 28 ++++++++++------------------
+ src/qemu/qemu_domain.h |  1 +
+ src/qemu/qemu_driver.c |  6 ++----
+ 3 files changed, 13 insertions(+), 22 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 0edf316fff..91a9f0481b 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -16001,27 +16001,23 @@ qemuDomainSaveCookiePtr
+ qemuDomainSaveCookieNew(virDomainObjPtr vm)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+-    qemuDomainSaveCookiePtr cookie = NULL;
++    g_autoptr(qemuDomainSaveCookie) cookie = NULL;
+ 
+     if (qemuDomainInitialize() < 0)
+-        goto error;
++        return NULL;
+ 
+     if (!(cookie = virObjectNew(qemuDomainSaveCookieClass)))
+-        goto error;
++        return NULL;
+ 
+     if (priv->origCPU && !(cookie->cpu = virCPUDefCopy(vm->def->cpu)))
+-        goto error;
++        return NULL;
+ 
+     cookie->slirpHelper = qemuDomainGetSlirpHelperOk(vm);
+ 
+     VIR_DEBUG("Save cookie %p, cpu=%p, slirpHelper=%d",
+               cookie, cookie->cpu, cookie->slirpHelper);
+ 
+-    return cookie;
+-
+- error:
+-    virObjectUnref(cookie);
+-    return NULL;
++    return g_steal_pointer(&cookie);
+ }
+ 
+ 
+@@ -16029,26 +16025,22 @@ static int
+ qemuDomainSaveCookieParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED,
+                           virObjectPtr *obj)
+ {
+-    qemuDomainSaveCookiePtr cookie = NULL;
++    g_autoptr(qemuDomainSaveCookie) cookie = NULL;
+ 
+     if (qemuDomainInitialize() < 0)
+-        goto error;
++        return -1;
+ 
+     if (!(cookie = virObjectNew(qemuDomainSaveCookieClass)))
+-        goto error;
++        return -1;
+ 
+     if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST,
+                           &cookie->cpu) < 0)
+-        goto error;
++        return -1;
+ 
+     cookie->slirpHelper = virXPathBoolean("boolean(./slirpHelper)", ctxt) > 0;
+ 
+-    *obj = (virObjectPtr) cookie;
++    *obj = (virObjectPtr) g_steal_pointer(&cookie);
+     return 0;
+-
+- error:
+-    virObjectUnref(cookie);
+-    return -1;
+ }
+ 
+ 
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index c6afc484f6..60b80297fa 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -610,6 +610,7 @@ struct _qemuDomainSaveCookie {
+     bool slirpHelper;
+ };
+ 
++G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainSaveCookie, virObjectUnref);
+ 
+ typedef struct _qemuDomainXmlNsDef qemuDomainXmlNsDef;
+ typedef qemuDomainXmlNsDef *qemuDomainXmlNsDefPtr;
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index e1c0550b9a..ce9b1772c1 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -3293,7 +3293,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver,
+     virObjectEventPtr event = NULL;
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     virQEMUSaveDataPtr data = NULL;
+-    qemuDomainSaveCookiePtr cookie = NULL;
++    g_autoptr(qemuDomainSaveCookie) cookie = NULL;
+ 
+     if (!qemuMigrationSrcIsAllowed(driver, vm, false, 0))
+         goto cleanup;
+@@ -3399,7 +3399,6 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver,
+         qemuDomainRemoveInactiveJob(driver, vm);
+ 
+  cleanup:
+-    virObjectUnref(cookie);
+     virQEMUSaveDataFree(data);
+     virObjectEventStateQueue(driver->domainEventState, event);
+     return ret;
+@@ -6808,7 +6807,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+     g_autofree char *errbuf = NULL;
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+     virQEMUSaveHeaderPtr header = &data->header;
+-    qemuDomainSaveCookiePtr cookie = NULL;
++    g_autoptr(qemuDomainSaveCookie) cookie = NULL;
+ 
+     if (virSaveCookieParseString(data->cookie, (virObjectPtr *)&cookie,
+                                  virDomainXMLOptionGetSaveCookie(driver->xmlopt)) < 0)
+@@ -6919,7 +6918,6 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+     ret = 0;
+ 
+  cleanup:
+-    virObjectUnref(cookie);
+     if (qemuSecurityRestoreSavedStateLabel(driver, vm, path) < 0)
+         VIR_WARN("failed to restore save state label on %s", path);
+     return ret;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Use-switch-statement-in-qemuBuildCpuCommandLine.patch b/SOURCES/libvirt-qemu-Use-switch-statement-in-qemuBuildCpuCommandLine.patch
new file mode 100644
index 0000000..450a974
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Use-switch-statement-in-qemuBuildCpuCommandLine.patch
@@ -0,0 +1,74 @@
+From 67198a38ee3bce9ff19a8c80a593724d684d966e Mon Sep 17 00:00:00 2001
+Message-Id: <67198a38ee3bce9ff19a8c80a593724d684d966e@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 13:12:33 +0100
+Subject: [PATCH] qemu: Use switch statement in qemuBuildCpuCommandLine()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Make sure we are taking all possible virDomainTimerNameType values
+into account. This will make upcoming changes easier.
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit f8e923c1ba70d7be53ea18d9b4de040763347f9e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214121237.623948-3-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_command.c | 34 ++++++++++++++++++++++++----------
+ 1 file changed, 24 insertions(+), 10 deletions(-)
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index d144855b0d..0ad09baa1d 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -6616,16 +6616,30 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
+     for (i = 0; i < def->clock.ntimers; i++) {
+         virDomainTimerDefPtr timer = def->clock.timers[i];
+ 
+-        if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK &&
+-            timer->present != -1) {
+-            qemuBuildCpuFeature(qemuCaps, &buf, "kvmclock",
+-                                !!timer->present);
+-        } else if (timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK &&
+-                   timer->present == 1) {
+-            virBufferAddLit(&buf, ",hv-time");
+-        } else if (timer->name == VIR_DOMAIN_TIMER_NAME_TSC &&
+-                   timer->frequency > 0) {
+-            virBufferAsprintf(&buf, ",tsc-frequency=%lu", timer->frequency);
++        switch ((virDomainTimerNameType)timer->name) {
++        case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
++            if (timer->present != -1) {
++                qemuBuildCpuFeature(qemuCaps, &buf, "kvmclock",
++                                    !!timer->present);
++            }
++            break;
++        case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
++            if (timer->present == 1)
++                virBufferAddLit(&buf, ",hv-time");
++            break;
++        case VIR_DOMAIN_TIMER_NAME_TSC:
++            if (timer->frequency > 0)
++                virBufferAsprintf(&buf, ",tsc-frequency=%lu", timer->frequency);
++            break;
++        case VIR_DOMAIN_TIMER_NAME_PLATFORM:
++        case VIR_DOMAIN_TIMER_NAME_PIT:
++        case VIR_DOMAIN_TIMER_NAME_RTC:
++        case VIR_DOMAIN_TIMER_NAME_HPET:
++            break;
++        case VIR_DOMAIN_TIMER_NAME_LAST:
++        default:
++            virReportEnumRangeError(virDomainTimerNameType, timer->name);
++            return -1;
+         }
+     }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-Validate-configuration-for-the-armvtimer-timer.patch b/SOURCES/libvirt-qemu-Validate-configuration-for-the-armvtimer-timer.patch
new file mode 100644
index 0000000..86f5cd4
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Validate-configuration-for-the-armvtimer-timer.patch
@@ -0,0 +1,78 @@
+From 8152b6ac3b740bfe1155e3c4c251684cc5b3192e Mon Sep 17 00:00:00 2001
+Message-Id: <8152b6ac3b740bfe1155e3c4c251684cc5b3192e@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 13:12:36 +0100
+Subject: [PATCH] qemu: Validate configuration for the armvtimer timer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Its use is limited to certain guest types, and it only supports
+a subset of all possible tick policies.
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit aeddab230cd1e2a12d5d6352971bb70ea067a1c4)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214121237.623948-6-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 4de4f9da53..1bed117eb0 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -5506,6 +5506,44 @@ qemuDomainDefValidateClockTimers(const virDomainDef *def,
+             break;
+ 
+         case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
++            if (def->virtType != VIR_DOMAIN_VIRT_KVM ||
++                !qemuDomainIsARMVirt(def)) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                               _("Configuring the '%s' timer is not supported "
++                                 "for virtType=%s arch=%s machine=%s guests"),
++                               virDomainTimerNameTypeToString(timer->name),
++                               virDomainVirtTypeToString(def->virtType),
++                               virArchToString(def->os.arch),
++                               def->os.machine);
++                return -1;
++            }
++            if (timer->present == 0) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                               _("The '%s' timer can't be disabled"),
++                               virDomainTimerNameTypeToString(timer->name));
++                return -1;
++            }
++            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_KVM_NO_ADJVTIME)) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                               _("Configuring the '%s' timer is not supported "
++                                 "with this QEMU binary"),
++                               virDomainTimerNameTypeToString(timer->name));
++                return -1;
++            }
++
++            switch (timer->tickpolicy) {
++            case -1:
++            case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
++            case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
++                break;
++            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
++            case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                               _("The '%s' timer does not support tickpolicy '%s'"),
++                               virDomainTimerNameTypeToString(timer->name),
++                               virDomainTimerTickpolicyTypeToString(timer->tickpolicy));
++                return -1;
++            }
+             break;
+         }
+     }
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-add-QEMU_CAPS_DEVICE_VHOST_USER_FS.patch b/SOURCES/libvirt-qemu-add-QEMU_CAPS_DEVICE_VHOST_USER_FS.patch
new file mode 100644
index 0000000..3614dd4
--- /dev/null
+++ b/SOURCES/libvirt-qemu-add-QEMU_CAPS_DEVICE_VHOST_USER_FS.patch
@@ -0,0 +1,122 @@
+From e6a402520fef59636ede2d24249ae6b4fe45ac60 Mon Sep 17 00:00:00 2001
+Message-Id: <e6a402520fef59636ede2d24249ae6b4fe45ac60@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:39 +0100
+Subject: [PATCH] qemu: add QEMU_CAPS_DEVICE_VHOST_USER_FS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduced by QEMU commit 98fc1ada4cf70af0f1df1a2d7183cf786fc7da05
+    virtio: add vhost-user-fs base device
+
+Released in QEMU v4.2.0.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit d99128a62b9f84e3e5b372d1e6419f4f1d1dffe6)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+
+Conflicts: * different set of capabilities available downstream:
+    src/qemu/qemu_capabilities.c
+    tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
+  * missing downstream:
+    tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <2450cfcd270e664a9832a82367787b6cdfc2c6fa.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_capabilities.c                      | 2 ++
+ src/qemu/qemu_capabilities.h                      | 1 +
+ tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml | 1 +
+ tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml   | 1 +
+ tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml  | 1 +
+ tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml | 1 +
+ 6 files changed, 7 insertions(+)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 6912a6f72b..34df4d89b3 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -558,6 +558,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
+               /* 350 */
+               "virtio-net.failover",
+               "cpu.kvm-no-adjvtime",
++              "vhost-user-fs",
+     );
+ 
+ 
+@@ -1272,6 +1273,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
+     { "vhost-user-vga", QEMU_CAPS_DEVICE_VHOST_USER_VGA },
+     { "ramfb", QEMU_CAPS_DEVICE_RAMFB },
+     { "max-arm-cpu", QEMU_CAPS_ARM_MAX_CPU },
++    { "vhost-user-fs-device", QEMU_CAPS_DEVICE_VHOST_USER_FS },
+ };
+ 
+ static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = {
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index 4ccb0c55bc..e3449a9ca3 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -539,6 +539,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+     /* 350 */
+     QEMU_CAPS_VIRTIO_NET_FAILOVER, /* virtio-net-*.failover */
+     QEMU_CAPS_CPU_KVM_NO_ADJVTIME, /* cpu.kvm-no-adjvtime */
++    QEMU_CAPS_DEVICE_VHOST_USER_FS, /* -device vhost-user-fs */
+ 
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+index 6af09e1a83..55fa169d89 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+@@ -177,6 +177,7 @@
+   <flag name='drive-nvme'/>
+   <flag name='smp-dies'/>
+   <flag name='virtio-net.failover'/>
++  <flag name='vhost-user-fs'/>
+   <version>4001050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>61700242</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
+index c8746f05ef..49963b7020 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
+@@ -136,6 +136,7 @@
+   <flag name='blockdev-file-dynamic-auto-read-only'/>
+   <flag name='drive-nvme'/>
+   <flag name='smp-dies'/>
++  <flag name='vhost-user-fs'/>
+   <version>4001050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>39100242</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+index c71791e205..ed3dea23b3 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+@@ -220,6 +220,7 @@
+   <flag name='drive-nvme'/>
+   <flag name='smp-dies'/>
+   <flag name='virtio-net.failover'/>
++  <flag name='vhost-user-fs'/>
+   <version>4002000</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>43100242</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+index e871ba528e..8195da4e27 100644
+--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+@@ -179,6 +179,7 @@
+   <flag name='smp-dies'/>
+   <flag name='virtio-net.failover'/>
+   <flag name='cpu.kvm-no-adjvtime'/>
++  <flag name='vhost-user-fs'/>
+   <version>4002050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>61700241</microcodeVersion>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-add-capabilities-flag-for-failover-feature.patch b/SOURCES/libvirt-qemu-add-capabilities-flag-for-failover-feature.patch
new file mode 100644
index 0000000..454a9ea
--- /dev/null
+++ b/SOURCES/libvirt-qemu-add-capabilities-flag-for-failover-feature.patch
@@ -0,0 +1,123 @@
+From a2712d6a8ef06050b4e31d9e6e9800a4babc2cd8 Mon Sep 17 00:00:00 2001
+Message-Id: <a2712d6a8ef06050b4e31d9e6e9800a4babc2cd8@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Thu, 30 Jan 2020 14:12:39 -0500
+Subject: [PATCH] qemu: add capabilities flag for failover feature
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Presence of the virtio-net-pci option called "failover" indicates
+support in a qemu binary of a simplistic bonding of a virtio-net
+device with another PCI device. This feature allows migration of
+guests that have a network device assigned to a guest with VFIO, by
+creating a network bond device in the guest consisting of the
+VFIO-assigned device and a virtio-net-pci device, then temporarily
+(and automatically) unplugging the VFIO net device prior to migration
+(and hotplugging an equivalent device on the migration
+destination). (The feature is called "failover" because the bond
+device uses the vfio-pci netdev for normal guest networking, but
+"fails over" to the virtio-net-pci netdev once the vfio-pci device is
+unplugged for migration.)
+
+Full functioning of the feature also requires support in the
+virtio-net driver in the guest OS (since that is where the bond device
+resides), but if the "failover" commandline option is present for the
+virtio-net-pci device in qemu, at least the qemu part of the feature
+is available, and libvirt can add the proper options to both the
+virtio-net-pci and vfio-pci device commandlines to indicate qemu
+should attempt doing the failover during migration.
+
+This patch just adds the qemu capabilities flag "virtio-net.failover".
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit cad65f222f29dffd4e91d43b230665aca813c7a6)
+
+Conflicts:
+   src/qemu/qemu_capabilities.c
+   src/qemu/qemu_capabilities.h
+   tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+   tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+
+     context changed due to other capabilities flags
+     added upstream
+
+   tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
+
+     only exists upstream
+
+https://bugzilla.redhat.com/1693587
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20200130191244.24174-2-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_capabilities.c                      | 4 ++++
+ src/qemu/qemu_capabilities.h                      | 3 +++
+ tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml | 1 +
+ tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml  | 1 +
+ 4 files changed, 9 insertions(+)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 893fc5a1bb..10c17323be 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -554,6 +554,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
+               "savevm-monitor-nodes",
+               "drive-nvme",
+               "smp-dies",
++
++              /* 350 */
++              "virtio-net.failover",
+     );
+ 
+ 
+@@ -1299,6 +1302,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioNet[] = {
+     { "disable-legacy", QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY },
+     { "iommu_platform", QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM },
+     { "ats", QEMU_CAPS_VIRTIO_PCI_ATS },
++    { "failover", QEMU_CAPS_VIRTIO_NET_FAILOVER },
+ };
+ 
+ static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsSpaprPCIHostBridge[] = {
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index 5ec8901bb3..6ab0eabd3f 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -536,6 +536,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+     QEMU_CAPS_DRIVE_NVME, /* -drive file.driver=nvme */
+     QEMU_CAPS_SMP_DIES, /*  -smp dies= */
+ 
++    /* 350 */
++    QEMU_CAPS_VIRTIO_NET_FAILOVER, /* virtio-net-*.failover */
++
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+ 
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+index 184bb7ff77..6af09e1a83 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+@@ -176,6 +176,7 @@
+   <flag name='savevm-monitor-nodes'/>
+   <flag name='drive-nvme'/>
+   <flag name='smp-dies'/>
++  <flag name='virtio-net.failover'/>
+   <version>4001050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>61700242</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+index afd59a269d..c71791e205 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+@@ -219,6 +219,7 @@
+   <flag name='savevm-monitor-nodes'/>
+   <flag name='drive-nvme'/>
+   <flag name='smp-dies'/>
++  <flag name='virtio-net.failover'/>
+   <version>4002000</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>43100242</microcodeVersion>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-add-code-for-handling-virtiofsd.patch b/SOURCES/libvirt-qemu-add-code-for-handling-virtiofsd.patch
new file mode 100644
index 0000000..d80f3de
--- /dev/null
+++ b/SOURCES/libvirt-qemu-add-code-for-handling-virtiofsd.patch
@@ -0,0 +1,528 @@
+From d4f90466fc4685b72ae9ca4bae1d022c04f0e2be Mon Sep 17 00:00:00 2001
+Message-Id: <d4f90466fc4685b72ae9ca4bae1d022c04f0e2be@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:46 +0100
+Subject: [PATCH] qemu: add code for handling virtiofsd
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Start virtiofsd for each <filesystem> device using it.
+
+Pre-create the socket for communication with QEMU and pass it
+to virtiofsd.
+
+Note that virtiofsd needs to run as root.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+
+Introduced by QEMU commit a43efa34c7d7b628cbf1ec0fe60043e5c91043ea
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit f0f986efa8a8e352fbdce7079ec440a4f3c8f522)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <78ba169fbe59c5307db462ad78b65b06776d64a6.1583322091.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ po/POTFILES.in            |   1 +
+ src/qemu/Makefile.inc.am  |   2 +
+ src/qemu/qemu_domain.c    |   5 +-
+ src/qemu/qemu_domain.h    |   2 +-
+ src/qemu/qemu_extdevice.c |  20 ++-
+ src/qemu/qemu_virtiofs.c  | 301 ++++++++++++++++++++++++++++++++++++++
+ src/qemu/qemu_virtiofs.h  |  37 +++++
+ tests/qemuxml2argvtest.c  |  11 ++
+ 8 files changed, 376 insertions(+), 3 deletions(-)
+ create mode 100644 src/qemu/qemu_virtiofs.c
+ create mode 100644 src/qemu/qemu_virtiofs.h
+
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index faf173584e..29984042f4 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -169,6 +169,7 @@
+ @SRCDIR@/src/qemu/qemu_tpm.c
+ @SRCDIR@/src/qemu/qemu_vhost_user.c
+ @SRCDIR@/src/qemu/qemu_vhost_user_gpu.c
++@SRCDIR@/src/qemu/qemu_virtiofs.c
+ @SRCDIR@/src/remote/remote_daemon.c
+ @SRCDIR@/src/remote/remote_daemon_config.c
+ @SRCDIR@/src/remote/remote_daemon_dispatch.c
+diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am
+index 967f6e75a2..77786526ea 100644
+--- a/src/qemu/Makefile.inc.am
++++ b/src/qemu/Makefile.inc.am
+@@ -67,6 +67,8 @@ QEMU_DRIVER_SOURCES = \
+ 	qemu/qemu_vhost_user.h \
+ 	qemu/qemu_vhost_user_gpu.c \
+ 	qemu/qemu_vhost_user_gpu.h \
++	qemu/qemu_virtiofs.c \
++	qemu/qemu_virtiofs.h \
+ 	qemu/qemu_checkpoint.c \
+ 	qemu/qemu_checkpoint.h \
+ 	qemu/qemu_backup.c \
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 79d8de2e42..3cbe7ef6e1 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1440,8 +1440,11 @@ qemuDomainFSPrivateNew(void)
+ 
+ 
+ static void
+-qemuDomainFSPrivateDispose(void *obj G_GNUC_UNUSED)
++qemuDomainFSPrivateDispose(void *obj)
+ {
++    qemuDomainFSPrivatePtr priv = obj;
++
++    g_free(priv->vhostuser_fs_sock);
+ }
+ 
+ static virClassPtr qemuDomainVideoPrivateClass;
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index c581b3a162..83150e4e6d 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -568,7 +568,7 @@ typedef qemuDomainFSPrivate *qemuDomainFSPrivatePtr;
+ struct _qemuDomainFSPrivate {
+     virObject parent;
+ 
+-    int dummy;
++    char *vhostuser_fs_sock;
+ };
+ 
+ 
+diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
+index bb73787b8d..bfa770f45a 100644
+--- a/src/qemu/qemu_extdevice.c
++++ b/src/qemu/qemu_extdevice.c
+@@ -20,11 +20,13 @@
+ 
+ #include <config.h>
+ 
++#include "qemu_command.h"
+ #include "qemu_extdevice.h"
+ #include "qemu_vhost_user_gpu.h"
+ #include "qemu_domain.h"
+ #include "qemu_tpm.h"
+ #include "qemu_slirp.h"
++#include "qemu_virtiofs.h"
+ 
+ #include "viralloc.h"
+ #include "virlog.h"
+@@ -153,7 +155,7 @@ qemuExtDevicesCleanupHost(virQEMUDriverPtr driver,
+ int
+ qemuExtDevicesStart(virQEMUDriverPtr driver,
+                     virDomainObjPtr vm,
+-                    virLogManagerPtr logManager G_GNUC_UNUSED,
++                    virLogManagerPtr logManager,
+                     bool incomingMigration)
+ {
+     virDomainDefPtr def = vm->def;
+@@ -183,6 +185,15 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
+             return -1;
+     }
+ 
++    for (i = 0; i < def->nfss; i++) {
++        virDomainFSDefPtr fs = def->fss[i];
++
++        if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
++            if (qemuVirtioFSStart(logManager, driver, vm, fs) < 0)
++                return -1;
++        }
++    }
++
+     return 0;
+ }
+ 
+@@ -214,6 +225,13 @@ qemuExtDevicesStop(virQEMUDriverPtr driver,
+         if (slirp)
+             qemuSlirpStop(slirp, vm, driver, net, false);
+     }
++
++    for (i = 0; i < def->nfss; i++) {
++        virDomainFSDefPtr fs = def->fss[i];
++
++        if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)
++            qemuVirtioFSStop(driver, vm, fs);
++    }
+ }
+ 
+ 
+diff --git a/src/qemu/qemu_virtiofs.c b/src/qemu/qemu_virtiofs.c
+new file mode 100644
+index 0000000000..09ab2cef27
+--- /dev/null
++++ b/src/qemu/qemu_virtiofs.c
+@@ -0,0 +1,301 @@
++/*
++ * qemu_virtiofs.c: virtiofs support
++ *
++ * 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/>.
++ */
++
++#include <config.h>
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++
++#include "logging/log_manager.h"
++#include "virlog.h"
++#include "qemu_command.h"
++#include "qemu_conf.h"
++#include "qemu_extdevice.h"
++#include "qemu_security.h"
++#include "qemu_virtiofs.h"
++#include "virpidfile.h"
++#include "virqemu.h"
++#include "virutil.h"
++
++#define VIR_FROM_THIS VIR_FROM_QEMU
++
++
++char *
++qemuVirtioFSCreatePidFilename(virDomainObjPtr vm,
++                              const char *alias)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    g_autofree char *shortName = NULL;
++    g_autofree char *name = NULL;
++
++    if (!(shortName = virDomainDefGetShortName(vm->def)))
++        return NULL;
++
++    name = g_strdup_printf("%s-%s-virtiofsd", shortName, alias);
++
++    return virPidFileBuildPath(priv->libDir, name);
++}
++
++
++char *
++qemuVirtioFSCreateSocketFilename(virDomainObjPtr vm,
++                                 const char *alias)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++
++    return virFileBuildPath(priv->libDir, alias, "-virtiofsd.sock");
++}
++
++
++static char *
++qemuVirtioFSCreateLogFilename(virQEMUDriverConfigPtr cfg,
++                              const virDomainDef *def,
++                              const char *alias)
++{
++    g_autofree char *name = NULL;
++
++    name = g_strdup_printf("%s-%s", def->name, alias);
++
++    return virFileBuildPath(cfg->logDir, name, "-virtiofsd.log");
++}
++
++
++static int
++qemuVirtioFSOpenChardev(virQEMUDriverPtr driver,
++                        virDomainObjPtr vm,
++                        const char *socket_path)
++{
++    virDomainChrSourceDefPtr chrdev = virDomainChrSourceDefNew(NULL);
++    virDomainChrDef chr = { .source = chrdev };
++    VIR_AUTOCLOSE fd = -1;
++    int ret = -1;
++
++    chrdev->type = VIR_DOMAIN_CHR_TYPE_UNIX;
++    chrdev->data.nix.listen = true;
++    chrdev->data.nix.path = g_strdup(socket_path);
++
++    if (qemuSecuritySetDaemonSocketLabel(driver->securityManager, vm->def) < 0)
++        goto cleanup;
++    fd = qemuOpenChrChardevUNIXSocket(chrdev);
++    if (fd < 0) {
++        ignore_value(qemuSecurityClearSocketLabel(driver->securityManager, vm->def));
++        goto cleanup;
++    }
++    if (qemuSecurityClearSocketLabel(driver->securityManager, vm->def) < 0)
++        goto cleanup;
++
++    if (qemuSecuritySetChardevLabel(driver, vm, &chr) < 0)
++        goto cleanup;
++
++    ret = fd;
++    fd = -1;
++
++ cleanup:
++    virObjectUnref(chrdev);
++    return ret;
++}
++
++
++static virCommandPtr
++qemuVirtioFSBuildCommandLine(virQEMUDriverConfigPtr cfg,
++                             virDomainFSDefPtr fs,
++                             int *fd)
++{
++    g_autoptr(virCommand) cmd = NULL;
++    g_auto(virBuffer) opts = VIR_BUFFER_INITIALIZER;
++
++    if (!(cmd = virCommandNew(fs->binary)))
++        return NULL;
++
++    virCommandAddArgFormat(cmd, "--fd=%d", *fd);
++    virCommandPassFD(cmd, *fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
++    *fd = -1;
++
++    virCommandAddArg(cmd, "-o");
++    virBufferAddLit(&opts, "source=");
++    virQEMUBuildBufferEscapeComma(&opts, fs->src->path);
++    if (fs->cache)
++        virBufferAsprintf(&opts, ",cache=%s", virDomainFSCacheModeTypeToString(fs->cache));
++
++    if (fs->xattr == VIR_TRISTATE_SWITCH_ON)
++        virBufferAddLit(&opts, ",xattr");
++    else if (fs->xattr == VIR_TRISTATE_SWITCH_OFF)
++        virBufferAddLit(&opts, ",no_xattr");
++
++    if (fs->flock == VIR_TRISTATE_SWITCH_ON)
++        virBufferAddLit(&opts, ",flock");
++    else if (fs->flock == VIR_TRISTATE_SWITCH_OFF)
++        virBufferAddLit(&opts, ",no_flock");
++
++    if (fs->posix_lock == VIR_TRISTATE_SWITCH_ON)
++        virBufferAddLit(&opts, ",posix_lock");
++    else if (fs->posix_lock == VIR_TRISTATE_SWITCH_OFF)
++        virBufferAddLit(&opts, ",no_posix_lock");
++
++    virCommandAddArgBuffer(cmd, &opts);
++    if (cfg->virtiofsdDebug)
++        virCommandAddArg(cmd, "-d");
++
++    return g_steal_pointer(&cmd);
++}
++
++int
++qemuVirtioFSStart(virLogManagerPtr logManager,
++                  virQEMUDriverPtr driver,
++                  virDomainObjPtr vm,
++                  virDomainFSDefPtr fs)
++{
++    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
++    g_autoptr(virCommand) cmd = NULL;
++    g_autofree char *socket_path = NULL;
++    g_autofree char *pidfile = NULL;
++    g_autofree char *logpath = NULL;
++    pid_t pid = (pid_t) -1;
++    VIR_AUTOCLOSE fd = -1;
++    VIR_AUTOCLOSE logfd = -1;
++    int ret = -1;
++    int rc;
++
++    if (!virFileExists(fs->src->path)) {
++        virReportError(VIR_ERR_INTERNAL_ERROR,
++                       _("the virtiofs export directory '%s' does not exist"),
++                       fs->src->path);
++        return -1;
++    }
++
++    if (!(pidfile = qemuVirtioFSCreatePidFilename(vm, fs->info.alias)))
++        goto cleanup;
++
++    if (!(socket_path = qemuVirtioFSCreateSocketFilename(vm, fs->info.alias)))
++        goto cleanup;
++
++    if ((fd = qemuVirtioFSOpenChardev(driver, vm, socket_path)) < 0)
++        goto cleanup;
++
++    logpath = qemuVirtioFSCreateLogFilename(cfg, vm->def, fs->info.alias);
++
++    if (cfg->stdioLogD) {
++        if ((logfd = virLogManagerDomainOpenLogFile(logManager,
++                                                    "qemu",
++                                                    vm->def->uuid,
++                                                    vm->def->name,
++                                                    logpath,
++                                                    0,
++                                                    NULL, NULL)) < 0)
++            goto cleanup;
++    } else {
++        if ((logfd = open(logpath, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)) < 0) {
++            virReportSystemError(errno, _("failed to create logfile %s"),
++                                 logpath);
++            goto cleanup;
++        }
++        if (virSetCloseExec(logfd) < 0) {
++            virReportSystemError(errno, _("failed to set close-on-exec flag on %s"),
++                                 logpath);
++            goto error;
++        }
++    }
++
++    if (!(cmd = qemuVirtioFSBuildCommandLine(cfg, fs, &fd)))
++        goto cleanup;
++
++    /* so far only running as root is supported */
++    virCommandSetUID(cmd, 0);
++    virCommandSetGID(cmd, 0);
++
++    virCommandSetPidFile(cmd, pidfile);
++    virCommandSetOutputFD(cmd, &logfd);
++    virCommandSetErrorFD(cmd, &logfd);
++    virCommandNonblockingFDs(cmd);
++    virCommandDaemonize(cmd);
++
++    if (qemuExtDeviceLogCommand(driver, vm, cmd, "virtiofsd") < 0)
++        goto cleanup;
++
++    rc = virCommandRun(cmd, NULL);
++
++    if (rc < 0) {
++        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                       _("Could not start 'virtiofsd'"));
++        goto error;
++    }
++
++    rc = virPidFileReadPath(pidfile, &pid);
++    if (rc < 0) {
++        virReportSystemError(-rc,
++                             _("Unable to read virtiofsd pidfile '%s'"),
++                             pidfile);
++        goto error;
++    }
++
++    if (virProcessKill(pid, 0) != 0) {
++        virReportSystemError(errno, "%s",
++                             _("virtiofsd died unexpectedly"));
++        goto error;
++    }
++
++    QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock = g_steal_pointer(&socket_path);
++    ret = 0;
++
++ cleanup:
++    if (socket_path)
++        unlink(socket_path);
++    return ret;
++
++ error:
++    if (pid != -1)
++        virProcessKillPainfully(pid, true);
++    if (pidfile)
++        unlink(pidfile);
++    goto cleanup;
++}
++
++
++void
++qemuVirtioFSStop(virQEMUDriverPtr driver G_GNUC_UNUSED,
++                    virDomainObjPtr vm,
++                    virDomainFSDefPtr fs)
++{
++    g_autofree char *pidfile = NULL;
++    virErrorPtr orig_err;
++    pid_t pid = -1;
++    int rc;
++
++    virErrorPreserveLast(&orig_err);
++
++    if (!(pidfile = qemuVirtioFSCreatePidFilename(vm, fs->info.alias)))
++        goto cleanup;
++
++    rc = virPidFileReadPathIfAlive(pidfile, &pid, NULL);
++    if (rc >= 0 && pid != (pid_t) -1)
++        virProcessKillPainfully(pid, true);
++
++    if (unlink(pidfile) < 0 &&
++        errno != ENOENT) {
++        virReportSystemError(errno,
++                             _("Unable to remove stale pidfile %s"),
++                             pidfile);
++    }
++
++    if (QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock)
++        unlink(QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock);
++
++ cleanup:
++    virErrorRestore(&orig_err);
++}
+diff --git a/src/qemu/qemu_virtiofs.h b/src/qemu/qemu_virtiofs.h
+new file mode 100644
+index 0000000000..b2f0c57d0c
+--- /dev/null
++++ b/src/qemu/qemu_virtiofs.h
+@@ -0,0 +1,37 @@
++/*
++ * qemu_virtiofs.h: virtiofs support
++ *
++ * 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/>.
++ */
++
++#pragma once
++
++
++char *
++qemuVirtioFSCreatePidFilename(virDomainObjPtr vm,
++                              const char *alias);
++char *
++qemuVirtioFSCreateSocketFilename(virDomainObjPtr vm,
++                                 const char *alias);
++
++int
++qemuVirtioFSStart(virLogManagerPtr logManager,
++                  virQEMUDriverPtr driver,
++                  virDomainObjPtr vm,
++                  virDomainFSDefPtr fs);
++void
++qemuVirtioFSStop(virQEMUDriverPtr driver,
++                 virDomainObjPtr vm,
++                 virDomainFSDefPtr fs);
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index 8215935bab..a391823090 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -496,6 +496,17 @@ testCompareXMLToArgv(const void *data)
+         }
+     }
+ 
++    for (i = 0; i < vm->def->nfss; i++) {
++        virDomainFSDefPtr fs = vm->def->fss[i];
++        char *s;
++
++        if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)
++            continue;
++
++        s = g_strdup_printf("/tmp/lib/domain--1-guest/fs%zu.vhost-fs.sock", i);
++        QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock = s;
++    }
++
+     if (vm->def->vsock) {
+         virDomainVsockDefPtr vsock = vm->def->vsock;
+         qemuDomainVsockPrivatePtr vsockPriv =
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-add-support-for-specifying-CPU-dies-topology-parameter.patch b/SOURCES/libvirt-qemu-add-support-for-specifying-CPU-dies-topology-parameter.patch
new file mode 100644
index 0000000..9656320
--- /dev/null
+++ b/SOURCES/libvirt-qemu-add-support-for-specifying-CPU-dies-topology-parameter.patch
@@ -0,0 +1,382 @@
+From 2527410246c5d9f0642087fbd894fdba8d8fa906 Mon Sep 17 00:00:00 2001
+Message-Id: <2527410246c5d9f0642087fbd894fdba8d8fa906@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 3 Feb 2020 18:07:24 +0000
+Subject: [PATCH] qemu: add support for specifying CPU "dies" topology
+ parameter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QEMU since 4.1.0 supports the "dies" parameter for -smp
+
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 4cf8dd0c57330e9141333a1b9f4e318e3c83a289)
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785207
+Message-Id: <20200203180726.2203691-4-berrange@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_capabilities.c                  |  2 ++
+ src/qemu/qemu_capabilities.h                  |  1 +
+ src/qemu/qemu_command.c                       |  9 +++--
+ .../caps_4.1.0.x86_64.xml                     |  1 +
+ .../caps_4.2.0.aarch64.xml                    |  1 +
+ .../qemucapabilitiesdata/caps_4.2.0.ppc64.xml |  1 +
+ .../qemucapabilitiesdata/caps_4.2.0.s390x.xml |  1 +
+ .../caps_4.2.0.x86_64.xml                     |  1 +
+ .../hugepages-nvdimm.x86_64-latest.args       |  2 +-
+ ...memory-default-hugepage.x86_64-latest.args |  2 +-
+ .../memfd-memory-numa.x86_64-latest.args      |  2 +-
+ ...y-hotplug-nvdimm-access.x86_64-latest.args |  2 +-
+ ...ry-hotplug-nvdimm-align.x86_64-latest.args |  2 +-
+ ...ry-hotplug-nvdimm-label.x86_64-latest.args |  2 +-
+ ...ory-hotplug-nvdimm-pmem.x86_64-latest.args |  2 +-
+ ...hotplug-nvdimm-readonly.x86_64-latest.args |  2 +-
+ .../memory-hotplug-nvdimm.x86_64-latest.args  |  2 +-
+ tests/qemuxml2argvdata/smp-dies.args          | 29 ++++++++++++++++
+ tests/qemuxml2argvdata/smp-dies.xml           | 33 +++++++++++++++++++
+ tests/qemuxml2argvtest.c                      |  1 +
+ 20 files changed, 86 insertions(+), 12 deletions(-)
+ create mode 100644 tests/qemuxml2argvdata/smp-dies.args
+ create mode 100644 tests/qemuxml2argvdata/smp-dies.xml
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index edefb70309..893fc5a1bb 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -553,6 +553,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
+               "blockdev-file-dynamic-auto-read-only",
+               "savevm-monitor-nodes",
+               "drive-nvme",
++              "smp-dies",
+     );
+ 
+ 
+@@ -3097,6 +3098,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
+     { "sandbox", "elevateprivileges", QEMU_CAPS_SECCOMP_BLACKLIST },
+     { "chardev", "fd", QEMU_CAPS_CHARDEV_FD_PASS },
+     { "overcommit", NULL, QEMU_CAPS_OVERCOMMIT },
++    { "smp-opts", "dies", QEMU_CAPS_SMP_DIES },
+ };
+ 
+ static int
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index d76c1dbfa9..5ec8901bb3 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -534,6 +534,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+     QEMU_CAPS_BLOCK_FILE_AUTO_READONLY_DYNAMIC, /* the auto-read-only property of block backends for files is dynamic */
+     QEMU_CAPS_SAVEVM_MONITOR_NODES, /* 'savevm' handles monitor-owned nodes properly */
+     QEMU_CAPS_DRIVE_NVME, /* -drive file.driver=nvme */
++    QEMU_CAPS_SMP_DIES, /*  -smp dies= */
+ 
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index d7e8216092..7a184c229e 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -7105,7 +7105,8 @@ qemuBuildTSEGCommandLine(virCommandPtr cmd,
+ 
+ static int
+ qemuBuildSmpCommandLine(virCommandPtr cmd,
+-                        virDomainDefPtr def)
++                        virDomainDefPtr def,
++                        virQEMUCapsPtr qemuCaps)
+ {
+     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+     unsigned int maxvcpus = virDomainDefGetVcpusMax(def);
+@@ -7130,12 +7131,14 @@ qemuBuildSmpCommandLine(virCommandPtr cmd,
+     /* sockets, cores, and threads are either all zero
+      * or all non-zero, thus checking one of them is enough */
+     if (def->cpu && def->cpu->sockets) {
+-        if (def->cpu->dies != 1) {
++        if (def->cpu->dies != 1 && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_DIES)) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                            _("Only 1 die per socket is supported"));
+             return -1;
+         }
+         virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets);
++        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_DIES))
++            virBufferAsprintf(&buf, ",dies=%u", def->cpu->dies);
+         virBufferAsprintf(&buf, ",cores=%u", def->cpu->cores);
+         virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
+     } else {
+@@ -9823,7 +9826,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
+     if (qemuBuildMemCommandLine(cmd, cfg, def, qemuCaps, priv) < 0)
+         return NULL;
+ 
+-    if (qemuBuildSmpCommandLine(cmd, def) < 0)
++    if (qemuBuildSmpCommandLine(cmd, def, qemuCaps) < 0)
+         return NULL;
+ 
+     if (qemuBuildIOThreadCommandLine(cmd, def) < 0)
+diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml
+index a98945de0e..54b797a86a 100644
+--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml
+@@ -215,6 +215,7 @@
+   <flag name='ramfb'/>
+   <flag name='blockdev-file-dynamic-auto-read-only'/>
+   <flag name='drive-nvme'/>
++  <flag name='smp-dies'/>
+   <version>4001000</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>43100241</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+index a6469073fd..184bb7ff77 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+@@ -175,6 +175,7 @@
+   <flag name='blockdev-file-dynamic-auto-read-only'/>
+   <flag name='savevm-monitor-nodes'/>
+   <flag name='drive-nvme'/>
++  <flag name='smp-dies'/>
+   <version>4001050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>61700242</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml
+index ee9fb23640..7c62546d74 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml
+@@ -176,6 +176,7 @@
+   <flag name='machine.pseries.cap-ccf-assist'/>
+   <flag name='blockdev-file-dynamic-auto-read-only'/>
+   <flag name='drive-nvme'/>
++  <flag name='smp-dies'/>
+   <version>4001050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>42900242</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
+index fdf5cb4ce9..c8746f05ef 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
+@@ -135,6 +135,7 @@
+   <flag name='query-cpu-model-comparison'/>
+   <flag name='blockdev-file-dynamic-auto-read-only'/>
+   <flag name='drive-nvme'/>
++  <flag name='smp-dies'/>
+   <version>4001050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>39100242</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+index 4857e2f5a5..afd59a269d 100644
+--- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+@@ -218,6 +218,7 @@
+   <flag name='blockdev-file-dynamic-auto-read-only'/>
+   <flag name='savevm-monitor-nodes'/>
+   <flag name='drive-nvme'/>
++  <flag name='smp-dies'/>
+   <version>4002000</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>43100242</microcodeVersion>
+diff --git a/tests/qemuxml2argvdata/hugepages-nvdimm.x86_64-latest.args b/tests/qemuxml2argvdata/hugepages-nvdimm.x86_64-latest.args
+index 9056e56cb7..0d795dca91 100644
+--- a/tests/qemuxml2argvdata/hugepages-nvdimm.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/hugepages-nvdimm.x86_64-latest.args
+@@ -15,7 +15,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+ -m size=1048576k,slots=16,maxmem=1099511627776k \
+ -overcommit mem-lock=off \
+--smp 2,sockets=2,cores=1,threads=1 \
++-smp 2,sockets=2,dies=1,cores=1,threads=1 \
+ -object memory-backend-file,id=ram-node0,prealloc=yes,\
+ mem-path=/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1,share=yes,size=1073741824 \
+ -numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \
+diff --git a/tests/qemuxml2argvdata/memfd-memory-default-hugepage.x86_64-latest.args b/tests/qemuxml2argvdata/memfd-memory-default-hugepage.x86_64-latest.args
+index 998c9f98bd..a655fb1f7c 100644
+--- a/tests/qemuxml2argvdata/memfd-memory-default-hugepage.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memfd-memory-default-hugepage.x86_64-latest.args
+@@ -16,7 +16,7 @@ file=/tmp/lib/domain--1-instance-00000092/master-key.aes \
+ -m 14336 \
+ -mem-prealloc \
+ -overcommit mem-lock=off \
+--smp 8,sockets=1,cores=8,threads=1 \
++-smp 8,sockets=1,dies=1,cores=8,threads=1 \
+ -object memory-backend-memfd,id=ram-node0,hugetlb=yes,hugetlbsize=2097152,\
+ share=yes,size=15032385536,host-nodes=3,policy=preferred \
+ -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \
+diff --git a/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args b/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args
+index 998c9f98bd..a655fb1f7c 100644
+--- a/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memfd-memory-numa.x86_64-latest.args
+@@ -16,7 +16,7 @@ file=/tmp/lib/domain--1-instance-00000092/master-key.aes \
+ -m 14336 \
+ -mem-prealloc \
+ -overcommit mem-lock=off \
+--smp 8,sockets=1,cores=8,threads=1 \
++-smp 8,sockets=1,dies=1,cores=8,threads=1 \
+ -object memory-backend-memfd,id=ram-node0,hugetlb=yes,hugetlbsize=2097152,\
+ share=yes,size=15032385536,host-nodes=3,policy=preferred \
+ -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.x86_64-latest.args
+index beac9ab22a..c8a6ec5755 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.x86_64-latest.args
+@@ -15,7 +15,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+ -m size=219136k,slots=16,maxmem=1099511627776k \
+ -overcommit mem-lock=off \
+--smp 2,sockets=2,cores=1,threads=1 \
++-smp 2,sockets=2,dies=1,cores=1,threads=1 \
+ -numa node,nodeid=0,cpus=0-1,mem=214 \
+ -object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+ share=no,size=536870912 \
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.x86_64-latest.args
+index 3e599098f0..60e9e80039 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.x86_64-latest.args
+@@ -15,7 +15,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+ -m size=219136k,slots=16,maxmem=1099511627776k \
+ -overcommit mem-lock=off \
+--smp 2,sockets=2,cores=1,threads=1 \
++-smp 2,sockets=2,dies=1,cores=1,threads=1 \
+ -numa node,nodeid=0,cpus=0-1,mem=214 \
+ -object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+ share=no,size=536870912,align=2097152 \
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.x86_64-latest.args
+index 05a473dbcc..8c5e483cbb 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.x86_64-latest.args
+@@ -15,7 +15,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+ -m size=219136k,slots=16,maxmem=1099511627776k \
+ -overcommit mem-lock=off \
+--smp 2,sockets=2,cores=1,threads=1 \
++-smp 2,sockets=2,dies=1,cores=1,threads=1 \
+ -numa node,nodeid=0,cpus=0-1,mem=214 \
+ -object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+ share=no,size=536870912 \
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.x86_64-latest.args
+index c3554ac101..7f77ab9fce 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.x86_64-latest.args
+@@ -15,7 +15,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+ -m size=219136k,slots=16,maxmem=1099511627776k \
+ -overcommit mem-lock=off \
+--smp 2,sockets=2,cores=1,threads=1 \
++-smp 2,sockets=2,dies=1,cores=1,threads=1 \
+ -numa node,nodeid=0,cpus=0-1,mem=214 \
+ -object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+ share=no,size=536870912,pmem=on \
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.x86_64-latest.args
+index e1d3fc57a4..631835a380 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.x86_64-latest.args
+@@ -15,7 +15,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+ -m size=219136k,slots=16,maxmem=1099511627776k \
+ -overcommit mem-lock=off \
+--smp 2,sockets=2,cores=1,threads=1 \
++-smp 2,sockets=2,dies=1,cores=1,threads=1 \
+ -numa node,nodeid=0,cpus=0-1,mem=214 \
+ -object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+ share=no,size=536870912 \
+diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-nvdimm.x86_64-latest.args
+index dc6ddd3a0e..48221a5526 100644
+--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm.x86_64-latest.args
+@@ -15,7 +15,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc,accel=tcg,usb=off,dump-guest-core=off,nvdimm=on \
+ -m size=1048576k,slots=16,maxmem=1099511627776k \
+ -overcommit mem-lock=off \
+--smp 2,sockets=2,cores=1,threads=1 \
++-smp 2,sockets=2,dies=1,cores=1,threads=1 \
+ -numa node,nodeid=0,cpus=0-1,mem=1024 \
+ -object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
+ size=536870912 \
+diff --git a/tests/qemuxml2argvdata/smp-dies.args b/tests/qemuxml2argvdata/smp-dies.args
+new file mode 100644
+index 0000000000..632e9d8e34
+--- /dev/null
++++ b/tests/qemuxml2argvdata/smp-dies.args
+@@ -0,0 +1,29 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-QEMUGuest1 \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-i386 \
++-name QEMUGuest1 \
++-S \
++-machine pc,accel=tcg,usb=off,dump-guest-core=off \
++-m 214 \
++-realtime mlock=off \
++-smp 1,maxcpus=4,sockets=2,dies=2,cores=1,threads=1 \
++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
++server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-no-acpi \
++-usb \
++-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
++-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1
+diff --git a/tests/qemuxml2argvdata/smp-dies.xml b/tests/qemuxml2argvdata/smp-dies.xml
+new file mode 100644
+index 0000000000..caadaef8b5
+--- /dev/null
++++ b/tests/qemuxml2argvdata/smp-dies.xml
+@@ -0,0 +1,33 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static' current='1'>4</vcpu>
++  <os>
++    <type arch='i686' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <cpu>
++    <topology sockets='2' dies='2' cores='1' threads='1'/>
++  </cpu>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <disk type='block' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source dev='/dev/HostVG/QEMUGuest1'/>
++      <target dev='hda' bus='ide'/>
++      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
++    </disk>
++    <controller type='usb' index='0'/>
++    <controller type='ide' index='0'/>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index 58b4deefc6..b923590930 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1689,6 +1689,7 @@ mymain(void)
+     DO_TEST("qemu-ns-alt", NONE);
+ 
+     DO_TEST("smp", NONE);
++    DO_TEST("smp-dies", QEMU_CAPS_SMP_DIES);
+ 
+     DO_TEST("iothreads", QEMU_CAPS_OBJECT_IOTHREAD);
+     DO_TEST("iothreads-ids", QEMU_CAPS_OBJECT_IOTHREAD);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-add-virtiofsd_debug-to-qemu.conf.patch b/SOURCES/libvirt-qemu-add-virtiofsd_debug-to-qemu.conf.patch
new file mode 100644
index 0000000..157f3e5
--- /dev/null
+++ b/SOURCES/libvirt-qemu-add-virtiofsd_debug-to-qemu.conf.patch
@@ -0,0 +1,99 @@
+From 26d83d4f99fbdebf9546ebb883535a85dda2fbad Mon Sep 17 00:00:00 2001
+Message-Id: <26d83d4f99fbdebf9546ebb883535a85dda2fbad@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:43 +0100
+Subject: [PATCH] qemu: add virtiofsd_debug to qemu.conf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a 'virtiofsd_debug' option for tuning whether to run virtiofsd
+in debug mode.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit f04319a5449974f1553458e96c2a6ee25e65ab93)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <6e46af8184e9e982a6aca92a62534623795bb1fc.1583322091.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/libvirtd_qemu.aug         | 1 +
+ src/qemu/qemu.conf                 | 7 +++++++
+ src/qemu/qemu_conf.c               | 2 ++
+ src/qemu/qemu_conf.h               | 1 +
+ src/qemu/test_libvirtd_qemu.aug.in | 1 +
+ 5 files changed, 12 insertions(+)
+
+diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
+index 557b6f38f8..3014fa6b86 100644
+--- a/src/qemu/libvirtd_qemu.aug
++++ b/src/qemu/libvirtd_qemu.aug
+@@ -116,6 +116,7 @@ module Libvirtd_qemu =
+    let nvram_entry = str_array_entry "nvram"
+ 
+    let debug_level_entry = int_entry "gluster_debug_level"
++                 | bool_entry "virtiofsd_debug"
+ 
+    let memory_entry = str_entry "memory_backing_dir"
+ 
+diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
+index b6805ffc41..815d2d78ae 100644
+--- a/src/qemu/qemu.conf
++++ b/src/qemu/qemu.conf
+@@ -809,6 +809,13 @@
+ #
+ #gluster_debug_level = 9
+ 
++# virtiofsd debug
++#
++# Whether to enable the debugging output of the virtiofsd daemon.
++# Possible values are 0 or 1. Disabled by default.
++#
++#virtiofsd_debug = 1
++
+ # To enhance security, QEMU driver is capable of creating private namespaces
+ # for each domain started. Well, so far only "mount" namespace is supported. If
+ # enabled it means qemu process is unable to see all the devices on the system,
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 029996427e..7aaf2862a4 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -801,6 +801,8 @@ virQEMUDriverConfigLoadDebugEntry(virQEMUDriverConfigPtr cfg,
+ {
+     if (virConfGetValueUInt(conf, "gluster_debug_level", &cfg->glusterDebugLevel) < 0)
+         return -1;
++    if (virConfGetValueBool(conf, "virtiofsd_debug", &cfg->virtiofsdDebug) < 0)
++        return -1;
+ 
+     return 0;
+ }
+diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
+index b9401635d7..4361f5b2bb 100644
+--- a/src/qemu/qemu_conf.h
++++ b/src/qemu/qemu_conf.h
+@@ -202,6 +202,7 @@ struct _virQEMUDriverConfig {
+     virFirmwarePtr *firmwares;
+     size_t nfirmwares;
+     unsigned int glusterDebugLevel;
++    bool virtiofsdDebug;
+ 
+     char *memoryBackingDir;
+ 
+diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
+index dd90edf687..fca9a942c9 100644
+--- a/src/qemu/test_libvirtd_qemu.aug.in
++++ b/src/qemu/test_libvirtd_qemu.aug.in
+@@ -98,6 +98,7 @@ module Test_libvirtd_qemu =
+ }
+ { "stdio_handler" = "logd" }
+ { "gluster_debug_level" = "9" }
++{ "virtiofsd_debug" = "1" }
+ { "namespaces"
+     { "1" = "mount" }
+ }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-add-wait-unplug-to-qemu-migration-status-enum.patch b/SOURCES/libvirt-qemu-add-wait-unplug-to-qemu-migration-status-enum.patch
new file mode 100644
index 0000000..b5163bd
--- /dev/null
+++ b/SOURCES/libvirt-qemu-add-wait-unplug-to-qemu-migration-status-enum.patch
@@ -0,0 +1,82 @@
+From 614ff7c7faf6ad46bb3b44ff5b57e839b00af4a4 Mon Sep 17 00:00:00 2001
+Message-Id: <614ff7c7faf6ad46bb3b44ff5b57e839b00af4a4@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Thu, 30 Jan 2020 14:12:43 -0500
+Subject: [PATCH] qemu: add wait-unplug to qemu migration status enum
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Aside from itinerant error (actually warning) messages due to an
+unrecognized response from qemu, this isn't even necessary - the
+migration proceeds successfully to completion anyway.
+
+(I'm not sure where to see this status reported in the API though - do
+we need to add an extra state, or recognition of a new event somewhere?)
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 8a226ddb3602586a2ba2359afc4448c02f566a0e)
+
+https://bugzilla.redhat.com/1693587
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20200130191244.24174-6-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_migration.c    | 1 +
+ src/qemu/qemu_monitor.c      | 1 +
+ src/qemu/qemu_monitor.h      | 1 +
+ src/qemu/qemu_monitor_json.c | 1 +
+ 4 files changed, 4 insertions(+)
+
+diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
+index 46612a3c84..b56ccbdc3c 100644
+--- a/src/qemu/qemu_migration.c
++++ b/src/qemu/qemu_migration.c
+@@ -1457,6 +1457,7 @@ qemuMigrationUpdateJobType(qemuDomainJobInfoPtr jobInfo)
+     case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
+     case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
+     case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
++    case QEMU_MONITOR_MIGRATION_STATUS_WAIT_UNPLUG:
+     case QEMU_MONITOR_MIGRATION_STATUS_LAST:
+         break;
+     }
+diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
+index ccd20b3740..4f547bf5ec 100644
+--- a/src/qemu/qemu_monitor.c
++++ b/src/qemu/qemu_monitor.c
+@@ -168,6 +168,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
+               "device", "postcopy-active",
+               "completed", "failed",
+               "cancelling", "cancelled",
++              "wait-unplug",
+ );
+ 
+ VIR_ENUM_IMPL(qemuMonitorVMStatus,
+diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
+index 3f3b81cddd..cca2cdcb27 100644
+--- a/src/qemu/qemu_monitor.h
++++ b/src/qemu/qemu_monitor.h
+@@ -767,6 +767,7 @@ typedef enum {
+     QEMU_MONITOR_MIGRATION_STATUS_ERROR,
+     QEMU_MONITOR_MIGRATION_STATUS_CANCELLING,
+     QEMU_MONITOR_MIGRATION_STATUS_CANCELLED,
++    QEMU_MONITOR_MIGRATION_STATUS_WAIT_UNPLUG,
+ 
+     QEMU_MONITOR_MIGRATION_STATUS_LAST
+ } qemuMonitorMigrationStatus;
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index e5164d218a..5d8c7e9b5e 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -3515,6 +3515,7 @@ qemuMonitorJSONGetMigrationStatsReply(virJSONValuePtr reply,
+     case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
+     case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
+     case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED:
++    case QEMU_MONITOR_MIGRATION_STATUS_WAIT_UNPLUG:
+     case QEMU_MONITOR_MIGRATION_STATUS_LAST:
+         break;
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-allow-migration-with-assigned-PCI-hostdev-if-teaming-is-set.patch b/SOURCES/libvirt-qemu-allow-migration-with-assigned-PCI-hostdev-if-teaming-is-set.patch
new file mode 100644
index 0000000..b36e29f
--- /dev/null
+++ b/SOURCES/libvirt-qemu-allow-migration-with-assigned-PCI-hostdev-if-teaming-is-set.patch
@@ -0,0 +1,96 @@
+From a86311164657b4bc304705b1dd5cea3db83c7c12 Mon Sep 17 00:00:00 2001
+Message-Id: <a86311164657b4bc304705b1dd5cea3db83c7c12@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Thu, 30 Jan 2020 14:12:42 -0500
+Subject: [PATCH] qemu: allow migration with assigned PCI hostdev if <teaming>
+ is set
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Normally a PCI hostdev can't be migrated, so
+qemuMigrationSrcIsAllowedHostdev() won't permit it. In the case of a a
+hostdev network interface that has <teaming type='transient'/> set,
+QEMU will automatically unplug the device prior to migration, and
+re-plug a corresponding device on the destination. This patch modifies
+qemuMigrationSrcIsAllowedHostdev() to allow domains with those devices
+to be migrated.
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 2758f680b7d586baf084f340b153d7706b8ce12b)
+
+https://bugzilla.redhat.com/1693587
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20200130191244.24174-5-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_migration.c | 52 ++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 48 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
+index 29d228a8d9..46612a3c84 100644
+--- a/src/qemu/qemu_migration.c
++++ b/src/qemu/qemu_migration.c
+@@ -1093,10 +1093,54 @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def)
+      * forbidden. */
+     for (i = 0; i < def->nhostdevs; i++) {
+         virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+-        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+-            hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+-            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+-                           _("domain has assigned non-USB host devices"));
++        switch ((virDomainHostdevMode)hostdev->mode) {
++        case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES:
++            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
++                           _("cannot migrate a domain with <hostdev mode='capabilities'>"));
++            return false;
++
++        case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
++            switch ((virDomainHostdevSubsysType)hostdev->source.subsys.type) {
++            case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
++                /* USB devices can be "migrated" */
++                continue;
++
++            case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
++            case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
++            case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
++                virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
++                               _("cannot migrate a domain with <hostdev mode='subsystem' type='%s'>"),
++                               virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
++                return false;
++
++            case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
++                /*
++                 * if this is a network interface with <teaming
++                 * type='transient'>, migration *is* allowed because
++                 * the device will be auto-unplugged by QEMU during
++                 * migration.
++                 */
++                if (hostdev->parentnet &&
++                    hostdev->parentnet->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT) {
++                    continue;
++                }
++
++                /* all other PCI hostdevs can't be migrated */
++                virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
++                               _("cannot migrate a domain with <hostdev mode='subsystem' type='%s'>"),
++                               virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
++                return false;
++
++            case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
++                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                               _("invalid hostdev subsystem type"));
++                return false;
++            }
++            break;
++
++        case VIR_DOMAIN_HOSTDEV_MODE_LAST:
++            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                           _("invalid hostdev mode"));
+             return false;
+         }
+     }
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-backup-Implement-support-for-backup-disk-bitmap-name-configuration.patch b/SOURCES/libvirt-qemu-backup-Implement-support-for-backup-disk-bitmap-name-configuration.patch
new file mode 100644
index 0000000..8871ea3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-backup-Implement-support-for-backup-disk-bitmap-name-configuration.patch
@@ -0,0 +1,56 @@
+From fc87d33beca46597b7d413752a07f50af8579a6a Mon Sep 17 00:00:00 2001
+Message-Id: <fc87d33beca46597b7d413752a07f50af8579a6a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:42 +0100
+Subject: [PATCH] qemu: backup: Implement support for backup disk bitmap name
+ configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use the user-configured name of the bitmap when merging the appropriate
+bitmaps for an incremental backup so that the user can see it as
+configured. Additionally expose the default bitmap name if nothing is
+configured.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 0c3792a155d79ecf39221b9856fa14fde183af91)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <0071b6d1293859c700344434e71e3b2f75ce6ffd.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_backup.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
+index 2cc0e6ab07..23518a5d40 100644
+--- a/src/qemu/qemu_backup.c
++++ b/src/qemu/qemu_backup.c
+@@ -322,7 +322,10 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
+         return -1;
+ 
+     if (incremental) {
+-        dd->incrementalBitmap = g_strdup_printf("backup-%s", dd->domdisk->dst);
++        if (dd->backupdisk->exportbitmap)
++            dd->incrementalBitmap = g_strdup(dd->backupdisk->exportbitmap);
++        else
++            dd->incrementalBitmap = g_strdup_printf("backup-%s", dd->domdisk->dst);
+ 
+         if (qemuBackupDiskPrepareOneBitmaps(dd, actions, incremental,
+                                             blockNamedNodeData) < 0)
+@@ -368,6 +371,10 @@ static int
+ qemuBackupDiskPrepareDataOnePull(virJSONValuePtr actions,
+                                  struct qemuBackupDiskData *dd)
+ {
++    if (!dd->backupdisk->exportbitmap &&
++        dd->incrementalBitmap)
++        dd->backupdisk->exportbitmap = g_strdup(dd->incrementalBitmap);
++
+     if (qemuMonitorTransactionBackup(actions,
+                                      dd->domdisk->src->nodeformat,
+                                      dd->blockjob->name,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-backup-Implement-support-for-backup-disk-export-name-configuration.patch b/SOURCES/libvirt-qemu-backup-Implement-support-for-backup-disk-export-name-configuration.patch
new file mode 100644
index 0000000..a617dca
--- /dev/null
+++ b/SOURCES/libvirt-qemu-backup-Implement-support-for-backup-disk-export-name-configuration.patch
@@ -0,0 +1,46 @@
+From ca5b0a17880bd76c2965e86fa6b6ee93dec204b9 Mon Sep 17 00:00:00 2001
+Message-Id: <ca5b0a17880bd76c2965e86fa6b6ee93dec204b9@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:41 +0100
+Subject: [PATCH] qemu: backup: Implement support for backup disk export name
+ configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Pass the exportname as configured when exporting the image via NBD and
+fill it with the default if it's not configured.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit bce4ac55f8d3df9d649c74d2f35feeaad4422028)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <de4d8ed67fa09ec4016bcafb818f9ab704afb305.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_backup.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
+index c47de2f4a8..2cc0e6ab07 100644
+--- a/src/qemu/qemu_backup.c
++++ b/src/qemu/qemu_backup.c
+@@ -548,9 +548,12 @@ qemuBackupBeginPullExportDisks(virDomainObjPtr vm,
+     for (i = 0; i < ndisks; i++) {
+         struct qemuBackupDiskData *dd = disks + i;
+ 
++        if (!dd->backupdisk->exportname)
++            dd->backupdisk->exportname = g_strdup(dd->domdisk->dst);
++
+         if (qemuMonitorNBDServerAdd(priv->mon,
+                                     dd->store->nodeformat,
+-                                    dd->domdisk->dst,
++                                    dd->backupdisk->exportname,
+                                     false,
+                                     dd->incrementalBitmap) < 0)
+             return -1;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-block-Add-support-for-HTTP-cookies.patch b/SOURCES/libvirt-qemu-block-Add-support-for-HTTP-cookies.patch
new file mode 100644
index 0000000..32be511
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Add-support-for-HTTP-cookies.patch
@@ -0,0 +1,122 @@
+From 79e5b82ba66bbf8cbf55701013749ed155d92633 Mon Sep 17 00:00:00 2001
+Message-Id: <79e5b82ba66bbf8cbf55701013749ed155d92633@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:05 +0100
+Subject: [PATCH] qemu: block: Add support for HTTP cookies
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Pass the alias of the secret object holding the cookie data as
+'cookie-secret' to qemu.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 06d3e8d5398f9ed292b84a18c3bb6ea4034a772e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <1bed750b384b4f553f36cff4782fc29e32af7ca4.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c                              | 14 +++++++++++---
+ .../disk-network-http.x86_64-latest.args           | 11 +++++++++--
+ tests/qemuxml2argvdata/disk-network-http.xml       |  8 ++++++++
+ 3 files changed, 28 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index f07420b6e2..80a8c7296d 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -680,6 +680,7 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+ {
+     qemuDomainStorageSourcePrivatePtr srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
+     const char *passwordalias = NULL;
++    const char *cookiealias = NULL;
+     const char *username = NULL;
+     virJSONValuePtr ret = NULL;
+     g_autoptr(virURI) uri = NULL;
+@@ -704,9 +705,15 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+     if (!(uristr = virURIFormat(uri)))
+         return NULL;
+ 
+-    if (!onlytarget && src->auth) {
+-        username = src->auth->username;
+-        passwordalias = srcPriv->secinfo->s.aes.alias;
++    if (!onlytarget) {
++        if (src->auth) {
++            username = src->auth->username;
++            passwordalias = srcPriv->secinfo->s.aes.alias;
++        }
++
++        if (srcPriv &&
++            srcPriv->httpcookie)
++            cookiealias = srcPriv->httpcookie->s.aes.alias;
+     }
+ 
+     ignore_value(virJSONValueObjectCreate(&ret,
+@@ -714,6 +721,7 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+                                           "S:username", username,
+                                           "S:password-secret", passwordalias,
+                                           "T:sslverify", src->sslverify,
++                                          "S:cookie-secret", cookiealias,
+                                           NULL));
+ 
+     return ret;
+diff --git a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+index 86e4597a81..cbb69e16a9 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+@@ -39,15 +39,22 @@ id=virtio-disk0,bootindex=1 \
+ "file":"libvirt-3-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=libvirt-3-format,\
+ id=virtio-disk1 \
++-object secret,id=libvirt-2-storage-httpcookie-secret0,\
++data=DrPR9NA6GKJb7qi1KbjHad3f3UIGTTDmAmOZHHv1F5w5T8rhnk3f+uSKStHe0J2O,\
++keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"http","url":"http://example.org:1234/test3.img",\
++"cookie-secret":"libvirt-2-storage-httpcookie-secret0",\
+ "node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-2-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=libvirt-2-format,\
+ id=virtio-disk2 \
++-object secret,id=libvirt-1-storage-httpcookie-secret0,\
++data=DrPR9NA6GKJb7qi1KbjHad3f3UIGTTDmAmOZHHv1F5w5T8rhnk3f+uSKStHe0J2O,\
++keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"https","url":"https://example.org:1234/test4.img",\
+-"sslverify":false,"node-name":"libvirt-1-storage","auto-read-only":true,\
+-"discard":"unmap"}' \
++"sslverify":false,"cookie-secret":"libvirt-1-storage-httpcookie-secret0",\
++"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-1-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=libvirt-1-format,\
+diff --git a/tests/qemuxml2argvdata/disk-network-http.xml b/tests/qemuxml2argvdata/disk-network-http.xml
+index 8c475aec1d..6acf75cf65 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.xml
++++ b/tests/qemuxml2argvdata/disk-network-http.xml
+@@ -31,6 +31,10 @@
+       <driver name='qemu' type='raw'/>
+       <source protocol='http' name='test3.img'>
+         <host name='example.org' port='1234'/>
++        <cookies>
++          <cookie name='test'>testcookievalue</cookie>
++          <cookie name='test2'>blurb</cookie>
++        </cookies>
+       </source>
+       <target dev='vdc' bus='virtio'/>
+     </disk>
+@@ -39,6 +43,10 @@
+       <source protocol='https' name='test4.img'>
+         <host name='example.org' port='1234'/>
+         <ssl verify='no'/>
++        <cookies>
++          <cookie name='test'>testcookievalue</cookie>
++          <cookie name='test2'>blurb</cookie>
++        </cookies>
+       </source>
+       <target dev='vdd' bus='virtio'/>
+     </disk>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-block-Add-validator-for-bitmap-chains-accross-backing-chains.patch b/SOURCES/libvirt-qemu-block-Add-validator-for-bitmap-chains-accross-backing-chains.patch
new file mode 100644
index 0000000..d4ea716
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Add-validator-for-bitmap-chains-accross-backing-chains.patch
@@ -0,0 +1,196 @@
+From eeb1315a8015aeda4d2fb7ce590c85c40ffb567d Mon Sep 17 00:00:00 2001
+Message-Id: <eeb1315a8015aeda4d2fb7ce590c85c40ffb567d@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:23 +0100
+Subject: [PATCH] qemu: block: Add validator for bitmap chains accross backing
+ chains
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a validator which checks that a bitmap spanning multiple backing
+chain members doesn't look broken. The current rules are that no
+intermediate birmaps are missing (unfortunately it's hard to know
+whether the topmost or bottommost bitmap is missing) and none of the
+components is inconsistent.
+
+We can obviously improve it over time.
+
+The validator is also tested against the existing bitmap data we have
+for the backup merging test as well as some of the existing broken
+bitmap synthetic test cases.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 41c7e5c2a689a4ad091cec40b61beeeb3dde49b8)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <a1020495b33e99b2c1bb847dff26565d4def1e20.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 41 +++++++++++++++++++++++++
+ src/qemu/qemu_block.h |  5 ++++
+ tests/qemublocktest.c | 70 +++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 116 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 03f029368e..b19290e677 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2687,3 +2687,44 @@ qemuBlockGetNamedNodeData(virDomainObjPtr vm,
+ 
+     return g_steal_pointer(&blockNamedNodeData);
+ }
++
++
++/**
++ * qemuBlockBitmapChainIsValid:
++ *
++ * Validates that the backing chain of @src contains proper consistent bitmap
++ * data for a chain of bitmaps named @bitmapname.
++ *
++ * A valid chain:
++ * 1) bitmaps of same name are in a consecutive subset of images without gap
++ * 2) don't have any inconsistent bitmaps
++ */
++bool
++qemuBlockBitmapChainIsValid(virStorageSourcePtr src,
++                            const char *bitmapname,
++                            virHashTablePtr blockNamedNodeData)
++{
++    qemuBlockNamedNodeDataBitmapPtr bitmap;
++    virStorageSourcePtr n;
++    bool chain_started = false;
++    bool chain_ended = false;
++
++    for (n = src; n; n = n->backingStore) {
++        if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData, n, bitmapname))) {
++            if (chain_started)
++                chain_ended = true;
++
++            continue;
++        }
++
++        if (chain_ended)
++            return false;
++
++        chain_started = true;
++
++        if (bitmap->inconsistent)
++            return false;
++    }
++
++    return chain_started;
++}
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index 68646cbf2e..cf51b9bf4e 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -212,3 +212,8 @@ qemuBlockNamedNodeDataGetBitmapByName(virHashTablePtr blockNamedNodeData,
+ virHashTablePtr
+ qemuBlockGetNamedNodeData(virDomainObjPtr vm,
+                           qemuDomainAsyncJob asyncJob);
++
++bool
++qemuBlockBitmapChainIsValid(virStorageSourcePtr src,
++                            const char *bitmapname,
++                            virHashTablePtr blockNamedNodeData);
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 5946cd6c6b..6a7b07cfee 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -764,6 +764,41 @@ testQemuCheckpointDeleteMerge(const void *opaque)
+ }
+ 
+ 
++struct testQemuBlockBitmapValidateData {
++    const char *name;
++    const char *bitmapname;
++    virStorageSourcePtr chain;
++    bool expect;
++};
++
++static int
++testQemuBlockBitmapValidate(const void *opaque)
++{
++    const struct testQemuBlockBitmapValidateData *data = opaque;
++    g_autoptr(virJSONValue) nodedatajson = NULL;
++    g_autoptr(virHashTable) nodedata = NULL;
++    bool actual;
++
++    if (!(nodedatajson = virTestLoadFileJSON(bitmapDetectPrefix, data->name,
++                                             ".json", NULL)))
++        return -1;
++
++    if (!(nodedata = qemuMonitorJSONBlockGetNamedNodeDataJSON(nodedatajson))) {
++        VIR_TEST_VERBOSE("failed to load nodedata JSON\n");
++        return -1;
++    }
++
++    actual = qemuBlockBitmapChainIsValid(data->chain, data->bitmapname, nodedata);
++
++    if (actual != data->expect) {
++        VIR_TEST_VERBOSE("expected rv:'%d' actual rv:'%d'\n", data->expect, actual);
++        return -1;
++    }
++
++    return 0;
++}
++
++
+ static int
+ mymain(void)
+ {
+@@ -774,6 +809,7 @@ mymain(void)
+     struct testQemuImageCreateData imagecreatedata;
+     struct testQemuBackupIncrementalBitmapCalculateData backupbitmapcalcdata;
+     struct testQemuCheckpointDeleteMergeData checkpointdeletedata;
++    struct testQemuBlockBitmapValidateData blockbitmapvalidatedata;
+     char *capslatest_x86_64 = NULL;
+     virQEMUCapsPtr caps_x86_64 = NULL;
+     g_autoptr(virStorageSource) bitmapSourceChain = NULL;
+@@ -1041,7 +1077,41 @@ mymain(void)
+     TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-intermediate3", "d", "c", "snapshots-synthetic-checkpoint");
+     TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-current", "current", "d", "snapshots-synthetic-checkpoint");
+ 
++#define TEST_BITMAP_VALIDATE(testname, bitmap, rc) \
++    do { \
++        blockbitmapvalidatedata.name = testname; \
++        blockbitmapvalidatedata.chain = bitmapSourceChain; \
++        blockbitmapvalidatedata.bitmapname = bitmap; \
++        blockbitmapvalidatedata.expect = rc; \
++        if (virTestRun("bitmap validate " testname " " bitmap, \
++                       testQemuBlockBitmapValidate, \
++                       &blockbitmapvalidatedata) < 0) \
++            ret = -1; \
++    } while (0)
+ 
++    TEST_BITMAP_VALIDATE("basic", "a", true);
++    TEST_BITMAP_VALIDATE("basic", "b", true);
++    TEST_BITMAP_VALIDATE("basic", "c", true);
++    TEST_BITMAP_VALIDATE("basic", "d", true);
++    TEST_BITMAP_VALIDATE("basic", "current", true);
++
++    TEST_BITMAP_VALIDATE("snapshots", "a", true);
++    TEST_BITMAP_VALIDATE("snapshots", "b", true);
++    TEST_BITMAP_VALIDATE("snapshots", "c", true);
++    TEST_BITMAP_VALIDATE("snapshots", "d", true);
++    TEST_BITMAP_VALIDATE("snapshots", "current", true);
++
++    TEST_BITMAP_VALIDATE("synthetic", "a", false);
++    TEST_BITMAP_VALIDATE("synthetic", "b", true);
++    TEST_BITMAP_VALIDATE("synthetic", "c", true);
++    TEST_BITMAP_VALIDATE("synthetic", "d", true);
++    TEST_BITMAP_VALIDATE("synthetic", "current", true);
++
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "a", true);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "b", true);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "c", true);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "d", true);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "current", true);
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+     qemuTestDriverFree(&driver);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-block-Don-t-skip-creation-of-luks-formatted-images.patch b/SOURCES/libvirt-qemu-block-Don-t-skip-creation-of-luks-formatted-images.patch
new file mode 100644
index 0000000..fa76d45
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Don-t-skip-creation-of-luks-formatted-images.patch
@@ -0,0 +1,59 @@
+From b3285cc15d305161dd0f3730690d6a441c906456 Mon Sep 17 00:00:00 2001
+Message-Id: <b3285cc15d305161dd0f3730690d6a441c906456@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:45 +0100
+Subject: [PATCH] qemu: block: Don't skip creation of 'luks' formatted images
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+libvirt treats 'luks' images as raw+encryption. The logic in
+qemuBlockStorageSourceCreateFormat skipped the creation if the requested
+image was raw but didn't take into account the encryption.
+
+This manifested itself e.g. when attempting to do a virsh blockcopy with
+the following XML:
+
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source file='/tmp/enccpy'>
+        <encryption format='luks'>
+          <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
+        </encryption>
+      </source>
+    </disk>
+
+Where qemu would report the following error:
+
+ unable to execute QEMU command 'blockdev-add': Volume is not in LUKS format
+
+rather than actually formatting the image first.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit f4e7c792d58cbd7318fc30519c551e4fe0cd98de)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1371022
+Message-Id: <1a89d76526af86e4d0437852802a5da0d2aed701.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index eab21bc107..22f03da485 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2479,7 +2479,8 @@ qemuBlockStorageSourceCreateFormat(virDomainObjPtr vm,
+     g_autoptr(virJSONValue) createformatprops = NULL;
+     int ret;
+ 
+-    if (src->format == VIR_STORAGE_FILE_RAW)
++    if (src->format == VIR_STORAGE_FILE_RAW &&
++        !src->encryption)
+         return 0;
+ 
+     if (qemuBlockStorageSourceCreateGetFormatProps(src, backingStore,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-block-Extract-calls-of-qemuBlockGetNamedNodeData-into-a-helper-function.patch b/SOURCES/libvirt-qemu-block-Extract-calls-of-qemuBlockGetNamedNodeData-into-a-helper-function.patch
new file mode 100644
index 0000000..0b7e65e
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Extract-calls-of-qemuBlockGetNamedNodeData-into-a-helper-function.patch
@@ -0,0 +1,122 @@
+From 70cf28f452df43cec98387b3039c3b8c5dda10d4 Mon Sep 17 00:00:00 2001
+Message-Id: <70cf28f452df43cec98387b3039c3b8c5dda10d4@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:16 +0100
+Subject: [PATCH] qemu: block: Extract calls of qemuBlockGetNamedNodeData into
+ a helper function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Create a wrapper for qemuBlockGetNamedNodeData named
+qemuBlockGetNamedNodeData. The purpose of the wrapper is to integrate
+the monitor handling functionality and in the future possible
+qemuCaps-based flags.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 5ddfac11698ec230626e12d077206210424c9bb2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <5527853a9417cf84812cadb842b934ff67de1ea4.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_backup.c |  5 +----
+ src/qemu/qemu_block.c  | 20 ++++++++++++++++++++
+ src/qemu/qemu_block.h  |  4 ++++
+ src/qemu/qemu_driver.c | 16 ++++------------
+ 4 files changed, 29 insertions(+), 16 deletions(-)
+
+diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
+index 23518a5d40..8b1e9a7e19 100644
+--- a/src/qemu/qemu_backup.c
++++ b/src/qemu/qemu_backup.c
+@@ -830,10 +830,7 @@ qemuBackupBegin(virDomainObjPtr vm,
+             goto endjob;
+     }
+ 
+-    if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, QEMU_ASYNC_JOB_BACKUP) < 0)
+-        goto endjob;
+-    blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
+-    if (qemuDomainObjExitMonitor(priv->driver, vm) < 0 || !blockNamedNodeData)
++    if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_BACKUP)))
+         goto endjob;
+ 
+     if ((ndd = qemuBackupDiskPrepareData(vm, def, incremental, blockNamedNodeData,
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 22f03da485..13e240fdac 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2670,3 +2670,23 @@ qemuBlockNamedNodeDataGetBitmapByName(virHashTablePtr blockNamedNodeData,
+ 
+     return NULL;
+ }
++
++
++virHashTablePtr
++qemuBlockGetNamedNodeData(virDomainObjPtr vm,
++                          qemuDomainAsyncJob asyncJob)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    virQEMUDriverPtr driver = priv->driver;
++    g_autoptr(virHashTable) blockNamedNodeData = NULL;
++
++    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
++        return NULL;
++
++    blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
++
++    if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockNamedNodeData)
++        return NULL;
++
++    return g_steal_pointer(&blockNamedNodeData);
++}
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index 1a38e0eccf..68646cbf2e 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -208,3 +208,7 @@ qemuBlockNamedNodeDataBitmapPtr
+ qemuBlockNamedNodeDataGetBitmapByName(virHashTablePtr blockNamedNodeData,
+                                       virStorageSourcePtr src,
+                                       const char *bitmap);
++
++virHashTablePtr
++qemuBlockGetNamedNodeData(virDomainObjPtr vm,
++                          qemuDomainAsyncJob asyncJob);
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index e19e1da0bb..f7ad2dca28 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15622,15 +15622,9 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
+     if (!(actions = virJSONValueNewArray()))
+         return -1;
+ 
+-    if (blockdev) {
+-        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+-            return -1;
+-
+-        blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
+-
+-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockNamedNodeData)
+-            return -1;
+-    }
++    if (blockdev &&
++        !(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
++        return -1;
+ 
+     /* prepare a list of objects to use in the vm definition so that we don't
+      * have to roll back later */
+@@ -18334,9 +18328,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
+                                                                           priv->qemuCaps)))
+                 goto endjob;
+         } else {
+-            qemuDomainObjEnterMonitor(driver, vm);
+-            blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
+-            if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockNamedNodeData)
++            if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
+                 goto endjob;
+ 
+             if (qemuBlockStorageSourceCreateDetectSize(blockNamedNodeData,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-block-Extract-formatting-of-cookie-string.patch b/SOURCES/libvirt-qemu-block-Extract-formatting-of-cookie-string.patch
new file mode 100644
index 0000000..aae59f8
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Extract-formatting-of-cookie-string.patch
@@ -0,0 +1,108 @@
+From 41504cefb5ab3f473680bd7498fc940811cefc26 Mon Sep 17 00:00:00 2001
+Message-Id: <41504cefb5ab3f473680bd7498fc940811cefc26@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:06 +0100
+Subject: [PATCH] qemu: block: Extract formatting of cookie string
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduce qemuBlockStorageSourceGetCookieString which does the
+concatenation so that we can reuse it later.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit bafd2e94fabfe12bdc64c9972f56af536e6ad0eb)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+
+Conflicts:
+	src/qemu/qemu_block.c
+	src/qemu/qemu_block.h
+
+        Context, a8bcbb42172 not backported
+
+	src/qemu/qemu_domain.c
+
+        virBufferTrim change not backported, the conflict is on a
+        previous conflict resolution
+Message-Id: <bbc4bf3b1ebdc99aec680487c22d2a68c1cdda5f.1585063415.git.pkrempa@redhat.com>
+
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c  | 25 +++++++++++++++++++++++++
+ src/qemu/qemu_block.h  |  3 +++
+ src/qemu/qemu_domain.c | 13 +------------
+ 3 files changed, 29 insertions(+), 12 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 73a424f7a8..1f48f559e3 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -3306,3 +3306,28 @@ qemuBlockReopenReadOnly(virDomainObjPtr vm,
+ 
+     return 0;
+ }
++
++
++/**
++ * qemuBlockStorageSourceGetCookieString:
++ * @src: storage source
++ *
++ * Returns a properly formatted string representing cookies of @src in format
++ * accepted by qemu.
++ */
++char *
++qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src)
++{
++    virBuffer buf = VIR_BUFFER_INITIALIZER;
++    size_t i;
++
++    for (i = 0; i < src->ncookies; i++) {
++        virStorageNetCookieDefPtr cookie = src->cookies[i];
++
++        virBufferAsprintf(&buf, "%s=%s; ", cookie->name, cookie->value);
++    }
++
++    virBufferTrim(&buf, "; ", -1);
++
++    return virBufferContentAndReset(&buf);
++}
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index 506957c3d5..4e7708ce74 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -255,3 +255,6 @@ int
+ qemuBlockReopenReadOnly(virDomainObjPtr vm,
+                         virStorageSourcePtr src,
+                         qemuDomainAsyncJob asyncJob);
++
++char *
++qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src);
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 3d31e176d1..4007b4dbda 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1747,18 +1747,7 @@ qemuDomainSecretStorageSourcePrepareCookies(qemuDomainObjPrivatePtr priv,
+                                             const char *aliasprotocol)
+ {
+     g_autofree char *secretalias = qemuAliasForSecret(aliasprotocol, "httpcookie");
+-    g_autofree char *cookies = NULL;
+-    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+-    size_t i;
+-
+-    for (i = 0; i < src->ncookies; i++) {
+-        virStorageNetCookieDefPtr cookie = src->cookies[i];
+-
+-        virBufferAsprintf(&buf, "%s=%s; ", cookie->name, cookie->value);
+-    }
+-
+-    virBufferTrim(&buf, "; ", -1);
+-    cookies = virBufferContentAndReset(&buf);
++    g_autofree char *cookies = qemuBlockStorageSourceGetCookieString(src);
+ 
+     return qemuDomainSecretAESSetup(priv, secretalias, NULL,
+                                     (uint8_t *) cookies, strlen(cookies));
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemu-block-Implement-helpers-for-dealing-with-bitmaps-during-block-commit.patch b/SOURCES/libvirt-qemu-block-Implement-helpers-for-dealing-with-bitmaps-during-block-commit.patch
new file mode 100644
index 0000000..5080fe1
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Implement-helpers-for-dealing-with-bitmaps-during-block-commit.patch
@@ -0,0 +1,287 @@
+From 3e71c9c766a0452e0bae3b4593f3cba3d1caec60 Mon Sep 17 00:00:00 2001
+Message-Id: <3e71c9c766a0452e0bae3b4593f3cba3d1caec60@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:24 +0100
+Subject: [PATCH] qemu: block: Implement helpers for dealing with bitmaps
+ during block commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+qemuBlockBitmapsHandleCommitStart prepares for disabling the bitmaps in
+the 'base' of the commit job so that the bitmaps are not dirtied by the
+commit job. This needs to be done prior to start of the commit job.
+
+qemuBlockBitmapsHandleCommitFinish then calculates the necessary merges
+that agregate all the bitmaps between the commited images and write them
+into the base bitmap.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 1753f605506e28eb42bc5bb6fa9abe8fcbe6fb9b)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <c0624f94e802043ca10819aaaa9111ae230cfb7f.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 219 ++++++++++++++++++++++++++++++++++++++++++
+ src/qemu/qemu_block.h |  14 +++
+ 2 files changed, 233 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index b4da323610..21c1ad9618 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2988,6 +2988,225 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
+ }
+ 
+ 
++/**
++ * @topsrc: virStorageSource representing 'top' of the job
++ * @basesrc: virStorageSource representing 'base' of the job
++ * @blockNamedNodeData: hash table containing data about bitmaps
++ * @actions: filled with arguments for a 'transaction' command
++ * @disabledBitmapsBase: filled with a list of bitmap names which must be disabled
++ *
++ * Prepares data for correctly handling bitmaps during the start of a commit
++ * job. The bitmaps in the 'base' image must be disabled, so that the writes
++ * done by the blockjob don't dirty the enabled bitmaps.
++ *
++ * @actions and @disabledBitmapsBase are untouched if no bitmaps need
++ * to be disabled.
++ */
++int
++qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc,
++                                  virStorageSourcePtr basesrc,
++                                  virHashTablePtr blockNamedNodeData,
++                                  virJSONValuePtr *actions,
++                                  char ***disabledBitmapsBase)
++{
++    g_autoptr(virJSONValue) act = virJSONValueNewArray();
++    VIR_AUTOSTRINGLIST bitmaplist = NULL;
++    size_t curbitmapstr = 0;
++    qemuBlockNamedNodeDataPtr entry;
++    bool disable_bitmaps = false;
++    size_t i;
++
++    if (!(entry = virHashLookup(blockNamedNodeData, basesrc->nodeformat)))
++        return 0;
++
++    bitmaplist = g_new0(char *, entry->nbitmaps);
++
++    for (i = 0; i < entry->nbitmaps; i++) {
++        qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
++
++        if (!bitmap->recording || bitmap->inconsistent ||
++            !qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNamedNodeData))
++            continue;
++
++        disable_bitmaps = true;
++
++        if (qemuMonitorTransactionBitmapDisable(act, basesrc->nodeformat,
++                                                bitmap->name) < 0)
++            return -1;
++
++        bitmaplist[curbitmapstr++] = g_strdup(bitmap->name);
++    }
++
++    if (disable_bitmaps) {
++        *actions = g_steal_pointer(&act);
++        *disabledBitmapsBase = g_steal_pointer(&bitmaplist);
++    }
++
++    return 0;
++}
++
++
++struct qemuBlockBitmapsHandleCommitData {
++    bool skip;
++    bool create;
++    bool enable;
++    const char *basenode;
++    virJSONValuePtr merge;
++    unsigned long long granularity;
++    bool persistent;
++};
++
++
++static void
++qemuBlockBitmapsHandleCommitDataFree(void *opaque)
++{
++    struct qemuBlockBitmapsHandleCommitData *data = opaque;
++
++    virJSONValueFree(data->merge);
++    g_free(data);
++}
++
++
++static int
++qemuBlockBitmapsHandleCommitFinishIterate(void *payload,
++                                          const void *entryname,
++                                          void *opaque)
++{
++    struct qemuBlockBitmapsHandleCommitData *data = payload;
++    const char *bitmapname = entryname;
++    virJSONValuePtr actions = opaque;
++
++    if (data->skip)
++        return 0;
++
++    if (data->create) {
++        if (qemuMonitorTransactionBitmapAdd(actions, data->basenode, bitmapname,
++                                            data->persistent, !data->enable,
++                                            data->granularity) < 0)
++            return -1;
++    } else {
++        if (data->enable &&
++            qemuMonitorTransactionBitmapEnable(actions, data->basenode, bitmapname) < 0)
++            return -1;
++    }
++
++    if (data->merge &&
++        qemuMonitorTransactionBitmapMerge(actions, data->basenode, bitmapname,
++                                          &data->merge) < 0)
++        return -1;
++
++    return 0;
++}
++
++
++/**
++ * @topsrc: virStorageSource representing 'top' of the job
++ * @basesrc: virStorageSource representing 'base' of the job
++ * @blockNamedNodeData: hash table containing data about bitmaps
++ * @actions: filled with arguments for a 'transaction' command
++ * @disabledBitmapsBase: bitmap names which were disabled
++ *
++ * Calculates the necessary bitmap merges/additions/enablements to properly
++ * handle commit of images from 'top' into 'base'. The necessary operations
++ * in the form of arguments of the 'transaction' command are filled into
++ * 'actions' if there is anything to do. Otherwise NULL is returned.
++ */
++int
++qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc,
++                                   virStorageSourcePtr basesrc,
++                                   virHashTablePtr blockNamedNodeData,
++                                   virJSONValuePtr *actions,
++                                   char **disabledBitmapsBase)
++{
++    g_autoptr(virJSONValue) act = virJSONValueNewArray();
++    virStorageSourcePtr n;
++    qemuBlockNamedNodeDataPtr entry;
++    g_autoptr(virHashTable) commitdata = NULL;
++    struct qemuBlockBitmapsHandleCommitData *bitmapdata;
++    size_t i;
++
++    commitdata = virHashNew(qemuBlockBitmapsHandleCommitDataFree);
++
++    for (n = topsrc; n != basesrc; n = n->backingStore) {
++        if (!(entry = virHashLookup(blockNamedNodeData, n->nodeformat)))
++            continue;
++
++        for (i = 0; i < entry->nbitmaps; i++) {
++            qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
++
++            if (!(bitmapdata = virHashLookup(commitdata, bitmap->name))) {
++                bitmapdata = g_new0(struct qemuBlockBitmapsHandleCommitData, 1);
++
++                /* we must mirror the state of the topmost bitmap and merge
++                 * everything else */
++                bitmapdata->create = true;
++                bitmapdata->enable = bitmap->recording;
++                bitmapdata->basenode = basesrc->nodeformat;
++                bitmapdata->merge = virJSONValueNewArray();
++                bitmapdata->granularity = bitmap->granularity;
++                bitmapdata->persistent = bitmap->persistent;
++
++                if (virHashAddEntry(commitdata, bitmap->name, bitmapdata) < 0) {
++                    qemuBlockBitmapsHandleCommitDataFree(bitmapdata);
++                    return -1;
++                }
++            }
++
++            if (bitmap->inconsistent ||
++                !qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNamedNodeData))
++                bitmapdata->skip = true;
++
++            if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(bitmapdata->merge,
++                                                                 n->nodeformat,
++                                                                 bitmap->name) < 0)
++                return -1;
++        }
++    }
++
++    if ((entry = virHashLookup(blockNamedNodeData, basesrc->nodeformat))) {
++        /* note that all bitmaps in 'base' were disabled when commit was started */
++        for (i = 0; i < entry->nbitmaps; i++) {
++            qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
++
++            if ((bitmapdata = virHashLookup(commitdata, bitmap->name))) {
++                bitmapdata->create = false;
++            } else {
++                if (disabledBitmapsBase) {
++                    char **disabledbitmaps;
++
++                    for (disabledbitmaps = disabledBitmapsBase; *disabledbitmaps; disabledbitmaps++) {
++                        if (STREQ(*disabledBitmapsBase, bitmap->name)) {
++                            bitmapdata = g_new0(struct qemuBlockBitmapsHandleCommitData, 1);
++
++                            bitmapdata->create = false;
++                            bitmapdata->enable = true;
++                            bitmapdata->basenode = basesrc->nodeformat;
++                            bitmapdata->granularity = bitmap->granularity;
++                            bitmapdata->persistent = bitmap->persistent;
++
++                            if (virHashAddEntry(commitdata, bitmap->name, bitmapdata) < 0) {
++                                qemuBlockBitmapsHandleCommitDataFree(bitmapdata);
++                                return -1;
++                            }
++
++                            break;
++                        }
++                    }
++                }
++            }
++        }
++    }
++
++    if (virHashForEach(commitdata, qemuBlockBitmapsHandleCommitFinishIterate, act) < 0)
++        return -1;
++
++    if (virJSONValueArraySize(act) > 0)
++        *actions = g_steal_pointer(&act);
++
++    return 0;
++}
++
++
+ /**
+  * qemuBlockReopenFormat:
+  * @vm: domain object
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index e012052352..75b25bfea5 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -232,6 +232,20 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
+                                 bool shallow,
+                                 virJSONValuePtr *actions);
+ 
++int
++qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc,
++                                  virStorageSourcePtr basesrc,
++                                  virHashTablePtr blockNamedNodeData,
++                                  virJSONValuePtr *actions,
++                                  char ***disabledBitmapsBase);
++
++int
++qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc,
++                                   virStorageSourcePtr basesrc,
++                                   virHashTablePtr blockNamedNodeData,
++                                   virJSONValuePtr *actions,
++                                   char **disabledBitmapsBase);
++
+ int
+ qemuBlockReopenReadWrite(virDomainObjPtr vm,
+                          virStorageSourcePtr src,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-block-Implement-readahead-and-timeout-properties-for-curl-driver.patch b/SOURCES/libvirt-qemu-block-Implement-readahead-and-timeout-properties-for-curl-driver.patch
new file mode 100644
index 0000000..39c4c85
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Implement-readahead-and-timeout-properties-for-curl-driver.patch
@@ -0,0 +1,82 @@
+From f1650a0ed4fc226325e5a9772e6d04a95457f470 Mon Sep 17 00:00:00 2001
+Message-Id: <f1650a0ed4fc226325e5a9772e6d04a95457f470@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:06 +0100
+Subject: [PATCH] qemu: block: Implement readahead and timeout properties for
+ 'curl' driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Pass in the correct fields.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 9cac141cd67d2213074fd146b58812da8fe30603)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <71cba24b72024183752fe9873d0fd5f01caf122b.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c                                       | 2 ++
+ tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args | 6 ++++--
+ tests/qemuxml2argvdata/disk-network-http.xml                | 2 ++
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 80a8c7296d..b077e2e02f 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -722,6 +722,8 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+                                           "S:password-secret", passwordalias,
+                                           "T:sslverify", src->sslverify,
+                                           "S:cookie-secret", cookiealias,
++                                          "P:timeout", src->timeout,
++                                          "P:readahead", src->readahead,
+                                           NULL));
+ 
+     return ret;
+diff --git a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+index cbb69e16a9..2f2849ebdf 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+@@ -28,13 +28,15 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -boot strict=on \
+ -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+ -blockdev '{"driver":"http","url":"http://example.org:80/test.img",\
+-"node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \
++"timeout":1234,"node-name":"libvirt-4-storage","auto-read-only":true,\
++"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-4-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-4-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x2,drive=libvirt-4-format,\
+ id=virtio-disk0,bootindex=1 \
+ -blockdev '{"driver":"https","url":"https://example.org:443/test2.img",\
+-"node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \
++"readahead":1024,"node-name":"libvirt-3-storage","auto-read-only":true,\
++"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-3-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=libvirt-3-format,\
+diff --git a/tests/qemuxml2argvdata/disk-network-http.xml b/tests/qemuxml2argvdata/disk-network-http.xml
+index 6acf75cf65..20024c732e 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.xml
++++ b/tests/qemuxml2argvdata/disk-network-http.xml
+@@ -17,6 +17,7 @@
+       <driver name='qemu' type='raw'/>
+       <source protocol='http' name='test.img'>
+         <host name='example.org'/>
++        <timeout seconds='1234'/>
+       </source>
+       <target dev='vda' bus='virtio'/>
+     </disk>
+@@ -24,6 +25,7 @@
+       <driver name='qemu' type='raw'/>
+       <source protocol='https' name='test2.img'>
+         <host name='example.org'/>
++        <readahead size='1024'/>
+       </source>
+       <target dev='vdb' bus='virtio'/>
+     </disk>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-block-Implement-ssl-verification-configuration.patch b/SOURCES/libvirt-qemu-block-Implement-ssl-verification-configuration.patch
new file mode 100644
index 0000000..d285e0b
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Implement-ssl-verification-configuration.patch
@@ -0,0 +1,65 @@
+From 35ea15a7ddb570301c6dceb01e13e6f8ef6ba478 Mon Sep 17 00:00:00 2001
+Message-Id: <35ea15a7ddb570301c6dceb01e13e6f8ef6ba478@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:01 +0100
+Subject: [PATCH] qemu: block: Implement ssl verification configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allow disabling of SSL certificate validation for HTTPS and FTPS drives
+in qemu.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 304da9376c972413d77cc6c7f094a1b39d651ea8)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <a36c004cf393076f7d6cbfa377909c91b99e768d.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c                                       | 1 +
+ tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args | 3 ++-
+ tests/qemuxml2argvdata/disk-network-http.xml                | 1 +
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 5144cf266f..e60975a142 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -713,6 +713,7 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+                                           "s:url", uristr,
+                                           "S:username", username,
+                                           "S:password-secret", passwordalias,
++                                          "T:sslverify", src->sslverify,
+                                           NULL));
+ 
+     return ret;
+diff --git a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+index d39f357072..86e4597a81 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+@@ -46,7 +46,8 @@ id=virtio-disk1 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=libvirt-2-format,\
+ id=virtio-disk2 \
+ -blockdev '{"driver":"https","url":"https://example.org:1234/test4.img",\
+-"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
++"sslverify":false,"node-name":"libvirt-1-storage","auto-read-only":true,\
++"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-1-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=libvirt-1-format,\
+diff --git a/tests/qemuxml2argvdata/disk-network-http.xml b/tests/qemuxml2argvdata/disk-network-http.xml
+index 83a9865c83..8c475aec1d 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.xml
++++ b/tests/qemuxml2argvdata/disk-network-http.xml
+@@ -38,6 +38,7 @@
+       <driver name='qemu' type='raw'/>
+       <source protocol='https' name='test4.img'>
+         <host name='example.org' port='1234'/>
++        <ssl verify='no'/>
+       </source>
+       <target dev='vdd' bus='virtio'/>
+     </disk>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-block-Introduce-function-to-calculate-bitmap-handling-for-block-copy.patch b/SOURCES/libvirt-qemu-block-Introduce-function-to-calculate-bitmap-handling-for-block-copy.patch
new file mode 100644
index 0000000..89209e3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Introduce-function-to-calculate-bitmap-handling-for-block-copy.patch
@@ -0,0 +1,189 @@
+From 0890cd78e9391625a591a7a9327601ee79ba6636 Mon Sep 17 00:00:00 2001
+Message-Id: <0890cd78e9391625a591a7a9327601ee79ba6636@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:25 +0100
+Subject: [PATCH] qemu: block: Introduce function to calculate bitmap handling
+ for block-copy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a function calculating which bitmaps to copy to the mirror during
+a block-copy operation.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 26f07f68707e16bef3d48e1c0b138791ab5df346)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <6d4bd72b975f9f690cb34784ed22bb5fad6bbf2c.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 138 ++++++++++++++++++++++++++++++++++++++++++
+ src/qemu/qemu_block.h |   7 +++
+ 2 files changed, 145 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index b19290e677..63116ef5f2 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2728,3 +2728,141 @@ qemuBlockBitmapChainIsValid(virStorageSourcePtr src,
+ 
+     return chain_started;
+ }
++
++
++struct qemuBlockBitmapsHandleBlockcopyConcatData {
++    virHashTablePtr bitmaps_merge;
++    virJSONValuePtr actions;
++    const char *mirrornodeformat;
++    bool has_bitmaps;
++};
++
++
++static int
++qemuBlockBitmapsHandleBlockcopyConcatActions(void *payload,
++                                             const void *name,
++                                             void *opaque)
++{
++    struct qemuBlockBitmapsHandleBlockcopyConcatData *data = opaque;
++    virJSONValuePtr createactions = payload;
++    const char *bitmapname = name;
++    g_autoptr(virJSONValue) mergebitmaps = virHashSteal(data->bitmaps_merge, bitmapname);
++
++    data->has_bitmaps = true;
++
++    virJSONValueArrayConcat(data->actions, createactions);
++
++    if (qemuMonitorTransactionBitmapMerge(data->actions,
++                                          data->mirrornodeformat,
++                                          bitmapname,
++                                          &mergebitmaps) < 0)
++        return -1;
++
++    return 0;
++}
++
++
++/**
++ * qemuBlockBitmapsHandleBlockcopy:
++ * @src: disk source
++ * @mirror: mirror source
++ * @blockNamedNodeData: hash table containing data about bitmaps
++ * @shallow: whether shallow copy is requested
++ * @actions: filled with arguments for a 'transaction' command
++ *
++ * Calculates which bitmaps to copy and merge during a virDomainBlockCopy job.
++ * This is designed to be called when the job is already synchronised as it
++ * may result in active bitmaps being created.
++ *
++ * Returns 0 on success and -1 on error. If @actions is NULL when 0 is returned
++ * there are no actions to perform for the given job.
++ */
++int
++qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
++                                virStorageSourcePtr mirror,
++                                virHashTablePtr blockNamedNodeData,
++                                bool shallow,
++                                virJSONValuePtr *actions)
++{
++    g_autoptr(virHashTable) bitmaps = virHashNew(virJSONValueHashFree);
++    g_autoptr(virHashTable) bitmaps_merge = virHashNew(virJSONValueHashFree);
++    g_autoptr(virHashTable) bitmaps_skip = virHashNew(NULL);
++    g_autoptr(virJSONValue) tmpactions = virJSONValueNewArray();
++    qemuBlockNamedNodeDataPtr entry;
++    virStorageSourcePtr n;
++    size_t i;
++    struct qemuBlockBitmapsHandleBlockcopyConcatData data = { .bitmaps_merge = bitmaps_merge,
++                                                              .actions = tmpactions,
++                                                              .mirrornodeformat = mirror->nodeformat,
++                                                              .has_bitmaps = false, };
++
++    for (n = src; n; n = n->backingStore) {
++        if (!(entry = virHashLookup(blockNamedNodeData, n->nodeformat)))
++            continue;
++
++        for (i = 0; i < entry->nbitmaps; i++) {
++            qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
++            virJSONValuePtr bitmap_merge;
++
++            if (virHashHasEntry(bitmaps_skip, bitmap->name))
++                continue;
++
++            if (!(bitmap_merge = virHashLookup(bitmaps_merge, bitmap->name))) {
++                g_autoptr(virJSONValue) tmp = NULL;
++                bool disabled = !bitmap->recording;
++
++                /* disable any non top-layer bitmaps */
++                if (n != src)
++                    disabled = true;
++
++                if (!bitmap->persistent ||
++                    !(qemuBlockBitmapChainIsValid(n, bitmap->name,
++                                                  blockNamedNodeData))) {
++                    ignore_value(virHashAddEntry(bitmaps_skip, bitmap->name, NULL));
++                    continue;
++                }
++
++                /* prepare the data for adding the bitmap to the mirror */
++                tmp = virJSONValueNewArray();
++
++                if (qemuMonitorTransactionBitmapAdd(tmp,
++                                                    mirror->nodeformat,
++                                                    bitmap->name,
++                                                    true,
++                                                    disabled,
++                                                    bitmap->granularity) < 0)
++                    return -1;
++
++                if (virHashAddEntry(bitmaps, bitmap->name, tmp) < 0)
++                    return -1;
++
++                tmp = NULL;
++
++                /* prepare array for merging all the bitmaps from the original chain */
++                tmp = virJSONValueNewArray();
++
++                if (virHashAddEntry(bitmaps_merge, bitmap->name, tmp) < 0)
++                    return -1;
++
++                bitmap_merge = g_steal_pointer(&tmp);
++            }
++
++            if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(bitmap_merge,
++                                                                 n->nodeformat,
++                                                                 bitmap->name) < 0)
++                return -1;
++        }
++
++        if (shallow)
++            break;
++    }
++
++    if (virHashForEach(bitmaps, qemuBlockBitmapsHandleBlockcopyConcatActions,
++                       &data) < 0)
++        return -1;
++
++    if (data.has_bitmaps)
++        *actions = g_steal_pointer(&tmpactions);
++
++    return 0;
++}
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index cf51b9bf4e..a816190bb7 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -217,3 +217,10 @@ bool
+ qemuBlockBitmapChainIsValid(virStorageSourcePtr src,
+                             const char *bitmapname,
+                             virHashTablePtr blockNamedNodeData);
++
++int
++qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
++                                virStorageSourcePtr mirror,
++                                virHashTablePtr blockNamedNodeData,
++                                bool shallow,
++                                virJSONValuePtr *actions);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-block-Properly-format-storage-slice-into-backing-store-strings.patch b/SOURCES/libvirt-qemu-block-Properly-format-storage-slice-into-backing-store-strings.patch
new file mode 100644
index 0000000..7c28b70
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Properly-format-storage-slice-into-backing-store-strings.patch
@@ -0,0 +1,138 @@
+From 4d6f00b6dc1d17761ea5bd3656d0e60e2f6cfa61 Mon Sep 17 00:00:00 2001
+Message-Id: <4d6f00b6dc1d17761ea5bd3656d0e60e2f6cfa61@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:22 +0100
+Subject: [PATCH] qemu: block: Properly format storage slice into backing store
+ strings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When creating overlay images e.g. for snapshots or when merging
+snapshots we often specify the backing store string to use. Make the
+formatter aware of backing chain entries which have a <slice>
+configured so that we record it properly. Otherwise such images
+would not work without the XML (when detecting the backing chain).
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 73ca20146700c82e257b02ff8296e42a92629c58)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <68328ece6d627b223d5c7f56c5286fc5d0d04502.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 84 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 51 insertions(+), 33 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 1147f4d3af..387a2db2e6 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1930,44 +1930,48 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src)
+ {
+     int actualType = virStorageSourceGetActualType(src);
+     g_autoptr(virJSONValue) backingProps = NULL;
++    g_autoptr(virJSONValue) sliceProps = NULL;
++    virJSONValuePtr props = NULL;
+     g_autoptr(virURI) uri = NULL;
+     g_autofree char *backingJSON = NULL;
+     char *ret = NULL;
+ 
+-    if (virStorageSourceIsLocalStorage(src)) {
+-        ret = g_strdup(src->path);
+-        return ret;
+-    }
+-
+-    /* generate simplified URIs for the easy cases */
+-    if (actualType == VIR_STORAGE_TYPE_NETWORK &&
+-        src->nhosts == 1 &&
+-        src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
+-
+-        switch ((virStorageNetProtocol) src->protocol) {
+-        case VIR_STORAGE_NET_PROTOCOL_NBD:
+-        case VIR_STORAGE_NET_PROTOCOL_HTTP:
+-        case VIR_STORAGE_NET_PROTOCOL_HTTPS:
+-        case VIR_STORAGE_NET_PROTOCOL_FTP:
+-        case VIR_STORAGE_NET_PROTOCOL_FTPS:
+-        case VIR_STORAGE_NET_PROTOCOL_TFTP:
+-        case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+-        case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
+-            if (!(uri = qemuBlockStorageSourceGetURI(src)))
+-                return NULL;
+-
+-            if (!(ret = virURIFormat(uri)))
+-                return NULL;
+-
++    if (!src->sliceStorage) {
++        if (virStorageSourceIsLocalStorage(src)) {
++            ret = g_strdup(src->path);
+             return ret;
++        }
+ 
+-        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
+-        case VIR_STORAGE_NET_PROTOCOL_RBD:
+-        case VIR_STORAGE_NET_PROTOCOL_VXHS:
+-        case VIR_STORAGE_NET_PROTOCOL_SSH:
+-        case VIR_STORAGE_NET_PROTOCOL_LAST:
+-        case VIR_STORAGE_NET_PROTOCOL_NONE:
+-            break;
++        /* generate simplified URIs for the easy cases */
++        if (actualType == VIR_STORAGE_TYPE_NETWORK &&
++            src->nhosts == 1 &&
++            src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
++
++            switch ((virStorageNetProtocol) src->protocol) {
++            case VIR_STORAGE_NET_PROTOCOL_NBD:
++            case VIR_STORAGE_NET_PROTOCOL_HTTP:
++            case VIR_STORAGE_NET_PROTOCOL_HTTPS:
++            case VIR_STORAGE_NET_PROTOCOL_FTP:
++            case VIR_STORAGE_NET_PROTOCOL_FTPS:
++            case VIR_STORAGE_NET_PROTOCOL_TFTP:
++            case VIR_STORAGE_NET_PROTOCOL_ISCSI:
++            case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
++                if (!(uri = qemuBlockStorageSourceGetURI(src)))
++                    return NULL;
++
++                if (!(ret = virURIFormat(uri)))
++                    return NULL;
++
++                return ret;
++
++            case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
++            case VIR_STORAGE_NET_PROTOCOL_RBD:
++            case VIR_STORAGE_NET_PROTOCOL_VXHS:
++            case VIR_STORAGE_NET_PROTOCOL_SSH:
++            case VIR_STORAGE_NET_PROTOCOL_LAST:
++            case VIR_STORAGE_NET_PROTOCOL_NONE:
++                break;
++            }
+         }
+     }
+ 
+@@ -1975,7 +1979,21 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src)
+     if (!(backingProps = qemuBlockStorageSourceGetBackendProps(src, false, true, false)))
+         return NULL;
+ 
+-    if (!(backingJSON = virJSONValueToString(backingProps, false)))
++    props = backingProps;
++
++    if (src->sliceStorage) {
++        if (virJSONValueObjectCreate(&sliceProps,
++                                     "s:driver", "raw",
++                                     "U:offset", src->sliceStorage->offset,
++                                     "U:size", src->sliceStorage->size,
++                                     "a:file", &backingProps,
++                                     NULL) < 0)
++            return NULL;
++
++        props = sliceProps;
++    }
++
++    if (!(backingJSON = virJSONValueToString(props, false)))
+         return NULL;
+ 
+     ret = g_strdup_printf("json:%s", backingJSON);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-block-Support-VIR_DOMAIN_BLOCK_COMMIT-PULL-REBASE_RELATIVE-with-blockdev.patch b/SOURCES/libvirt-qemu-block-Support-VIR_DOMAIN_BLOCK_COMMIT-PULL-REBASE_RELATIVE-with-blockdev.patch
new file mode 100644
index 0000000..01f5c05
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Support-VIR_DOMAIN_BLOCK_COMMIT-PULL-REBASE_RELATIVE-with-blockdev.patch
@@ -0,0 +1,127 @@
+From 9990d25b88bd2a03c5badb1e40da01030c4b68e4 Mon Sep 17 00:00:00 2001
+Message-Id: <9990d25b88bd2a03c5badb1e40da01030c4b68e4@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:41 +0200
+Subject: [PATCH] qemu: block: Support
+ VIR_DOMAIN_BLOCK_COMMIT/PULL/REBASE_RELATIVE with blockdev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Preservation of the relative relationship requires us to load the
+backing store strings from the disk images. With blockdev we stopped
+detecting the backing chain if it's specified in the XML so the relative
+links were not loaded at that point. To preserve the functionality from
+the pre-blockdev without accessing the backing chain unnecessarily
+during VM startup we must refresh the relative links when relative
+block commit or block pull is requested.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1818655
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit ffc6249c79dbf980d116af7c7ed20222538a7c1c)
+Message-Id: <05fc4389e00afd4b8bf5653fb730c4d8f6a4516d.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_block.c  | 46 ++++++++++++++++++++++++++++++++++++++++++
+ src/qemu/qemu_block.h  |  5 +++++
+ src/qemu/qemu_driver.c |  8 ++++++++
+ 3 files changed, 59 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index ba7318b074..e7577c1312 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -3341,3 +3341,49 @@ qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src)
+ 
+     return virBufferContentAndReset(&buf);
+ }
++
++
++/**
++ * qemuBlockUpdateRelativeBacking:
++ * @vm: domain object
++ * @src: starting point of the update
++ * @topsrc: top level image in the backing chain (used to get security label)
++ *
++ * Reload data necessary for keeping backing store links starting from @src
++ * relative.
++ */
++int
++qemuBlockUpdateRelativeBacking(virDomainObjPtr vm,
++                               virStorageSourcePtr src,
++                               virStorageSourcePtr topsrc)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    virQEMUDriverPtr driver = priv->driver;
++    virStorageSourcePtr n;
++
++    for (n = src; virStorageSourceHasBacking(n); n = n->backingStore) {
++        g_autofree char *backingStoreStr = NULL;
++        int rc;
++
++        if (n->backingStore->relPath)
++            break;
++
++        if (!virStorageFileSupportsBackingChainTraversal(n))
++            continue;
++
++        if (qemuDomainStorageFileInit(driver, vm, n, topsrc) < 0)
++            return -1;
++
++        rc = virStorageFileGetBackingStoreStr(n, &backingStoreStr);
++
++        virStorageFileDeinit(n);
++
++        if (rc < 0)
++            return rc;
++
++        if (backingStoreStr && virStorageIsRelative(backingStoreStr))
++            n->backingStore->relPath = g_steal_pointer(&backingStoreStr);
++    }
++
++    return 0;
++}
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index 4e7708ce74..06afa54115 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -258,3 +258,8 @@ qemuBlockReopenReadOnly(virDomainObjPtr vm,
+ 
+ char *
+ qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src);
++
++int
++qemuBlockUpdateRelativeBacking(virDomainObjPtr vm,
++                               virStorageSourcePtr src,
++                               virStorageSourcePtr topsrc);
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 3c3c7b6041..27a50f60ef 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17740,6 +17740,10 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm,
+                 goto endjob;
+             }
+ 
++            if (blockdev &&
++                qemuBlockUpdateRelativeBacking(vm, disk->src, disk->src) < 0)
++                goto endjob;
++
+             if (virStorageFileGetRelativeBackingPath(disk->src->backingStore,
+                                                      baseSource,
+                                                      &backingPath) < 0)
+@@ -18867,6 +18871,10 @@ qemuDomainBlockCommit(virDomainPtr dom,
+             goto endjob;
+         }
+ 
++        if (blockdev && top_parent &&
++            qemuBlockUpdateRelativeBacking(vm, top_parent, disk->src) < 0)
++            goto endjob;
++
+         if (virStorageFileGetRelativeBackingPath(topSource, baseSource,
+                                                  &backingPath) < 0)
+             goto endjob;
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemu-block-forbid-creation-of-storage-sources-with-slice.patch b/SOURCES/libvirt-qemu-block-forbid-creation-of-storage-sources-with-slice.patch
new file mode 100644
index 0000000..89cbf1f
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-forbid-creation-of-storage-sources-with-slice.patch
@@ -0,0 +1,43 @@
+From eb3af538c22a06297d7f423210cbebcdd008e0c1 Mon Sep 17 00:00:00 2001
+Message-Id: <eb3af538c22a06297d7f423210cbebcdd008e0c1@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:18 +0100
+Subject: [PATCH] qemu: block: forbid creation of storage sources with <slice>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Specifically creating such images via libvirt during blockjobs would
+be much more hassle than it's worth. Just forbid them for now.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 8c4303768846834893687db68ec265ce35aab5df)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <756f5928f4ba944fdec54f60724194a046276a01.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index b408d4c81f..1147f4d3af 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2529,6 +2529,12 @@ qemuBlockStorageSourceCreate(virDomainObjPtr vm,
+     int ret = -1;
+     int rc;
+ 
++    if (src->sliceStorage) {
++        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
++                       _("creation of images with slice type='storage' is not supported"));
++        return -1;
++    }
++
+     if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0)
+         goto cleanup;
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-block-implement-helpers-for-blockdev-reopen.patch b/SOURCES/libvirt-qemu-block-implement-helpers-for-blockdev-reopen.patch
new file mode 100644
index 0000000..0917faa
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-implement-helpers-for-blockdev-reopen.patch
@@ -0,0 +1,155 @@
+From 416b12099e379ec4c19e55a0414a448d140f3dc1 Mon Sep 17 00:00:00 2001
+Message-Id: <416b12099e379ec4c19e55a0414a448d140f3dc1@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:16 +0100
+Subject: [PATCH] qemu: block: implement helpers for blockdev-reopen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduce a set of helpers to call blockdev-reopen in certain scenarios
+
+Libvirt will use the QMP command to turn certain members of the backing
+chain read-write for bitmap manipulation and we'll also want to use it
+to replace/install the backing chain of a qcow2 format node.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 96063ce280a398493d7a78a35f674ed25078d849)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <f7b3a9cc523a22b9f1678483b6b8bf302ae7e1cc.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 101 ++++++++++++++++++++++++++++++++++++++++++
+ src/qemu/qemu_block.h |   9 ++++
+ 2 files changed, 110 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 141059ae81..b4da323610 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2986,3 +2986,104 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
+ 
+     return 0;
+ }
++
++
++/**
++ * qemuBlockReopenFormat:
++ * @vm: domain object
++ * @src: storage source to reopen
++ * @asyncJob: qemu async job type
++ *
++ * Invokes the 'blockdev-reopen' command on the format layer of @src. This means
++ * that @src must be already properly configured for the desired outcome. The
++ * nodenames of @src are used to identify the specific image in qemu.
++ */
++static int
++qemuBlockReopenFormat(virDomainObjPtr vm,
++                      virStorageSourcePtr src,
++                      qemuDomainAsyncJob asyncJob)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    virQEMUDriverPtr driver = priv->driver;
++    g_autoptr(virJSONValue) reopenprops = NULL;
++    int rc;
++
++    /* If we are lacking the object here, qemu might have opened an image with
++     * a node name unknown to us */
++    if (!src->backingStore) {
++        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
++                       _("can't reopen image with unknown presence of backing store"));
++        return -1;
++    }
++
++    if (!(reopenprops = qemuBlockStorageSourceGetBlockdevProps(src, src->backingStore)))
++        return -1;
++
++    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
++        return -1;
++
++    rc = qemuMonitorBlockdevReopen(priv->mon, &reopenprops);
++
++    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
++        return -1;
++
++    return 0;
++}
++
++
++/**
++ * qemuBlockReopenReadWrite:
++ * @vm: domain object
++ * @src: storage source to reopen
++ * @asyncJob: qemu async job type
++ *
++ * Wrapper that reopens @src read-write. We currently depend on qemu
++ * reopening the storage with 'auto-read-only' enabled for us.
++ * After successful reopen @src's 'readonly' flag is modified. Does nothing
++ * if @src is already read-write.
++ */
++int
++qemuBlockReopenReadWrite(virDomainObjPtr vm,
++                         virStorageSourcePtr src,
++                         qemuDomainAsyncJob asyncJob)
++{
++    if (!src->readonly)
++        return 0;
++
++    src->readonly = false;
++    if (qemuBlockReopenFormat(vm, src, asyncJob) < 0) {
++        src->readonly = true;
++        return -1;
++    }
++
++    return 0;
++}
++
++
++/**
++ * qemuBlockReopenReadOnly:
++ * @vm: domain object
++ * @src: storage source to reopen
++ * @asyncJob: qemu async job type
++ *
++ * Wrapper that reopens @src read-only. We currently depend on qemu
++ * reopening the storage with 'auto-read-only' enabled for us.
++ * After successful reopen @src's 'readonly' flag is modified. Does nothing
++ * if @src is already read-only.
++ */
++int
++qemuBlockReopenReadOnly(virDomainObjPtr vm,
++                         virStorageSourcePtr src,
++                         qemuDomainAsyncJob asyncJob)
++{
++    if (src->readonly)
++        return 0;
++
++    src->readonly = true;
++    if (qemuBlockReopenFormat(vm, src, asyncJob) < 0) {
++        src->readonly = false;
++        return -1;
++    }
++
++    return 0;
++}
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index 197f5dae97..e012052352 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -231,3 +231,12 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
+                                 virHashTablePtr blockNamedNodeData,
+                                 bool shallow,
+                                 virJSONValuePtr *actions);
++
++int
++qemuBlockReopenReadWrite(virDomainObjPtr vm,
++                         virStorageSourcePtr src,
++                         qemuDomainAsyncJob asyncJob);
++int
++qemuBlockReopenReadOnly(virDomainObjPtr vm,
++                        virStorageSourcePtr src,
++                        qemuDomainAsyncJob asyncJob);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-blockcopy-Actually-unplug-unused-images-when-mirror-job-fails-to-start.patch b/SOURCES/libvirt-qemu-blockcopy-Actually-unplug-unused-images-when-mirror-job-fails-to-start.patch
new file mode 100644
index 0000000..f6b9f59
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockcopy-Actually-unplug-unused-images-when-mirror-job-fails-to-start.patch
@@ -0,0 +1,43 @@
+From 830d5044f0069e3e34e826d27478c9a19503adcf Mon Sep 17 00:00:00 2001
+Message-Id: <830d5044f0069e3e34e826d27478c9a19503adcf@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:36 +0100
+Subject: [PATCH] qemu: blockcopy: Actually unplug unused images when mirror
+ job fails to start
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If a mirror job fails to start in -blockdev mode we'd not unplug the
+backing files we added first because the code on the error path checked
+the wrong value. 'rc' is used as status of the code which added the
+images, but the state of the 'block(dev)-mirror' call is stored in 'ret'
+at that point.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 623366d13066174e60067fa763ddc2c3d1db20ef)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1792195
+Message-Id: <5e9e1dd3db0f3137079f2fb29974778f8cf32879.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 6163b13e91..83f24d7231 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -18415,7 +18415,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
+     qemuBlockJobStarted(job, vm);
+ 
+  endjob:
+-    if (rc < 0 &&
++    if (ret < 0 &&
+         virDomainObjIsActive(vm) &&
+         (data || crdata)) {
+         qemuDomainObjEnterMonitor(driver, vm);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-blockcopy-Allow-late-opening-of-the-backing-chain-of-a-shallow-copy.patch b/SOURCES/libvirt-qemu-blockcopy-Allow-late-opening-of-the-backing-chain-of-a-shallow-copy.patch
new file mode 100644
index 0000000..c7cdc1d
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockcopy-Allow-late-opening-of-the-backing-chain-of-a-shallow-copy.patch
@@ -0,0 +1,137 @@
+From 7e60e728bc225b3499a3d1fad6b56d0ce8c40908 Mon Sep 17 00:00:00 2001
+Message-Id: <7e60e728bc225b3499a3d1fad6b56d0ce8c40908@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:39 +0100
+Subject: [PATCH] qemu: blockcopy: Allow late opening of the backing chain of a
+ shallow copy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+oVirt used a quirk in the pre-blockdev semantics of drive-mirror which
+opened the backing chain of the mirror destination only once
+'block-job-complete' was called.
+
+Our introduction of blockdev made qemu open the backing chain images
+right at the start of the job. This broke oVirt's usage of this API
+because they copy the data into the backing chain during the time the
+block copy job is running.
+
+Re-introduce late open of the backing chain if qemu allows us to use
+blockdev-snapshot on write-only nodes as it can be used to install the
+backing chain even for an existing image now.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit cc7868a8b3cfa4a0062936c23e82e4a31923f724)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1803092
+Message-Id: <d37e660b9610d7a1cc42892ff3305cb477a8f98a.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 57 +++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 53 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 5a4e979907..441bb02b6b 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17556,10 +17556,12 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+                      qemuBlockJobDataPtr job,
+                      virDomainDiskDefPtr disk)
+ {
++    g_autoptr(qemuBlockStorageSourceChainData) chainattachdata = NULL;
+     int ret = -1;
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+     g_autoptr(virJSONValue) actions = NULL;
++    g_autoptr(virJSONValue) reopenactions = NULL;
+ 
+     if (job->state != QEMU_BLOCKJOB_STATE_READY) {
+         virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
+@@ -17590,6 +17592,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+         if (blockdev && !job->jobflagsmissing) {
+             g_autoptr(virHashTable) blockNamedNodeData = NULL;
+             bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW;
++            bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT;
+ 
+             if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
+                 return -1;
+@@ -17598,6 +17601,27 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+                                                 blockNamedNodeData,
+                                                 shallow, &actions) < 0)
+                 return -1;
++
++            /* Open and install the backing chain of 'mirror' late if we can use
++             * blockdev-snapshot to do it. This is to appease oVirt that wants
++             * to copy data into the backing chain while the top image is being
++             * copied shallow */
++            if (reuse && shallow &&
++                virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY) &&
++                virStorageSourceHasBacking(disk->mirror)) {
++
++                if (!(chainattachdata = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->mirror->backingStore,
++                                                                                         priv->qemuCaps)))
++                    return -1;
++
++                reopenactions = virJSONValueNewArray();
++
++                if (qemuMonitorTransactionSnapshotBlockdev(reopenactions,
++                                                           disk->mirror->backingStore->nodeformat,
++                                                           disk->mirror->nodeformat))
++                    return -1;
++            }
++
+         }
+         break;
+ 
+@@ -17609,7 +17633,15 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+     if (blockdev) {
+         int rc = 0;
+ 
+-        if (actions)
++        if (chainattachdata) {
++            if ((rc = qemuBlockStorageSourceChainAttach(priv->mon, chainattachdata)) == 0) {
++                /* install backing images on success, or unplug them on failure */
++                if ((rc = qemuMonitorTransaction(priv->mon, &reopenactions)) != 0)
++                    qemuBlockStorageSourceChainDetach(priv->mon, chainattachdata);
++            }
++        }
++
++        if (actions && rc == 0)
+             rc = qemuMonitorTransaction(priv->mon, &actions);
+ 
+         if (rc == 0)
+@@ -18354,9 +18386,26 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
+ 
+     if (blockdev) {
+         if (mirror_reuse) {
+-            if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(mirror,
+-                                                                          priv->qemuCaps)))
+-                goto endjob;
++            /* oVirt depended on late-backing-chain-opening semantics the old
++             * qemu command had to copy the backing chain data while the top
++             * level is being copied. To restore this semantics if
++             * blockdev-reopen is supported defer opening of the backing chain
++             * of 'mirror' to the pivot step */
++            if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY)) {
++                g_autoptr(virStorageSource) terminator = virStorageSourceNew();
++
++                if (!terminator)
++                    goto endjob;
++
++                if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdevTop(mirror,
++                                                                                 terminator,
++                                                                                 priv->qemuCaps)))
++                    goto endjob;
++            } else {
++                if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(mirror,
++                                                                              priv->qemuCaps)))
++                    goto endjob;
++            }
+         } else {
+             if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
+                 goto endjob;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-blockjob-Handle-bitmaps-after-finish-of-normal-block-commit.patch b/SOURCES/libvirt-qemu-blockjob-Handle-bitmaps-after-finish-of-normal-block-commit.patch
new file mode 100644
index 0000000..47341be
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockjob-Handle-bitmaps-after-finish-of-normal-block-commit.patch
@@ -0,0 +1,95 @@
+From 629629bccbaef81ab1e187fbf5aab4e07d49f350 Mon Sep 17 00:00:00 2001
+Message-Id: <629629bccbaef81ab1e187fbf5aab4e07d49f350@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:31 +0100
+Subject: [PATCH] qemu: blockjob: Handle bitmaps after finish of normal
+ block-commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Merge the bitmaps into base of the block commit after the job finishes.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit db450a742224fb96d8f4d45fde3d0c19faeabfdb)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <dcf1a67be965850ccd4b35f3ef4587dee5c77151.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_blockjob.c | 52 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 52 insertions(+)
+
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index 63f1cc79c3..0b7e1403e6 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -1049,6 +1049,55 @@ qemuBlockJobDeleteImages(virQEMUDriverPtr driver,
+     }
+ }
+ 
++
++/**
++ * qemuBlockJobProcessEventCompletedCommitBitmaps:
++ *
++ * Handles the bitmap changes after commit. This returns -1 on monitor failures.
++ */
++static int
++qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm,
++                                               qemuBlockJobDataPtr job,
++                                               qemuDomainAsyncJob asyncJob)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    g_autoptr(virHashTable) blockNamedNodeData = NULL;
++    g_autoptr(virJSONValue) actions = NULL;
++
++    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
++        return 0;
++
++    if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
++        return -1;
++
++    if (qemuBlockBitmapsHandleCommitFinish(job->data.commit.top,
++                                           job->data.commit.base,
++                                           blockNamedNodeData,
++                                           &actions,
++                                           job->data.commit.disabledBitmapsBase) < 0)
++        return 0;
++
++    if (!actions)
++        return 0;
++
++    if (qemuBlockReopenReadWrite(vm, job->data.commit.base, asyncJob) < 0)
++        return -1;
++
++    if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0)
++        return -1;
++
++    qemuMonitorTransaction(priv->mon, &actions);
++
++    if (qemuDomainObjExitMonitor(priv->driver, vm) < 0)
++        return -1;
++
++    if (qemuBlockReopenReadOnly(vm, job->data.commit.base, asyncJob) < 0)
++        return -1;
++
++    return 0;
++}
++
++
+ /**
+  * qemuBlockJobProcessEventCompletedCommit:
+  * @driver: qemu driver object
+@@ -1106,6 +1155,9 @@ qemuBlockJobProcessEventCompletedCommit(virQEMUDriverPtr driver,
+     if (!n)
+         return;
+ 
++    if (qemuBlockJobProcessEventCompletedCommitBitmaps(vm, job, asyncJob) < 0)
++        return;
++
+     /* revert access to images */
+     qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.base,
+                                        true, false, false);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-blockjob-Re-enable-bitmaps-after-failed-block-commit.patch b/SOURCES/libvirt-qemu-blockjob-Re-enable-bitmaps-after-failed-block-commit.patch
new file mode 100644
index 0000000..538ca89
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockjob-Re-enable-bitmaps-after-failed-block-commit.patch
@@ -0,0 +1,90 @@
+From 8e5be603c7e3ab3679af498a30cc510177c20514 Mon Sep 17 00:00:00 2001
+Message-Id: <8e5be603c7e3ab3679af498a30cc510177c20514@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:32 +0100
+Subject: [PATCH] qemu: blockjob: Re-enable bitmaps after failed block-commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If a block-commit fails we should at least re-enable the bitmaps so that
+the operation can be re-tried.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 4a39b25c81d40d8d2b5d4e33c53b3660aa4c9fda)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <34dd58f94ac59b5ef970070c07a36ced6bbe77af.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_blockjob.c | 42 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index 0b7e1403e6..21a043d369 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -1345,6 +1345,40 @@ qemuBlockJobProcessEventFailedActiveCommit(virQEMUDriverPtr driver,
+ }
+ 
+ 
++static void
++qemuBlockJobProcessEventFailedCommitCommon(virDomainObjPtr vm,
++                                           qemuBlockJobDataPtr job,
++                                           qemuDomainAsyncJob asyncJob)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    g_autoptr(virJSONValue) actions = virJSONValueNewArray();
++    char **disabledBitmaps = job->data.commit.disabledBitmapsBase;
++
++    if (!disabledBitmaps || !*disabledBitmaps)
++        return;
++
++    for (; *disabledBitmaps; disabledBitmaps++) {
++        qemuMonitorTransactionBitmapEnable(actions,
++                                           job->data.commit.base->nodeformat,
++                                           *disabledBitmaps);
++    }
++
++    if (qemuBlockReopenReadWrite(vm, job->data.commit.base, asyncJob) < 0)
++        return;
++
++    if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0)
++        return;
++
++    qemuMonitorTransaction(priv->mon, &actions);
++
++    if (qemuDomainObjExitMonitor(priv->driver, vm) < 0)
++        return;
++
++    if (qemuBlockReopenReadOnly(vm, job->data.commit.base, asyncJob) < 0)
++        return;
++}
++
++
+ static void
+ qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver,
+                                         virDomainObjPtr vm,
+@@ -1452,13 +1486,17 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
+     case QEMU_BLOCKJOB_TYPE_COMMIT:
+         if (success)
+             qemuBlockJobProcessEventCompletedCommit(driver, vm, job, asyncJob);
++        else
++            qemuBlockJobProcessEventFailedCommitCommon(vm, job, asyncJob);
+         break;
+ 
+     case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
+-        if (success)
++        if (success) {
+             qemuBlockJobProcessEventCompletedActiveCommit(driver, vm, job, asyncJob);
+-        else
++        } else {
+             qemuBlockJobProcessEventFailedActiveCommit(driver, vm, job);
++            qemuBlockJobProcessEventFailedCommitCommon(vm, job, asyncJob);
++        }
+         break;
+ 
+     case QEMU_BLOCKJOB_TYPE_CREATE:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-blockjob-Store-flags-for-all-the-block-job-types.patch b/SOURCES/libvirt-qemu-blockjob-Store-flags-for-all-the-block-job-types.patch
new file mode 100644
index 0000000..c2fa9f9
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockjob-Store-flags-for-all-the-block-job-types.patch
@@ -0,0 +1,154 @@
+From 51688727a7278bdbc9cdb49ab6bc11f38995ab26 Mon Sep 17 00:00:00 2001
+Message-Id: <51688727a7278bdbc9cdb49ab6bc11f38995ab26@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:22 +0100
+Subject: [PATCH] qemu: blockjob: Store 'flags' for all the block job types
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The flags may control important aspects of the block job which may
+influence also the termination of the job. Store the 'flags' for all
+the block job types.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit ccd4228afff22214ea9b9199b2228d79a5cb5877)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <27c11423760ca65573e2539ac822e88d20ad2916.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_blockjob.c | 13 ++++++++++---
+ src/qemu/qemu_blockjob.h |  9 ++++++---
+ src/qemu/qemu_driver.c   |  7 ++++---
+ 3 files changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index 3dc9222a6f..6b59bbeb2c 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -252,7 +252,8 @@ qemuBlockJobDiskNew(virDomainObjPtr vm,
+ qemuBlockJobDataPtr
+ qemuBlockJobDiskNewPull(virDomainObjPtr vm,
+                         virDomainDiskDefPtr disk,
+-                        virStorageSourcePtr base)
++                        virStorageSourcePtr base,
++                        unsigned int jobflags)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     g_autoptr(qemuBlockJobData) job = NULL;
+@@ -269,6 +270,7 @@ qemuBlockJobDiskNewPull(virDomainObjPtr vm,
+         return NULL;
+ 
+     job->data.pull.base = base;
++    job->jobflags = jobflags;
+ 
+     if (qemuBlockJobRegister(job, vm, disk, true) < 0)
+         return NULL;
+@@ -283,7 +285,8 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm,
+                           virStorageSourcePtr topparent,
+                           virStorageSourcePtr top,
+                           virStorageSourcePtr base,
+-                          bool delete_imgs)
++                          bool delete_imgs,
++                          unsigned int jobflags)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     g_autoptr(qemuBlockJobData) job = NULL;
+@@ -307,6 +310,7 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm,
+     job->data.commit.top = top;
+     job->data.commit.base = base;
+     job->data.commit.deleteCommittedImages = delete_imgs;
++    job->jobflags = jobflags;
+ 
+     if (qemuBlockJobRegister(job, vm, disk, true) < 0)
+         return NULL;
+@@ -350,7 +354,8 @@ qemuBlockJobDiskNewCopy(virDomainObjPtr vm,
+                         virDomainDiskDefPtr disk,
+                         virStorageSourcePtr mirror,
+                         bool shallow,
+-                        bool reuse)
++                        bool reuse,
++                        unsigned int jobflags)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     g_autoptr(qemuBlockJobData) job = NULL;
+@@ -371,6 +376,8 @@ qemuBlockJobDiskNewCopy(virDomainObjPtr vm,
+     if (shallow && !reuse)
+         job->data.copy.shallownew = true;
+ 
++    job->jobflags = jobflags;
++
+     if (qemuBlockJobRegister(job, vm, disk, true) < 0)
+         return NULL;
+ 
+diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
+index 53c495fa8a..4045878568 100644
+--- a/src/qemu/qemu_blockjob.h
++++ b/src/qemu/qemu_blockjob.h
+@@ -176,7 +176,8 @@ qemuBlockJobDiskNew(virDomainObjPtr vm,
+ qemuBlockJobDataPtr
+ qemuBlockJobDiskNewPull(virDomainObjPtr vm,
+                         virDomainDiskDefPtr disk,
+-                        virStorageSourcePtr base);
++                        virStorageSourcePtr base,
++                        unsigned int jobflags);
+ 
+ qemuBlockJobDataPtr
+ qemuBlockJobDiskNewCommit(virDomainObjPtr vm,
+@@ -184,7 +185,8 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm,
+                           virStorageSourcePtr topparent,
+                           virStorageSourcePtr top,
+                           virStorageSourcePtr base,
+-                          bool delete_imgs);
++                          bool delete_imgs,
++                          unsigned int jobflags);
+ 
+ qemuBlockJobDataPtr
+ qemuBlockJobNewCreate(virDomainObjPtr vm,
+@@ -197,7 +199,8 @@ qemuBlockJobDiskNewCopy(virDomainObjPtr vm,
+                         virDomainDiskDefPtr disk,
+                         virStorageSourcePtr mirror,
+                         bool shallow,
+-                        bool reuse);
++                        bool reuse,
++                        unsigned int jobflags);
+ 
+ qemuBlockJobDataPtr
+ qemuBlockJobDiskNewBackup(virDomainObjPtr vm,
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 0667402ebb..71c75b25a6 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17686,7 +17686,7 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm,
+         speed <<= 20;
+     }
+ 
+-    if (!(job = qemuBlockJobDiskNewPull(vm, disk, baseSource)))
++    if (!(job = qemuBlockJobDiskNewPull(vm, disk, baseSource, flags)))
+         goto endjob;
+ 
+     if (blockdev) {
+@@ -18373,7 +18373,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
+             goto endjob;
+     }
+ 
+-    if (!(job = qemuBlockJobDiskNewCopy(vm, disk, mirror, mirror_shallow, mirror_reuse)))
++    if (!(job = qemuBlockJobDiskNewCopy(vm, disk, mirror, mirror_shallow, mirror_reuse, flags)))
+         goto endjob;
+ 
+     disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
+@@ -18794,7 +18794,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
+ 
+     if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
+                                           baseSource,
+-                                          flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE)))
++                                          flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
++                                          flags)))
+         goto endjob;
+ 
+     disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-blockjob-Store-jobflags-with-block-job-data.patch b/SOURCES/libvirt-qemu-blockjob-Store-jobflags-with-block-job-data.patch
new file mode 100644
index 0000000..f074852
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockjob-Store-jobflags-with-block-job-data.patch
@@ -0,0 +1,125 @@
+From 5278c00147b0ac777d5ddd73062d0c6146da4908 Mon Sep 17 00:00:00 2001
+Message-Id: <5278c00147b0ac777d5ddd73062d0c6146da4908@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:21 +0100
+Subject: [PATCH] qemu: blockjob: Store 'jobflags' with block job data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a variable which will store the contents of the 'flags' variable as
+passed in by the individual block jobs. Since the flags may influence
+behaviour of the jobs it's important to preserve them to the
+finalization steps.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 9ba804a1d16b12dac2ec2edbd0f384c21d4bc5c8)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <81db2d5e281716bf385d6d9c634136e36e8bd391.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_blockjob.h                             | 3 +++
+ src/qemu/qemu_domain.c                               | 7 +++++++
+ tests/qemustatusxml2xmldata/backup-pull-in.xml       | 2 +-
+ tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml | 8 ++++----
+ 4 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
+index 7d584a2980..53c495fa8a 100644
+--- a/src/qemu/qemu_blockjob.h
++++ b/src/qemu/qemu_blockjob.h
+@@ -129,6 +129,9 @@ struct _qemuBlockJobData {
+     virStorageSourcePtr chain; /* Reference to the chain the job operates on. */
+     virStorageSourcePtr mirrorChain; /* reference to 'mirror' part of the job */
+ 
++    unsigned int jobflags; /* per job flags */
++    bool jobflagsmissing; /* job flags were not stored */
++
+     union {
+         qemuBlockJobPullData pull;
+         qemuBlockJobCommitData commit;
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 94efcdf9b1..846d1ecb29 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -2582,6 +2582,8 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
+     virBufferEscapeString(&attrBuf, " newstate='%s'", newstate);
+     if (job->brokentype != QEMU_BLOCKJOB_TYPE_NONE)
+         virBufferEscapeString(&attrBuf, " brokentype='%s'", qemuBlockjobTypeToString(job->brokentype));
++    if (!job->jobflagsmissing)
++        virBufferAsprintf(&attrBuf, " jobflags='0x%x'", job->jobflags);
+     virBufferEscapeString(&childBuf, "<errmsg>%s</errmsg>", job->errmsg);
+ 
+     if (job->disk) {
+@@ -3294,6 +3296,7 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
+     int newstate = -1;
+     bool invalidData = false;
+     xmlNodePtr tmp;
++    unsigned long jobflags = 0;
+ 
+     ctxt->node = node;
+ 
+@@ -3333,6 +3336,9 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
+         STRNEQ(mirror, "yes"))
+         invalidData = true;
+ 
++    if (virXPathULongHex("string(./@jobflags)", ctxt, &jobflags) != 0)
++        job->jobflagsmissing = true;
++
+     if (!disk && !invalidData) {
+         if ((tmp = virXPathNode("./chains/disk", ctxt)) &&
+             !(job->chain = qemuDomainObjPrivateXMLParseBlockjobChain(tmp, ctxt, xmlopt)))
+@@ -3352,6 +3358,7 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
+ 
+     job->state = state;
+     job->newstate = newstate;
++    job->jobflags = jobflags;
+     job->errmsg = virXPathString("string(./errmsg)", ctxt);
+     job->invalidData = invalidData;
+     job->disk = disk;
+diff --git a/tests/qemustatusxml2xmldata/backup-pull-in.xml b/tests/qemustatusxml2xmldata/backup-pull-in.xml
+index 3c69c41840..1db978a3ac 100644
+--- a/tests/qemustatusxml2xmldata/backup-pull-in.xml
++++ b/tests/qemustatusxml2xmldata/backup-pull-in.xml
+@@ -235,7 +235,7 @@
+   <allowReboot value='yes'/>
+   <nodename index='0'/>
+   <blockjobs active='yes'>
+-    <blockjob name='backup-vda-libvirt-3-format' type='backup' state='running'>
++    <blockjob name='backup-vda-libvirt-3-format' type='backup' state='running' jobflags='0x0'>
+       <disk dst='vda'/>
+       <bitmap name='bitmapname'/>
+       <store type='file' format='qcow2'>
+diff --git a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
+index b5d62fd4ab..ca6d110179 100644
+--- a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
++++ b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
+@@ -261,19 +261,19 @@
+         </source>
+       </src>
+     </blockjob>
+-    <blockjob name='copy-vdd-libvirt-4321-format' type='copy' state='ready' shallownew='yes'>
++    <blockjob name='copy-vdd-libvirt-4321-format' type='copy' state='ready' jobflags='0x0' shallownew='yes'>
+       <disk dst='vdd'/>
+     </blockjob>
+-    <blockjob name='commit-vdc-libvirt-9-format' type='commit' state='running'>
++    <blockjob name='commit-vdc-libvirt-9-format' type='commit' state='running' jobflags='0x0'>
+       <disk dst='vdc'/>
+       <base node='libvirt-11-format'/>
+       <top node='libvirt-9-format'/>
+       <topparent node='libvirt-2-format'/>
+     </blockjob>
+-    <blockjob name='drive-virtio-disk0' type='copy' state='ready'>
++    <blockjob name='drive-virtio-disk0' type='copy' state='ready' jobflags='0x0'>
+       <disk dst='vda' mirror='yes'/>
+     </blockjob>
+-    <blockjob name='create-libvirt-1338-format' type='create' state='running'>
++    <blockjob name='create-libvirt-1338-format' type='create' state='running' jobflags='0xabcd'>
+       <chains>
+         <disk type='file' format='qcow2'>
+           <source file='/create/src1.qcow2' index='1339'>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-blockjob-Store-list-of-bitmaps-disabled-prior-to-commit.patch b/SOURCES/libvirt-qemu-blockjob-Store-list-of-bitmaps-disabled-prior-to-commit.patch
new file mode 100644
index 0000000..2a4d1ae
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockjob-Store-list-of-bitmaps-disabled-prior-to-commit.patch
@@ -0,0 +1,117 @@
+From 7322bb9f51c7c2c35d2e65734e03ff0056b5af22 Mon Sep 17 00:00:00 2001
+Message-Id: <7322bb9f51c7c2c35d2e65734e03ff0056b5af22@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:22 +0100
+Subject: [PATCH] qemu: blockjob: Store list of bitmaps disabled prior to
+ commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Starting a commit job will require disabling bitmaps in the base image
+so that they are not dirtied by the commit job. We need to store a list
+of the bitmaps so that we can later re-enable them.
+
+Add a field and status XML handling code as well as a test.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 41de7230ab169e80237f3e3a29bfecd9baf1a578)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <f009cdda8b29df504d19bddffea5638913f8c931.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_blockjob.h                      |  2 ++
+ src/qemu/qemu_domain.c                        | 26 +++++++++++++++++++
+ .../blockjob-blockdev-in.xml                  |  4 +++
+ 3 files changed, 32 insertions(+)
+
+diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
+index 4045878568..c1d95ea3d8 100644
+--- a/src/qemu/qemu_blockjob.h
++++ b/src/qemu/qemu_blockjob.h
+@@ -88,6 +88,8 @@ struct _qemuBlockJobCommitData {
+     virStorageSourcePtr top;
+     virStorageSourcePtr base;
+     bool deleteCommittedImages;
++    char **disabledBitmapsBase; /* a NULL-terminated list of bitmap names which
++                                   were disabled in @base for the commit job */
+ };
+ 
+ 
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 0faf042145..a273aefa6b 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -2603,6 +2603,9 @@ static void
+ qemuDomainPrivateBlockJobFormatCommit(qemuBlockJobDataPtr job,
+                                       virBufferPtr buf)
+ {
++    g_auto(virBuffer) disabledBitmapsBuf = VIR_BUFFER_INIT_CHILD(buf);
++    char **bitmaps = job->data.commit.disabledBitmapsBase;
++
+     if (job->data.commit.base)
+         virBufferAsprintf(buf, "<base node='%s'/>\n", job->data.commit.base->nodeformat);
+ 
+@@ -2614,6 +2617,11 @@ qemuDomainPrivateBlockJobFormatCommit(qemuBlockJobDataPtr job,
+ 
+     if (job->data.commit.deleteCommittedImages)
+         virBufferAddLit(buf, "<deleteCommittedImages/>\n");
++
++    while (bitmaps && *bitmaps)
++        virBufferEscapeString(&disabledBitmapsBuf, "<bitmap name='%s'/>\n", *(bitmaps++));
++
++    virXMLFormatElement(buf, "disabledBaseBitmaps", NULL, &disabledBitmapsBuf);
+ }
+ 
+ 
+@@ -3240,6 +3248,9 @@ static int
+ qemuDomainObjPrivateXMLParseBlockjobDataCommit(qemuBlockJobDataPtr job,
+                                                xmlXPathContextPtr ctxt)
+ {
++    g_autofree xmlNodePtr *nodes = NULL;
++    ssize_t nnodes;
++
+     if (job->type == QEMU_BLOCKJOB_TYPE_COMMIT) {
+         qemuDomainObjPrivateXMLParseBlockjobNodename(job,
+                                                      "string(./topparent/@node)",
+@@ -3266,6 +3277,21 @@ qemuDomainObjPrivateXMLParseBlockjobDataCommit(qemuBlockJobDataPtr job,
+         !job->data.commit.base)
+         return -1;
+ 
++    if ((nnodes = virXPathNodeSet("./disabledBaseBitmaps/bitmap", ctxt, &nodes)) > 0) {
++        size_t i;
++
++        job->data.commit.disabledBitmapsBase = g_new0(char *, nnodes + 1);
++
++        for (i = 0; i < nnodes; i++) {
++            char *tmp;
++
++            if (!(tmp = virXMLPropString(nodes[i], "name")))
++                return -1;
++
++            job->data.commit.disabledBitmapsBase[i] = g_steal_pointer(&tmp);
++        }
++    }
++
+     return 0;
+ }
+ 
+diff --git a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
+index ca6d110179..cc17a17ff4 100644
+--- a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
++++ b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml
+@@ -243,6 +243,10 @@
+       <base node='libvirt-19-format'/>
+       <top node='libvirt-17-format'/>
+       <deleteCommittedImages/>
++      <disabledBaseBitmaps>
++        <bitmap name='test'/>
++        <bitmap name='test1'/>
++      </disabledBaseBitmaps>
+     </blockjob>
+     <blockjob name='create-libvirt-1337-storage' type='create' state='running'>
+       <create mode='storage'/>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-build-vhost-user-fs-device-command-line.patch b/SOURCES/libvirt-qemu-build-vhost-user-fs-device-command-line.patch
new file mode 100644
index 0000000..c6634f3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-build-vhost-user-fs-device-command-line.patch
@@ -0,0 +1,222 @@
+From eb7fe047e08a536a6c888e61fbe5b149ecb6ce6a Mon Sep 17 00:00:00 2001
+Message-Id: <eb7fe047e08a536a6c888e61fbe5b149ecb6ce6a@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:49 +0100
+Subject: [PATCH] qemu: build vhost-user-fs device command line
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Format the 'vhost-user-fs' device on the QEMU command line.
+
+This device provides shared file system access using the FUSE protocol
+carried over virtio.
+The actual file server is implemented in an external vhost-user-fs device
+backend process.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 0627150a56fd53841918d558d8466feceb18552a)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <2df3adbe3991cb97a06707e818c30dfcb1f6de26.1583322091.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_command.c                       | 46 +++++++++++++++++-
+ ...vhost-user-fs-fd-memory.x86_64-latest.args | 39 +++++++++++++++
+ ...vhost-user-fs-hugepages.x86_64-latest.args | 47 +++++++++++++++++++
+ tests/qemuxml2argvtest.c                      |  3 ++
+ 4 files changed, 133 insertions(+), 2 deletions(-)
+ create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-fd-memory.x86_64-latest.args
+ create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-hugepages.x86_64-latest.args
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 7fdf58f067..fc5366d88d 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -2589,6 +2589,46 @@ qemuBuildDisksCommandLine(virCommandPtr cmd,
+ }
+ 
+ 
++static int
++qemuBuildVHostUserFsCommandLine(virCommandPtr cmd,
++                                virDomainFSDef *fs,
++                                const virDomainDef *def,
++                                qemuDomainObjPrivatePtr priv)
++{
++    g_autofree char *chardev_alias = NULL;
++    g_auto(virBuffer) opt = VIR_BUFFER_INITIALIZER;
++
++    chardev_alias = g_strdup_printf("chr-vu-%s", fs->info.alias);
++
++    virCommandAddArg(cmd, "-chardev");
++    virBufferAddLit(&opt, "socket");
++    virBufferAsprintf(&opt, ",id=%s", chardev_alias);
++    virBufferAddLit(&opt, ",path=");
++    virQEMUBuildBufferEscapeComma(&opt, QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock);
++    virCommandAddArgBuffer(cmd, &opt);
++
++    virCommandAddArg(cmd, "-device");
++
++    if (qemuBuildVirtioDevStr(&opt, "vhost-user-fs", priv->qemuCaps,
++                              VIR_DOMAIN_DEVICE_FS, fs) < 0)
++        return -1;
++
++    virBufferAsprintf(&opt, ",chardev=%s", chardev_alias);
++    if (fs->queue_size)
++        virBufferAsprintf(&opt, ",queue-size=%llu", fs->queue_size);
++    virBufferAddLit(&opt, ",tag=");
++    virQEMUBuildBufferEscapeComma(&opt, fs->dst);
++    if (qemuBuildVirtioOptionsStr(&opt, fs->virtio, priv->qemuCaps) < 0)
++        return -1;
++
++    if (qemuBuildDeviceAddressStr(&opt, def, &fs->info, priv->qemuCaps) < 0)
++        return -1;
++
++    virCommandAddArgBuffer(cmd, &opt);
++    return 0;
++}
++
++
+ static char *
+ qemuBuildFSStr(virDomainFSDefPtr fs)
+ {
+@@ -2681,7 +2721,7 @@ static int
+ qemuBuildFilesystemCommandLine(virCommandPtr cmd,
+                                const virDomainDef *def,
+                                virQEMUCapsPtr qemuCaps,
+-                               qemuDomainObjPrivatePtr priv G_GNUC_UNUSED)
++                               qemuDomainObjPrivatePtr priv)
+ {
+     size_t i;
+ 
+@@ -2696,7 +2736,9 @@ qemuBuildFilesystemCommandLine(virCommandPtr cmd,
+             break;
+ 
+         case VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS:
+-            /* TODO: vhost-user-fs-pci */
++            /* vhost-user-fs-pci */
++            if (qemuBuildVHostUserFsCommandLine(cmd, def->fss[i], def, priv) < 0)
++                return -1;
+             break;
+ 
+         case VIR_DOMAIN_FS_DRIVER_TYPE_LOOP:
+diff --git a/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.x86_64-latest.args b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.x86_64-latest.args
+new file mode 100644
+index 0000000000..a7df45a7f0
+--- /dev/null
++++ b/tests/qemuxml2argvdata/vhost-user-fs-fd-memory.x86_64-latest.args
+@@ -0,0 +1,39 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-guest \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-x86_64 \
++-name guest=guest,debug-threads=on \
++-S \
++-object secret,id=masterKey0,format=raw,\
++file=/tmp/lib/domain--1-guest/master-key.aes \
++-machine pc,accel=kvm,usb=off,dump-guest-core=off \
++-cpu qemu64 \
++-m 14336 \
++-overcommit mem-lock=off \
++-smp 2,sockets=2,cores=1,threads=1 \
++-object memory-backend-file,id=ram-node0,\
++mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-guest/ram-node0,share=yes,\
++size=15032385536 \
++-numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \
++-uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,fd=1729,server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-no-acpi \
++-boot strict=on \
++-chardev socket,id=chr-vu-fs0,path=/tmp/lib/domain--1-guest/fs0.vhost-fs.sock \
++-device vhost-user-fs-pci,chardev=chr-vu-fs0,queue-size=1024,tag=mount_tag,\
++bus=pci.0,addr=0x2 \
++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
++resourcecontrol=deny \
++-msg timestamp=on
+diff --git a/tests/qemuxml2argvdata/vhost-user-fs-hugepages.x86_64-latest.args b/tests/qemuxml2argvdata/vhost-user-fs-hugepages.x86_64-latest.args
+new file mode 100644
+index 0000000000..39190b8d3e
+--- /dev/null
++++ b/tests/qemuxml2argvdata/vhost-user-fs-hugepages.x86_64-latest.args
+@@ -0,0 +1,47 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-guest \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-x86_64 \
++-name guest=guest,debug-threads=on \
++-S \
++-object secret,id=masterKey0,format=raw,\
++file=/tmp/lib/domain--1-guest/master-key.aes \
++-machine q35,accel=tcg,usb=off,dump-guest-core=off \
++-cpu qemu64 \
++-m 2048 \
++-overcommit mem-lock=off \
++-smp 2,sockets=2,cores=1,threads=1 \
++-object memory-backend-file,id=ram-node0,prealloc=yes,\
++mem-path=/dev/hugepages2M/libvirt/qemu/-1-guest,share=yes,size=2147483648 \
++-numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \
++-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,fd=1729,server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-boot strict=on \
++-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
++addr=0x1 \
++-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \
++-device pcie-root-port,port=0xa,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \
++-device pcie-root-port,port=0xb,chassis=4,id=pci.4,bus=pcie.0,addr=0x1.0x3 \
++-blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/guest.qcow2",\
++"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2",\
++"file":"libvirt-1-storage"}' \
++-device virtio-blk-pci,scsi=off,bus=pci.4,addr=0x0,drive=libvirt-1-format,\
++id=virtio-disk0,bootindex=1 \
++-chardev socket,id=chr-vu-fs0,path=/tmp/lib/domain--1-guest/fs0.vhost-fs.sock \
++-device vhost-user-fs-pci,chardev=chr-vu-fs0,tag=mount_tag,bus=pci.1,addr=0x0 \
++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
++resourcecontrol=deny \
++-msg timestamp=on
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index a391823090..265ffce465 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -3053,6 +3053,9 @@ mymain(void)
+ 
+     DO_TEST_CAPS_VER("launch-security-sev", "2.12.0");
+ 
++    DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory");
++    DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages");
++
+     DO_TEST("riscv64-virt",
+             QEMU_CAPS_DEVICE_VIRTIO_MMIO);
+     DO_TEST("riscv64-virt-pci",
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-capabilities-Add-QEMU_CAPS_BLOCKDEV_REOPEN.patch b/SOURCES/libvirt-qemu-capabilities-Add-QEMU_CAPS_BLOCKDEV_REOPEN.patch
new file mode 100644
index 0000000..808eade
--- /dev/null
+++ b/SOURCES/libvirt-qemu-capabilities-Add-QEMU_CAPS_BLOCKDEV_REOPEN.patch
@@ -0,0 +1,53 @@
+From e76712462c74fad141b5d63563c554447fdc497a Mon Sep 17 00:00:00 2001
+Message-Id: <e76712462c74fad141b5d63563c554447fdc497a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:14 +0100
+Subject: [PATCH] qemu: capabilities: Add QEMU_CAPS_BLOCKDEV_REOPEN
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This capability will be asserted once qemu stabilizes 'blockdev-reopen'.
+For now we just add the capability so that we can introduce some code
+that will use the reopening call. This will show our willingness to
+adopt use of reopen and help qemu developers stabilize it.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit ecdd92976144ba9caeae3ce781e39b5e9cc08807)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <f3d864a179b997038d3c06e7de54c6ba77fff3d7.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_capabilities.c | 1 +
+ src/qemu/qemu_capabilities.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 663017157b..a4046b09d6 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -560,6 +560,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
+               "cpu.kvm-no-adjvtime",
+               "vhost-user-fs",
+               "blockdev-snapshot.allow-write-only-overlay",
++              "blockdev-reopen",
+     );
+ 
+ 
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index 2eb8599525..8fdbe05638 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -541,6 +541,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+     QEMU_CAPS_CPU_KVM_NO_ADJVTIME, /* cpu.kvm-no-adjvtime */
+     QEMU_CAPS_DEVICE_VHOST_USER_FS, /* -device vhost-user-fs */
+     QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY, /* blockdev-snapshot has the 'allow-write-only-overlay' feature */
++    QEMU_CAPS_BLOCKDEV_REOPEN, /* 'blockdev-reopen' qmp command is supported */
+ 
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-capabilities-Introduce-QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY.patch b/SOURCES/libvirt-qemu-capabilities-Introduce-QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY.patch
new file mode 100644
index 0000000..cfd1e2b
--- /dev/null
+++ b/SOURCES/libvirt-qemu-capabilities-Introduce-QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY.patch
@@ -0,0 +1,71 @@
+From b28ebb2480fb205ff10059a04745ff989d4f04b0 Mon Sep 17 00:00:00 2001
+Message-Id: <b28ebb2480fb205ff10059a04745ff989d4f04b0@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:38 +0100
+Subject: [PATCH] qemu: capabilities: Introduce
+ QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The capability is based on qemu's support of using blockdev-snapshot to
+install backing chain also for images which are in use by a block-copy
+job.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit d6498be16565f23750f7e906050bdbc30678101f)
+
+ Conflicts:
+	src/qemu/qemu_capabilities.c
+	src/qemu/qemu_capabilities.h
+
+        QEMU_CAPS_QMP_QUERY_NAMED_BLOCK_NODES_FLAT not backported
+
+	tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
+
+        Capability file update not backported
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1803092
+Message-Id: <8240acbad794e65a4e3c61be3fa6713e0cb181ae.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_capabilities.c | 2 ++
+ src/qemu/qemu_capabilities.h | 1 +
+ 2 files changed, 3 insertions(+)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 34df4d89b3..663017157b 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -559,6 +559,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
+               "virtio-net.failover",
+               "cpu.kvm-no-adjvtime",
+               "vhost-user-fs",
++              "blockdev-snapshot.allow-write-only-overlay",
+     );
+ 
+ 
+@@ -1432,6 +1433,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
+     { "blockdev-add/arg-type/+file/$dynamic-auto-read-only", QEMU_CAPS_BLOCK_FILE_AUTO_READONLY_DYNAMIC },
+     { "human-monitor-command/$savevm-monitor-nodes", QEMU_CAPS_SAVEVM_MONITOR_NODES },
+     { "blockdev-add/arg-type/+nvme", QEMU_CAPS_DRIVE_NVME },
++    { "blockdev-snapshot/$allow-write-only-overlay", QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY },
+ };
+ 
+ typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index e3449a9ca3..2eb8599525 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -540,6 +540,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+     QEMU_CAPS_VIRTIO_NET_FAILOVER, /* virtio-net-*.failover */
+     QEMU_CAPS_CPU_KVM_NO_ADJVTIME, /* cpu.kvm-no-adjvtime */
+     QEMU_CAPS_DEVICE_VHOST_USER_FS, /* -device vhost-user-fs */
++    QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY, /* blockdev-snapshot has the 'allow-write-only-overlay' feature */
+ 
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-Allow-checkpoint-redefine-for-offline-VMs.patch b/SOURCES/libvirt-qemu-checkpoint-Allow-checkpoint-redefine-for-offline-VMs.patch
new file mode 100644
index 0000000..e09952b
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-Allow-checkpoint-redefine-for-offline-VMs.patch
@@ -0,0 +1,59 @@
+From 3d1a4ab1ce9fce88a759e11532b6891903f86a4a Mon Sep 17 00:00:00 2001
+Message-Id: <3d1a4ab1ce9fce88a759e11532b6891903f86a4a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 3 Apr 2020 14:32:57 +0200
+Subject: [PATCH] qemu: checkpoint: Allow checkpoint redefine for offline VMs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Skip the liveness and capability checks when redefining checkpoints as
+we don't need qemu interactions to update the metadata.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 135a0b3f7142a8d4f591bb24b3ae7d0f36877bf7)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1819755
+
+Message-Id: <f1d392d78abde1ffbe1c0244d442bc0ec6aa18a6.1585916255.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 16480518fa..34cf122eb3 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -649,16 +649,18 @@ qemuCheckpointCreateXML(virDomainPtr domain,
+         update_current = false;
+     }
+ 
+-    if (!virDomainObjIsActive(vm)) {
+-        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+-                       _("cannot create checkpoint for inactive domain"));
+-        return NULL;
+-    }
++    if (!redefine) {
++        if (!virDomainObjIsActive(vm)) {
++            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
++                           _("cannot create checkpoint for inactive domain"));
++            return NULL;
++        }
+ 
+-    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP)) {
+-        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+-                       _("incremental backup is not supported yet"));
+-        return NULL;
++        if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP)) {
++            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
++                           _("incremental backup is not supported yet"));
++            return NULL;
++        }
+     }
+ 
+     if (!(def = virDomainCheckpointDefParseString(xmlDesc, driver->xmlopt,
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-Extract-calculation-of-bitmap-merging-for-checkpoint-deletion.patch b/SOURCES/libvirt-qemu-checkpoint-Extract-calculation-of-bitmap-merging-for-checkpoint-deletion.patch
new file mode 100644
index 0000000..6bf6c32
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-Extract-calculation-of-bitmap-merging-for-checkpoint-deletion.patch
@@ -0,0 +1,140 @@
+From 2de41b514449c5ab85a7a0943456a44909122874 Mon Sep 17 00:00:00 2001
+Message-Id: <2de41b514449c5ab85a7a0943456a44909122874@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:57 +0100
+Subject: [PATCH] qemu: checkpoint: Extract calculation of bitmap merging for
+ checkpoint deletion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This will allow some testing before refactoring.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit d9dfc1f7de2e54c015504e0a0370e8a89b5e971a)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <2b3c69597aa8f99af55e30f71d4496b6ae620d31.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 72 ++++++++++++++++++++++++--------------
+ src/qemu/qemu_checkpoint.h |  7 ++++
+ 2 files changed, 53 insertions(+), 26 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 1100f6e744..e75cdd0458 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -148,6 +148,46 @@ qemuCheckpointFindActiveDiskInParent(virDomainObjPtr vm,
+ }
+ 
+ 
++int
++qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
++                                 const char *delbitmap,
++                                 const char *parentbitmap,
++                                 bool chkcurrent,
++                                 virJSONValuePtr actions)
++{
++    if (parentbitmap) {
++        g_autoptr(virJSONValue) arr = NULL;
++
++        if (!(arr = virJSONValueNewArray()))
++            return -1;
++
++        if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
++                                                             src->nodeformat,
++                                                             delbitmap) < 0)
++            return -1;
++
++        if (chkcurrent) {
++            if (qemuMonitorTransactionBitmapEnable(actions,
++                                                   src->nodeformat,
++                                                   parentbitmap) < 0)
++                return -1;
++        }
++
++        if (qemuMonitorTransactionBitmapMerge(actions,
++                                              src->nodeformat,
++                                              parentbitmap, &arr) < 0)
++            return -1;
++    }
++
++    if (qemuMonitorTransactionBitmapRemove(actions,
++                                           src->nodeformat,
++                                           delbitmap) < 0)
++        return -1;
++
++    return 0;
++}
++
++
+ static int
+ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                              virDomainCheckpointDefPtr chkdef,
+@@ -167,6 +207,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+         virDomainCheckpointDiskDef *chkdisk = &chkdef->disks[i];
+         virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
+         virDomainCheckpointDiskDef *parentchkdisk = NULL;
++        const char *parentbitmap = NULL;
+ 
+         /* domdisk can be missing e.g. when it was unplugged */
+         if (!domdisk)
+@@ -178,33 +219,12 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+         /* If any ancestor checkpoint has a bitmap for the same
+          * disk, then this bitmap must be merged to the
+          * ancestor. */
+-        if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, parent, chkdisk->name))) {
+-            g_autoptr(virJSONValue) arr = NULL;
++        if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, parent,
++                                                                  chkdisk->name)))
++            parentbitmap = parentchkdisk->name;
+ 
+-            if (!(arr = virJSONValueNewArray()))
+-                return -1;
+-
+-            if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
+-                                                                 domdisk->src->nodeformat,
+-                                                                 chkdisk->bitmap) < 0)
+-                return -1;
+-
+-            if (chkcurrent) {
+-                if (qemuMonitorTransactionBitmapEnable(actions,
+-                                                       domdisk->src->nodeformat,
+-                                                       parentchkdisk->bitmap) < 0)
+-                    return -1;
+-            }
+-
+-            if (qemuMonitorTransactionBitmapMerge(actions,
+-                                                  domdisk->src->nodeformat,
+-                                                  parentchkdisk->bitmap, &arr) < 0)
+-                return -1;
+-        }
+-
+-        if (qemuMonitorTransactionBitmapRemove(actions,
+-                                               domdisk->src->nodeformat,
+-                                               chkdisk->bitmap) < 0)
++        if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, chkdisk->bitmap,
++                                             parentbitmap, chkcurrent, actions) < 0)
+             return -1;
+     }
+ 
+diff --git a/src/qemu/qemu_checkpoint.h b/src/qemu/qemu_checkpoint.h
+index eb85611ea6..85fd453d50 100644
+--- a/src/qemu/qemu_checkpoint.h
++++ b/src/qemu/qemu_checkpoint.h
+@@ -71,3 +71,10 @@ qemuCheckpointCreateFinalize(virQEMUDriverPtr driver,
+ void
+ qemuCheckpointRollbackMetadata(virDomainObjPtr vm,
+                                virDomainMomentObjPtr chk);
++
++int
++qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
++                                 const char *delbitmap,
++                                 const char *parentbitmap,
++                                 bool chkcurrent,
++                                 virJSONValuePtr actions);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-Introduce-helper-to-find-checkpoint-disk-definition-in-parents.patch b/SOURCES/libvirt-qemu-checkpoint-Introduce-helper-to-find-checkpoint-disk-definition-in-parents.patch
new file mode 100644
index 0000000..c1357b6
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-Introduce-helper-to-find-checkpoint-disk-definition-in-parents.patch
@@ -0,0 +1,215 @@
+From a7a774b357e4f56ef4860dbc04065197e3dd9640 Mon Sep 17 00:00:00 2001
+Message-Id: <a7a774b357e4f56ef4860dbc04065197e3dd9640@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:56 +0100
+Subject: [PATCH] qemu: checkpoint: Introduce helper to find checkpoint disk
+ definition in parents
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The algorithm is used in two places to find the parent checkpoint object
+which contains given disk and then uses data from the disk. Additionally
+the code is written in a very non-obvious way. Factor out the lookup of
+the disk into a function which also simplifies the callers.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 6796194a28bd42bcbb237ffae6faea262fcce660)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <4b9ca38d8272158c6d254cb1d3dad21cc736ad9f.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 127 ++++++++++++++++++++-----------------
+ 1 file changed, 70 insertions(+), 57 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 326707e098..1100f6e744 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -104,6 +104,50 @@ qemuCheckpointWriteMetadata(virDomainObjPtr vm,
+ }
+ 
+ 
++/**
++ * qemuCheckpointFindActiveDiskInParent:
++ * @vm: domain object
++ * @from: starting moment object
++ * @diskname: name (target) of the disk to find
++ *
++ * Find the first checkpoint starting from @from continuing through parents
++ * of the checkpoint which describes disk @diskname. Return the pointer to the
++ * definition of the disk.
++ */
++static virDomainCheckpointDiskDef *
++qemuCheckpointFindActiveDiskInParent(virDomainObjPtr vm,
++                                     virDomainMomentObjPtr from,
++                                     const char *diskname)
++{
++    virDomainMomentObjPtr parent = from;
++    virDomainCheckpointDefPtr parentdef = NULL;
++    size_t i;
++
++    while (parent) {
++        parentdef = virDomainCheckpointObjGetDef(parent);
++
++        for (i = 0; i < parentdef->ndisks; i++) {
++            virDomainCheckpointDiskDef *chkdisk = &parentdef->disks[i];
++
++            if (STRNEQ(chkdisk->name, diskname))
++                continue;
++
++            /* currently inspected checkpoint doesn't describe the disk,
++             * continue into parent checkpoint */
++            if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
++                break;
++
++            return chkdisk;
++        }
++
++        parent = virDomainCheckpointFindByName(vm->checkpoints,
++                                               parentdef->parent.parent_name);
++    }
++
++    return NULL;
++}
++
++
+ static int
+ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                              virDomainCheckpointDefPtr chkdef,
+@@ -112,13 +156,9 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     virQEMUDriverPtr driver = priv->driver;
+-    virDomainMomentObjPtr moment;
+-    virDomainCheckpointDefPtr parentdef = NULL;
+-    bool search_parents;
+     int rc;
+     g_autoptr(virJSONValue) actions = NULL;
+     size_t i;
+-    size_t j;
+ 
+     if (!(actions = virJSONValueNewArray()))
+         return -1;
+@@ -126,6 +166,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+     for (i = 0; i < chkdef->ndisks; i++) {
+         virDomainCheckpointDiskDef *chkdisk = &chkdef->disks[i];
+         virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
++        virDomainCheckpointDiskDef *parentchkdisk = NULL;
+ 
+         /* domdisk can be missing e.g. when it was unplugged */
+         if (!domdisk)
+@@ -137,42 +178,28 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+         /* If any ancestor checkpoint has a bitmap for the same
+          * disk, then this bitmap must be merged to the
+          * ancestor. */
+-        search_parents = true;
+-        for (moment = parent;
+-             search_parents && moment;
+-             moment = virDomainCheckpointFindByName(vm->checkpoints,
+-                                                    parentdef->parent.parent_name)) {
+-            parentdef = virDomainCheckpointObjGetDef(moment);
+-            for (j = 0; j < parentdef->ndisks; j++) {
+-                virDomainCheckpointDiskDef *disk2;
+-                g_autoptr(virJSONValue) arr = NULL;
++        if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, parent, chkdisk->name))) {
++            g_autoptr(virJSONValue) arr = NULL;
+ 
+-                disk2 = &parentdef->disks[j];
+-                if (STRNEQ(chkdisk->name, disk2->name) ||
+-                    disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+-                    continue;
+-                search_parents = false;
++            if (!(arr = virJSONValueNewArray()))
++                return -1;
+ 
+-                if (!(arr = virJSONValueNewArray()))
+-                    return -1;
++            if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
++                                                                 domdisk->src->nodeformat,
++                                                                 chkdisk->bitmap) < 0)
++                return -1;
+ 
+-                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
+-                                                                     domdisk->src->nodeformat,
+-                                                                     chkdisk->bitmap) < 0)
+-                    return -1;
+-
+-                if (chkcurrent) {
+-                    if (qemuMonitorTransactionBitmapEnable(actions,
+-                                                           domdisk->src->nodeformat,
+-                                                           disk2->bitmap) < 0)
+-                        return -1;
+-                }
+-
+-                if (qemuMonitorTransactionBitmapMerge(actions,
+-                                                      domdisk->src->nodeformat,
+-                                                      disk2->bitmap, &arr) < 0)
++            if (chkcurrent) {
++                if (qemuMonitorTransactionBitmapEnable(actions,
++                                                       domdisk->src->nodeformat,
++                                                       parentchkdisk->bitmap) < 0)
+                     return -1;
+             }
++
++            if (qemuMonitorTransactionBitmapMerge(actions,
++                                                  domdisk->src->nodeformat,
++                                                  parentchkdisk->bitmap, &arr) < 0)
++                return -1;
+         }
+ 
+         if (qemuMonitorTransactionBitmapRemove(actions,
+@@ -324,14 +351,12 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
+                          virDomainMomentObjPtr old_current,
+                          virDomainCheckpointDefPtr def)
+ {
+-    size_t i, j;
+-    virDomainCheckpointDefPtr olddef;
+-    virDomainMomentObjPtr parent;
+-    bool search_parents;
++    size_t i;
+ 
+     for (i = 0; i < def->ndisks; i++) {
+         virDomainCheckpointDiskDef *chkdisk = &def->disks[i];
+         virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
++        virDomainCheckpointDiskDef *parentchkdisk = NULL;
+ 
+         /* checkpoint definition validator mandates that the corresponding
+          * domdisk should exist */
+@@ -351,25 +376,13 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
+          * iteration; but it is also possible to have to search
+          * further than the immediate parent to find another
+          * checkpoint with a bitmap on the same disk.  */
+-        search_parents = true;
+-        for (parent = old_current; search_parents && parent;
+-             parent = virDomainCheckpointFindByName(vm->checkpoints,
+-                                                    olddef->parent.parent_name)) {
+-            olddef = virDomainCheckpointObjGetDef(parent);
+-            for (j = 0; j < olddef->ndisks; j++) {
+-                virDomainCheckpointDiskDef *disk2;
++        if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, old_current,
++                                                                  chkdisk->name))) {
+ 
+-                disk2 = &olddef->disks[j];
+-                if (STRNEQ(chkdisk->name, disk2->name) ||
+-                    disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+-                    continue;
+-                if (qemuMonitorTransactionBitmapDisable(actions,
+-                                                        domdisk->src->nodeformat,
+-                                                        disk2->bitmap) < 0)
+-                    return -1;
+-                search_parents = false;
+-                break;
+-            }
++            if (qemuMonitorTransactionBitmapDisable(actions,
++                                                    domdisk->src->nodeformat,
++                                                    parentchkdisk->bitmap) < 0)
++                return -1;
+         }
+     }
+     return 0;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-Introduce-support-for-deleting-checkpoints-accross-snapshots.patch b/SOURCES/libvirt-qemu-checkpoint-Introduce-support-for-deleting-checkpoints-accross-snapshots.patch
new file mode 100644
index 0000000..b62d94f
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-Introduce-support-for-deleting-checkpoints-accross-snapshots.patch
@@ -0,0 +1,298 @@
+From 30377cd627a919e51cc4bb60a8a57e94e73f016c Mon Sep 17 00:00:00 2001
+Message-Id: <30377cd627a919e51cc4bb60a8a57e94e73f016c@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:12 +0100
+Subject: [PATCH] qemu: checkpoint: Introduce support for deleting checkpoints
+ accross snapshots
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allow deleting of checkpoints when snapshots were created along. The
+code tracks and modifies the checkpoint list so that backups can still
+be taken with such a backing chain. This unfortunately requires to
+rename few bitmaps (by copying and deleting them) in some cases.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 30bc426071c0f5957af01181c063cd68ade97899)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <e9f416811658b2ba03968ae5fca783b7fb7649f7.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 112 ++++++++++++++++++++++++++++---------
+ src/qemu/qemu_checkpoint.h |   5 +-
+ tests/qemublocktest.c      |  34 +++++++----
+ 3 files changed, 111 insertions(+), 40 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index e75cdd0458..55061bbf76 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -24,6 +24,7 @@
+ #include "qemu_capabilities.h"
+ #include "qemu_monitor.h"
+ #include "qemu_domain.h"
++#include "qemu_block.h"
+ 
+ #include "virerror.h"
+ #include "virlog.h"
+@@ -150,39 +151,92 @@ qemuCheckpointFindActiveDiskInParent(virDomainObjPtr vm,
+ 
+ int
+ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
++                                 virHashTablePtr blockNamedNodeData,
+                                  const char *delbitmap,
+                                  const char *parentbitmap,
+-                                 bool chkcurrent,
+-                                 virJSONValuePtr actions)
++                                 virJSONValuePtr actions,
++                                 const char *diskdst)
+ {
+-    if (parentbitmap) {
+-        g_autoptr(virJSONValue) arr = NULL;
++    virStorageSourcePtr n = src;
+ 
+-        if (!(arr = virJSONValueNewArray()))
+-            return -1;
++    /* find the backing chain entry with bitmap named '@delbitmap' */
++    while (n) {
++        qemuBlockNamedNodeDataBitmapPtr tmp;
+ 
+-        if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
+-                                                             src->nodeformat,
+-                                                             delbitmap) < 0)
+-            return -1;
++        if ((tmp = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
++                                                         n, delbitmap))) {
++            break;
++        }
+ 
+-        if (chkcurrent) {
+-            if (qemuMonitorTransactionBitmapEnable(actions,
+-                                                   src->nodeformat,
+-                                                   parentbitmap) < 0)
++        n = n->backingStore;
++    }
++
++    if (!n) {
++        virReportError(VIR_ERR_INTERNAL_ERROR,
++                       _("bitmap '%s' not found in backing chain of '%s'"),
++                       delbitmap, diskdst);
++        return -1;
++    }
++
++    while (n) {
++        qemuBlockNamedNodeDataBitmapPtr srcbitmap;
++
++        if (!(srcbitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
++                                                                n, delbitmap)))
++            break;
++
++        /* For the actual checkpoint deletion we will merge any bitmap into the
++         * bitmap of the parent checkpoint (@parentbitmap) or for any image
++         * where the parent checkpoint bitmap is not present we must rename
++         * the bitmap of the deleted checkpoint into the bitmap of the parent
++         * checkpoint as qemu can't currently take the allocation map and turn
++         * it into a bitmap and thus we wouldn't be able to do a backup. */
++        if (parentbitmap) {
++            qemuBlockNamedNodeDataBitmapPtr dstbitmap;
++            g_autoptr(virJSONValue) arr = NULL;
++
++            dstbitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
++                                                              n, parentbitmap);
++
++            if (dstbitmap) {
++                if (srcbitmap->recording && !dstbitmap->recording) {
++                    if (qemuMonitorTransactionBitmapEnable(actions,
++                                                           n->nodeformat,
++                                                           dstbitmap->name) < 0)
++                        return -1;
++                }
++
++            } else {
++                if (qemuMonitorTransactionBitmapAdd(actions,
++                                                    n->nodeformat,
++                                                    parentbitmap,
++                                                    true,
++                                                    !srcbitmap->recording,
++                                                    srcbitmap->granularity) < 0)
++                    return -1;
++            }
++
++            if (!(arr = virJSONValueNewArray()))
++                return -1;
++
++            if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
++                                                                 n->nodeformat,
++                                                                 srcbitmap->name) < 0)
++                return -1;
++
++            if (qemuMonitorTransactionBitmapMerge(actions,
++                                                  n->nodeformat,
++                                                  parentbitmap, &arr) < 0)
+                 return -1;
+         }
+ 
+-        if (qemuMonitorTransactionBitmapMerge(actions,
+-                                              src->nodeformat,
+-                                              parentbitmap, &arr) < 0)
++        if (qemuMonitorTransactionBitmapRemove(actions,
++                                               n->nodeformat,
++                                               srcbitmap->name) < 0)
+             return -1;
+-    }
+ 
+-    if (qemuMonitorTransactionBitmapRemove(actions,
+-                                           src->nodeformat,
+-                                           delbitmap) < 0)
+-        return -1;
++        n = n->backingStore;
++    }
+ 
+     return 0;
+ }
+@@ -191,11 +245,11 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
+ static int
+ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                              virDomainCheckpointDefPtr chkdef,
+-                             bool chkcurrent,
+                              virDomainMomentObjPtr parent)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     virQEMUDriverPtr driver = priv->driver;
++    g_autoptr(virHashTable) blockNamedNodeData = NULL;
+     int rc;
+     g_autoptr(virJSONValue) actions = NULL;
+     size_t i;
+@@ -203,6 +257,11 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+     if (!(actions = virJSONValueNewArray()))
+         return -1;
+ 
++    qemuDomainObjEnterMonitor(driver, vm);
++    blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
++    if (qemuDomainObjExitMonitor(priv->driver, vm) < 0 || !blockNamedNodeData)
++        return -1;
++
+     for (i = 0; i < chkdef->ndisks; i++) {
+         virDomainCheckpointDiskDef *chkdisk = &chkdef->disks[i];
+         virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
+@@ -223,8 +282,9 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                                                                   chkdisk->name)))
+             parentbitmap = parentchkdisk->name;
+ 
+-        if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, chkdisk->bitmap,
+-                                             parentbitmap, chkcurrent, actions) < 0)
++        if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData,
++                                             chkdisk->bitmap, parentbitmap,
++                                             actions, domdisk->dst) < 0)
+             return -1;
+     }
+ 
+@@ -262,7 +322,7 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
+         virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
+         parent = virDomainCheckpointFindByName(vm->checkpoints,
+                                                chk->def->parent_name);
+-        if (qemuCheckpointDiscardBitmaps(vm, chkdef, chkcurrent, parent) < 0)
++        if (qemuCheckpointDiscardBitmaps(vm, chkdef, parent) < 0)
+             return -1;
+     }
+ 
+diff --git a/src/qemu/qemu_checkpoint.h b/src/qemu/qemu_checkpoint.h
+index 85fd453d50..976b1eed0f 100644
+--- a/src/qemu/qemu_checkpoint.h
++++ b/src/qemu/qemu_checkpoint.h
+@@ -74,7 +74,8 @@ qemuCheckpointRollbackMetadata(virDomainObjPtr vm,
+ 
+ int
+ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
++                                 virHashTablePtr blockNamedNodeData,
+                                  const char *delbitmap,
+                                  const char *parentbitmap,
+-                                 bool chkcurrent,
+-                                 virJSONValuePtr actions);
++                                 virJSONValuePtr actions,
++                                 const char *diskdst);
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index edaf82053d..e56f813424 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -704,6 +704,7 @@ struct testQemuCheckpointDeleteMergeData {
+     virStorageSourcePtr chain;
+     const char *deletebitmap;
+     const char *parentbitmap;
++    const char *nodedatafile;
+ };
+ 
+ 
+@@ -714,22 +715,30 @@ testQemuCheckpointDeleteMerge(const void *opaque)
+     g_autofree char *actual = NULL;
+     g_autofree char *expectpath = NULL;
+     g_autoptr(virJSONValue) actions = NULL;
+-    bool currentcheckpoint;
++    g_autoptr(virJSONValue) nodedatajson = NULL;
++    g_autoptr(virHashTable) nodedata = NULL;
+ 
+     expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir,
+                                  checkpointDeletePrefix, data->name);
+ 
++    if (!(nodedatajson = virTestLoadFileJSON(bitmapDetectPrefix, data->nodedatafile,
++                                             ".json", NULL)))
++        return -1;
++
++    if (!(nodedata = qemuMonitorJSONBlockGetNamedNodeDataJSON(nodedatajson))) {
++        VIR_TEST_VERBOSE("failed to load nodedata JSON\n");
++        return -1;
++    }
++
+     if (!(actions = virJSONValueNewArray()))
+         return -1;
+ 
+-    /* hack to get the 'current' state until the function stops accepting it */
+-    currentcheckpoint = STREQ("current", data->deletebitmap);
+-
+     if (qemuCheckpointDiscardDiskBitmaps(data->chain,
++                                         nodedata,
+                                          data->deletebitmap,
+                                          data->parentbitmap,
+-                                         currentcheckpoint,
+-                                         actions) < 0) {
++                                         actions,
++                                         "testdisk") < 0) {
+         VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n");
+         return -1;
+     }
+@@ -988,22 +997,23 @@ mymain(void)
+     TEST_BACKUP_BITMAP_CALCULATE("snapshot-intermediate", bitmapSourceChain, "d", "snapshots");
+     TEST_BACKUP_BITMAP_CALCULATE("snapshot-deep", bitmapSourceChain, "a", "snapshots");
+ 
+-#define TEST_CHECKPOINT_DELETE_MERGE(testname, delbmp, parbmp) \
++#define TEST_CHECKPOINT_DELETE_MERGE(testname, delbmp, parbmp, named) \
+     do { \
+         checkpointdeletedata.name = testname; \
+         checkpointdeletedata.chain = bitmapSourceChain; \
+         checkpointdeletedata.deletebitmap = delbmp; \
+         checkpointdeletedata.parentbitmap = parbmp; \
++        checkpointdeletedata.nodedatafile = named; \
+         if (virTestRun("checkpoint delete " testname, \
+                        testQemuCheckpointDeleteMerge, &checkpointdeletedata) < 0) \
+         ret = -1; \
+     } while (0)
+ 
+-    TEST_CHECKPOINT_DELETE_MERGE("basic-noparent", "a", NULL);
+-    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate1", "b", "a");
+-    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate2", "c", "b");
+-    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate3", "d", "c");
+-    TEST_CHECKPOINT_DELETE_MERGE("basic-current", "current", "d");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-noparent", "a", NULL, "basic");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate1", "b", "a", "basic");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate2", "c", "b", "basic");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate3", "d", "c", "basic");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-current", "current", "d", "basic");
+ 
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-Store-whether-deleted-checkpoint-is-current-in-a-variable.patch b/SOURCES/libvirt-qemu-checkpoint-Store-whether-deleted-checkpoint-is-current-in-a-variable.patch
new file mode 100644
index 0000000..5941741
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-Store-whether-deleted-checkpoint-is-current-in-a-variable.patch
@@ -0,0 +1,56 @@
+From f259cc67ba390d0d88f2db616514503714462742 Mon Sep 17 00:00:00 2001
+Message-Id: <f259cc67ba390d0d88f2db616514503714462742@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:49 +0100
+Subject: [PATCH] qemu: checkpoint: Store whether deleted checkpoint is current
+ in a variable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Avoid two computations by using a boolean.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 606dc66b0958fe3545a318ae9bc6a62a67786378)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <d2da4b96b189a8ac30f8be642d854a8a71e35083.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 2fa5c1ae00..d13d4c2a37 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -117,6 +117,7 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
+     size_t i, j;
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+     g_autofree char *chkFile = NULL;
++    bool chkcurrent = chk == virDomainCheckpointGetCurrent(vm->checkpoints);
+ 
+     if (!metadata_only && !virDomainObjIsActive(vm)) {
+         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+@@ -172,7 +173,7 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
+                     if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
+                         return -1;
+ 
+-                    if (chk == virDomainCheckpointGetCurrent(vm->checkpoints)) {
++                    if (chkcurrent) {
+                         if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
+                             return -1;
+                     }
+@@ -192,7 +193,7 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
+             return -1;
+     }
+ 
+-    if (chk == virDomainCheckpointGetCurrent(vm->checkpoints)) {
++    if (chkcurrent) {
+         virDomainCheckpointSetCurrent(vm->checkpoints, NULL);
+         if (update_parent && parent) {
+             virDomainCheckpointSetCurrent(vm->checkpoints, parent);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-Track-and-relabel-images-for-bitmap-merging.patch b/SOURCES/libvirt-qemu-checkpoint-Track-and-relabel-images-for-bitmap-merging.patch
new file mode 100644
index 0000000..a591845
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-Track-and-relabel-images-for-bitmap-merging.patch
@@ -0,0 +1,257 @@
+From eee9a7173898212632d42ef74777d6726ce29d5f Mon Sep 17 00:00:00 2001
+Message-Id: <eee9a7173898212632d42ef74777d6726ce29d5f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:15 +0100
+Subject: [PATCH] qemu: checkpoint: Track and relabel images for bitmap merging
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allow qemu access to modify backing files in case when we want to delete
+a checkpoint.
+
+This patch adds tracking of which images need to be relabelled when
+calculating the transaction, the code to relabel them and rollback.
+
+To verify that stuff works we also output the list of images to relabel
+into the test case output files in qemublocktest.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 8e94e290104ffb5d9db051ab0b0ff36f58dbc943)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <36c2dc7f5d0d59aac90b2e272983f72476b00661.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c                    | 35 ++++++++++++++++---
+ src/qemu/qemu_checkpoint.h                    |  3 +-
+ tests/qemublocktest.c                         | 19 ++++++++--
+ .../snapshots-intermediate1-out.json          |  2 ++
+ .../snapshots-intermediate2-out.json          |  3 ++
+ .../snapshots-intermediate3-out.json          |  2 ++
+ .../snapshots-noparent-out.json               |  4 +++
+ ...ynthetic-checkpoint-intermediate1-out.json |  2 ++
+ ...ynthetic-checkpoint-intermediate2-out.json |  2 ++
+ ...ynthetic-checkpoint-intermediate3-out.json |  2 ++
+ ...ots-synthetic-checkpoint-noparent-out.json |  4 +++
+ 11 files changed, 70 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 55061bbf76..59b7f63fdc 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -155,7 +155,8 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
+                                  const char *delbitmap,
+                                  const char *parentbitmap,
+                                  virJSONValuePtr actions,
+-                                 const char *diskdst)
++                                 const char *diskdst,
++                                 GSList **reopenimages)
+ {
+     virStorageSourcePtr n = src;
+ 
+@@ -235,6 +236,9 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
+                                                srcbitmap->name) < 0)
+             return -1;
+ 
++        if (n != src)
++            *reopenimages = g_slist_prepend(*reopenimages, n);
++
+         n = n->backingStore;
+     }
+ 
+@@ -250,9 +254,12 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     virQEMUDriverPtr driver = priv->driver;
+     g_autoptr(virHashTable) blockNamedNodeData = NULL;
+-    int rc;
++    int rc = -1;
+     g_autoptr(virJSONValue) actions = NULL;
+     size_t i;
++    g_autoptr(GSList) reopenimages = NULL;
++    g_autoptr(GSList) relabelimages = NULL;
++    GSList *next;
+ 
+     if (!(actions = virJSONValueNewArray()))
+         return -1;
+@@ -284,16 +291,34 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+ 
+         if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData,
+                                              chkdisk->bitmap, parentbitmap,
+-                                             actions, domdisk->dst) < 0)
++                                             actions, domdisk->dst,
++                                             &reopenimages) < 0)
+             return -1;
+     }
+ 
++    /* label any non-top images for read-write access */
++    for (next = reopenimages; next; next = next->next) {
++        virStorageSourcePtr src = next->data;
++
++        if (qemuDomainStorageSourceAccessAllow(driver, vm, src, false, false) < 0)
++            goto relabel;
++
++        relabelimages = g_slist_prepend(relabelimages, src);
++    }
++
+     qemuDomainObjEnterMonitor(driver, vm);
+     rc = qemuMonitorTransaction(priv->mon, &actions);
+-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
++    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+         return -1;
+ 
+-    return 0;
++ relabel:
++    for (next = relabelimages; next; next = next->next) {
++        virStorageSourcePtr src = next->data;
++
++        ignore_value(qemuDomainStorageSourceAccessAllow(driver, vm, src, true, false));
++    }
++
++    return rc;
+ }
+ 
+ 
+diff --git a/src/qemu/qemu_checkpoint.h b/src/qemu/qemu_checkpoint.h
+index 976b1eed0f..cf1e9e46cb 100644
+--- a/src/qemu/qemu_checkpoint.h
++++ b/src/qemu/qemu_checkpoint.h
+@@ -78,4 +78,5 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
+                                  const char *delbitmap,
+                                  const char *parentbitmap,
+                                  virJSONValuePtr actions,
+-                                 const char *diskdst);
++                                 const char *diskdst,
++                                 GSList **reopenimages);
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 2e5927f3c1..ed8b061e2e 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -717,6 +717,9 @@ testQemuCheckpointDeleteMerge(const void *opaque)
+     g_autoptr(virJSONValue) actions = NULL;
+     g_autoptr(virJSONValue) nodedatajson = NULL;
+     g_autoptr(virHashTable) nodedata = NULL;
++    g_autoptr(GSList) reopenimages = NULL;
++    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
++    GSList *tmp;
+ 
+     expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir,
+                                  checkpointDeletePrefix, data->name);
+@@ -738,14 +741,26 @@ testQemuCheckpointDeleteMerge(const void *opaque)
+                                          data->deletebitmap,
+                                          data->parentbitmap,
+                                          actions,
+-                                         "testdisk") < 0) {
++                                         "testdisk",
++                                         &reopenimages) < 0) {
+         VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n");
+         return -1;
+     }
+ 
+-    if (!(actual = virJSONValueToString(actions, true)))
++    if (virJSONValueToBuffer(actions, &buf, true) < 0)
+         return -1;
+ 
++    if (reopenimages) {
++        virBufferAddLit(&buf, "reopen nodes:\n");
++
++        for (tmp = reopenimages; tmp; tmp = tmp->next) {
++            virStorageSourcePtr src = tmp->data;
++            virBufferAsprintf(&buf, "%s\n", src->nodeformat);
++        }
++    }
++
++    actual = virBufferContentAndReset(&buf);
++
+     return virTestCompareToFile(actual, expectpath);
+ }
+ 
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
+index 29fefeea63..c9bda3a17a 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
+@@ -20,3 +20,5 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-3-format
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
+index 4da21a9df7..8a0e3f2cff 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
+@@ -57,3 +57,6 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-3-format
++libvirt-2-format
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
+index dc87dd60b8..211bc40baf 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
+@@ -57,3 +57,5 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-2-format
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
+index 45a84b47c2..f750f44da2 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
+@@ -21,3 +21,7 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-5-format
++libvirt-4-format
++libvirt-3-format
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
+index e979691e6f..d7e6d18637 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
+@@ -27,3 +27,5 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-3-format
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
+index e82098918a..cfbff010c2 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
+@@ -30,3 +30,5 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-2-format
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
+index dc87dd60b8..211bc40baf 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
+@@ -57,3 +57,5 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-2-format
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
+index 45a84b47c2..f750f44da2 100644
+--- a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
+@@ -21,3 +21,7 @@
+     }
+   }
+ ]
++reopen nodes:
++libvirt-5-format
++libvirt-4-format
++libvirt-3-format
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-Use-disk-definition-directly-when-creating-checkpoint.patch b/SOURCES/libvirt-qemu-checkpoint-Use-disk-definition-directly-when-creating-checkpoint.patch
new file mode 100644
index 0000000..5185ed5
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-Use-disk-definition-directly-when-creating-checkpoint.patch
@@ -0,0 +1,62 @@
+From dc4997ee498486135e46ca0e121835935bbf26db Mon Sep 17 00:00:00 2001
+Message-Id: <dc4997ee498486135e46ca0e121835935bbf26db@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:53 +0100
+Subject: [PATCH] qemu: checkpoint: Use disk definition directly when creating
+ checkpoint
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Lookup the whole disk definition rather than just the node name.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 7973f7d7926ac9dbc5464e6be6eb2aaacecc2251)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <d4ad0d55d36cfc8c1af9a997930936364e94648c.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 0aa854324b..03a8321135 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -320,12 +320,16 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
+ 
+     for (i = 0; i < def->ndisks; i++) {
+         virDomainCheckpointDiskDef *chkdisk = &def->disks[i];
+-        const char *node;
++        virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
+ 
+-        if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
++        /* checkpoint definition validator mandates that the corresponding
++         * domdisk should exist */
++        if (!domdisk ||
++            chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+             continue;
+-        node = qemuDomainDiskNodeFormatLookup(vm, chkdisk->name);
+-        if (qemuMonitorTransactionBitmapAdd(actions, node, chkdisk->bitmap, true, false, 0) < 0)
++
++        if (qemuMonitorTransactionBitmapAdd(actions, domdisk->src->nodeformat,
++                                            chkdisk->bitmap, true, false, 0) < 0)
+             return -1;
+ 
+         /* We only want one active bitmap for a disk along the
+@@ -348,7 +352,9 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
+                 if (STRNEQ(chkdisk->name, disk2->name) ||
+                     disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+                     continue;
+-                if (qemuMonitorTransactionBitmapDisable(actions, node, disk2->bitmap) < 0)
++                if (qemuMonitorTransactionBitmapDisable(actions,
++                                                        domdisk->src->nodeformat,
++                                                        disk2->bitmap) < 0)
+                     return -1;
+                 search_parents = false;
+                 break;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointAddActions.patch b/SOURCES/libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointAddActions.patch
new file mode 100644
index 0000000..d407d7d
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointAddActions.patch
@@ -0,0 +1,58 @@
+From 7a23710e912348efb55a98e7c6e6d1cc7f452b1f Mon Sep 17 00:00:00 2001
+Message-Id: <7a23710e912348efb55a98e7c6e6d1cc7f452b1f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:52 +0100
+Subject: [PATCH] qemu: checkpoint: rename disk->chkdisk in
+ qemuCheckpointAddActions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Upcoming patches will also use the domain disk definition. Rename disk
+to chkdisk for clarity.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit f3e0a45a00465a6f19f510f7806ade1764a7e162)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <ef78ad0aa581d70c4f007665cd00988796c02c8f.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index d347b8fc6c..0aa854324b 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -319,13 +319,13 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
+     bool search_parents;
+ 
+     for (i = 0; i < def->ndisks; i++) {
+-        virDomainCheckpointDiskDef *disk = &def->disks[i];
++        virDomainCheckpointDiskDef *chkdisk = &def->disks[i];
+         const char *node;
+ 
+-        if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
++        if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+             continue;
+-        node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
+-        if (qemuMonitorTransactionBitmapAdd(actions, node, disk->bitmap, true, false, 0) < 0)
++        node = qemuDomainDiskNodeFormatLookup(vm, chkdisk->name);
++        if (qemuMonitorTransactionBitmapAdd(actions, node, chkdisk->bitmap, true, false, 0) < 0)
+             return -1;
+ 
+         /* We only want one active bitmap for a disk along the
+@@ -345,7 +345,7 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
+                 virDomainCheckpointDiskDef *disk2;
+ 
+                 disk2 = &olddef->disks[j];
+-                if (STRNEQ(disk->name, disk2->name) ||
++                if (STRNEQ(chkdisk->name, disk2->name) ||
+                     disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+                     continue;
+                 if (qemuMonitorTransactionBitmapDisable(actions, node, disk2->bitmap) < 0)
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointDiscardBitmaps.patch b/SOURCES/libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointDiscardBitmaps.patch
new file mode 100644
index 0000000..8ea84ba
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointDiscardBitmaps.patch
@@ -0,0 +1,75 @@
+From 4a0a0c37c0f3ea2c8eb6b96b07c990d7a4ce1c8b Mon Sep 17 00:00:00 2001
+Message-Id: <4a0a0c37c0f3ea2c8eb6b96b07c990d7a4ce1c8b@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:51 +0100
+Subject: [PATCH] qemu: checkpoint: rename disk->chkdisk in
+ qemuCheckpointDiscardBitmaps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Upcoming patches will also use the domain disk definition. Rename disk
+to chkdisk for clarity.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit a303e8ea47c9a2caa39ae744c0bf9a2f724a6137)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <0799859ad288a747f1d12dd07bbb403053d78457.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 9ff3129570..d347b8fc6c 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -124,13 +124,13 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+         return -1;
+ 
+     for (i = 0; i < chkdef->ndisks; i++) {
+-        virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
++        virDomainCheckpointDiskDef *chkdisk = &chkdef->disks[i];
+         const char *node;
+ 
+-        if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
++        if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+             continue;
+ 
+-        node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
++        node = qemuDomainDiskNodeFormatLookup(vm, chkdisk->name);
+         /* If any ancestor checkpoint has a bitmap for the same
+          * disk, then this bitmap must be merged to the
+          * ancestor. */
+@@ -145,7 +145,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                 g_autoptr(virJSONValue) arr = NULL;
+ 
+                 disk2 = &parentdef->disks[j];
+-                if (STRNEQ(disk->name, disk2->name) ||
++                if (STRNEQ(chkdisk->name, disk2->name) ||
+                     disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+                     continue;
+                 search_parents = false;
+@@ -153,7 +153,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                 if (!(arr = virJSONValueNewArray()))
+                     return -1;
+ 
+-                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
++                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, chkdisk->bitmap) < 0)
+                     return -1;
+ 
+                 if (chkcurrent) {
+@@ -166,7 +166,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+             }
+         }
+ 
+-        if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
++        if (qemuMonitorTransactionBitmapRemove(actions, node, chkdisk->bitmap) < 0)
+             return -1;
+     }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-split-out-checkpoint-deletion-bitmaps.patch b/SOURCES/libvirt-qemu-checkpoint-split-out-checkpoint-deletion-bitmaps.patch
new file mode 100644
index 0000000..6beba43
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-split-out-checkpoint-deletion-bitmaps.patch
@@ -0,0 +1,192 @@
+From 628b1f392c5fb2e3a492640a9069edd244a7b150 Mon Sep 17 00:00:00 2001
+Message-Id: <628b1f392c5fb2e3a492640a9069edd244a7b150@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:50 +0100
+Subject: [PATCH] qemu: checkpoint: split out checkpoint deletion bitmaps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+qemuCheckpointDiscard is a massive function that can be separated into
+smaller bits. Extract the part that actually modifies the disk from the
+metadata handling.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 44e1b85717b9a4e6df24f9cbf846627e4f29b859)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <b6cdc7883d1f3b16e8a496dac6e9ec046ec2c4ea.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 137 ++++++++++++++++++++-----------------
+ 1 file changed, 76 insertions(+), 61 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index d13d4c2a37..9ff3129570 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -104,6 +104,81 @@ qemuCheckpointWriteMetadata(virDomainObjPtr vm,
+ }
+ 
+ 
++static int
++qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
++                             virDomainCheckpointDefPtr chkdef,
++                             bool chkcurrent,
++                             virDomainMomentObjPtr parent)
++{
++    qemuDomainObjPrivatePtr priv = vm->privateData;
++    virQEMUDriverPtr driver = priv->driver;
++    virDomainMomentObjPtr moment;
++    virDomainCheckpointDefPtr parentdef = NULL;
++    bool search_parents;
++    int rc;
++    g_autoptr(virJSONValue) actions = NULL;
++    size_t i;
++    size_t j;
++
++    if (!(actions = virJSONValueNewArray()))
++        return -1;
++
++    for (i = 0; i < chkdef->ndisks; i++) {
++        virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
++        const char *node;
++
++        if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
++            continue;
++
++        node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
++        /* If any ancestor checkpoint has a bitmap for the same
++         * disk, then this bitmap must be merged to the
++         * ancestor. */
++        search_parents = true;
++        for (moment = parent;
++             search_parents && moment;
++             moment = virDomainCheckpointFindByName(vm->checkpoints,
++                                                    parentdef->parent.parent_name)) {
++            parentdef = virDomainCheckpointObjGetDef(moment);
++            for (j = 0; j < parentdef->ndisks; j++) {
++                virDomainCheckpointDiskDef *disk2;
++                g_autoptr(virJSONValue) arr = NULL;
++
++                disk2 = &parentdef->disks[j];
++                if (STRNEQ(disk->name, disk2->name) ||
++                    disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
++                    continue;
++                search_parents = false;
++
++                if (!(arr = virJSONValueNewArray()))
++                    return -1;
++
++                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
++                    return -1;
++
++                if (chkcurrent) {
++                    if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
++                        return -1;
++                }
++
++                if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
++                    return -1;
++            }
++        }
++
++        if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
++            return -1;
++    }
++
++    qemuDomainObjEnterMonitor(driver, vm);
++    rc = qemuMonitorTransaction(priv->mon, &actions);
++    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
++        return -1;
++
++    return 0;
++}
++
++
+ static int
+ qemuCheckpointDiscard(virQEMUDriverPtr driver,
+                       virDomainObjPtr vm,
+@@ -112,9 +187,6 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
+                       bool metadata_only)
+ {
+     virDomainMomentObjPtr parent = NULL;
+-    virDomainMomentObjPtr moment;
+-    virDomainCheckpointDefPtr parentdef = NULL;
+-    size_t i, j;
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+     g_autofree char *chkFile = NULL;
+     bool chkcurrent = chk == virDomainCheckpointGetCurrent(vm->checkpoints);
+@@ -129,67 +201,10 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
+                               chk->def->name);
+ 
+     if (!metadata_only) {
+-        qemuDomainObjPrivatePtr priv = vm->privateData;
+-        bool search_parents;
+         virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
+-        int rc;
+-        g_autoptr(virJSONValue) actions = NULL;
+-
+-        if (!(actions = virJSONValueNewArray()))
+-            return -1;
+-
+         parent = virDomainCheckpointFindByName(vm->checkpoints,
+                                                chk->def->parent_name);
+-        for (i = 0; i < chkdef->ndisks; i++) {
+-            virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
+-            const char *node;
+-
+-            if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+-                continue;
+-
+-            node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
+-            /* If any ancestor checkpoint has a bitmap for the same
+-             * disk, then this bitmap must be merged to the
+-             * ancestor. */
+-            search_parents = true;
+-            for (moment = parent;
+-                 search_parents && moment;
+-                 moment = virDomainCheckpointFindByName(vm->checkpoints,
+-                                                        parentdef->parent.parent_name)) {
+-                parentdef = virDomainCheckpointObjGetDef(moment);
+-                for (j = 0; j < parentdef->ndisks; j++) {
+-                    virDomainCheckpointDiskDef *disk2;
+-                    g_autoptr(virJSONValue) arr = NULL;
+-
+-                    disk2 = &parentdef->disks[j];
+-                    if (STRNEQ(disk->name, disk2->name) ||
+-                        disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+-                        continue;
+-                    search_parents = false;
+-
+-                    if (!(arr = virJSONValueNewArray()))
+-                        return -1;
+-
+-                    if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
+-                        return -1;
+-
+-                    if (chkcurrent) {
+-                        if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
+-                            return -1;
+-                    }
+-
+-                    if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
+-                        return -1;
+-                }
+-            }
+-
+-            if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
+-                return -1;
+-        }
+-
+-        qemuDomainObjEnterMonitor(driver, vm);
+-        rc = qemuMonitorTransaction(priv->mon, &actions);
+-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
++        if (qemuCheckpointDiscardBitmaps(vm, chkdef, chkcurrent, parent) < 0)
+             return -1;
+     }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-checkpoint-tolerate-missing-disks-on-checkpoint-deletion.patch b/SOURCES/libvirt-qemu-checkpoint-tolerate-missing-disks-on-checkpoint-deletion.patch
new file mode 100644
index 0000000..d638b92
--- /dev/null
+++ b/SOURCES/libvirt-qemu-checkpoint-tolerate-missing-disks-on-checkpoint-deletion.patch
@@ -0,0 +1,85 @@
+From d59261d209da6f3dd4dfef7fab327de7cbb6e7ff Mon Sep 17 00:00:00 2001
+Message-Id: <d59261d209da6f3dd4dfef7fab327de7cbb6e7ff@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:54 +0100
+Subject: [PATCH] qemu: checkpoint: tolerate missing disks on checkpoint
+ deletion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If a disk is unplugged and then the user tries to delete a checkpoint
+the code would try to use NULL node name as it was not checked.
+
+Fix this by fetching the whole disk definition object and verifying it
+was found.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit f19248a1395e59abbd68ac31af3d9bd1273555bf)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <bab5a0f3d17855a657a6b7de4699a72e176780d6.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 03a8321135..326707e098 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -125,12 +125,15 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+ 
+     for (i = 0; i < chkdef->ndisks; i++) {
+         virDomainCheckpointDiskDef *chkdisk = &chkdef->disks[i];
+-        const char *node;
++        virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
++
++        /* domdisk can be missing e.g. when it was unplugged */
++        if (!domdisk)
++            continue;
+ 
+         if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+             continue;
+ 
+-        node = qemuDomainDiskNodeFormatLookup(vm, chkdisk->name);
+         /* If any ancestor checkpoint has a bitmap for the same
+          * disk, then this bitmap must be merged to the
+          * ancestor. */
+@@ -153,20 +156,28 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                 if (!(arr = virJSONValueNewArray()))
+                     return -1;
+ 
+-                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, chkdisk->bitmap) < 0)
++                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
++                                                                     domdisk->src->nodeformat,
++                                                                     chkdisk->bitmap) < 0)
+                     return -1;
+ 
+                 if (chkcurrent) {
+-                    if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
++                    if (qemuMonitorTransactionBitmapEnable(actions,
++                                                           domdisk->src->nodeformat,
++                                                           disk2->bitmap) < 0)
+                         return -1;
+                 }
+ 
+-                if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
++                if (qemuMonitorTransactionBitmapMerge(actions,
++                                                      domdisk->src->nodeformat,
++                                                      disk2->bitmap, &arr) < 0)
+                     return -1;
+             }
+         }
+ 
+-        if (qemuMonitorTransactionBitmapRemove(actions, node, chkdisk->bitmap) < 0)
++        if (qemuMonitorTransactionBitmapRemove(actions,
++                                               domdisk->src->nodeformat,
++                                               chkdisk->bitmap) < 0)
+             return -1;
+     }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-do-not-revert-to-NULL-bandwidth.patch b/SOURCES/libvirt-qemu-do-not-revert-to-NULL-bandwidth.patch
new file mode 100644
index 0000000..370f87d
--- /dev/null
+++ b/SOURCES/libvirt-qemu-do-not-revert-to-NULL-bandwidth.patch
@@ -0,0 +1,45 @@
+From ce01c67e13d27e578d13192bb20b585f1707f672 Mon Sep 17 00:00:00 2001
+Message-Id: <ce01c67e13d27e578d13192bb20b585f1707f672@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Mon, 10 Feb 2020 17:05:53 +0100
+Subject: [PATCH] qemu: do not revert to NULL bandwidth
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Otherwise an attempt to set an invalid value:
+  virsh domiftune rhel8.2 vnet0 --outbound 4294968
+on an interface with no bandwidth set crashes.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Fixes: f02e21cb3379a41cd42f2d8116f2d10dabace83b
+https://bugzilla.redhat.com/show_bug.cgi?id=1800505
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit bd622e2a211aad449b54683e2ebd5e980418dd7c)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <6096c4347521d1493728cc7842f6ad455665b744.1581350626.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_driver.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index caeb76a20c..08f492fa24 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -11646,8 +11646,10 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
+                                                net->bandwidth,
+                                                false,
+                                                !virDomainNetTypeSharesHostView(net)));
+-            ignore_value(virDomainNetBandwidthUpdate(net,
+-                                                     net->bandwidth));
++            if (net->bandwidth) {
++                ignore_value(virDomainNetBandwidthUpdate(net,
++                                                         net->bandwidth));
++            }
+             goto endjob;
+         }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-domain-Convert-detected-iso-image-format-into-raw.patch b/SOURCES/libvirt-qemu-domain-Convert-detected-iso-image-format-into-raw.patch
new file mode 100644
index 0000000..94191ec
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Convert-detected-iso-image-format-into-raw.patch
@@ -0,0 +1,43 @@
+From 627b980c628dd06fb9995e83130fbaa858d4087f Mon Sep 17 00:00:00 2001
+Message-Id: <627b980c628dd06fb9995e83130fbaa858d4087f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:42 +0100
+Subject: [PATCH] qemu: domain: Convert detected 'iso' image format into 'raw'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+While our code can detect ISO as a separate format, qemu does not use it
+as such and just passes it through as raw. Add conversion for detected
+parts of the backing chain so that the validation code does not reject
+it right away.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 3c6e6f55a5ded357c39b92629cd523e51f6ca8f9)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <2c6cfa942acf0d7fe56046122b23780ee5c0d777.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index f037f0812e..ed35260712 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -11598,6 +11598,10 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
+         return -1;
+ 
+     for (n = src->backingStore; virStorageSourceIsBacking(n); n = n->backingStore) {
++        /* convert detected ISO format to 'raw' as qemu would not understand it */
++        if (n->format == VIR_STORAGE_FILE_ISO)
++            n->format = VIR_STORAGE_FILE_RAW;
++
+         if (qemuDomainValidateStorageSource(n, priv->qemuCaps) < 0)
+             return -1;
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-domain-Extract-code-to-determine-topmost-nodename-to-qemuDomainDiskGetTopNodename.patch b/SOURCES/libvirt-qemu-domain-Extract-code-to-determine-topmost-nodename-to-qemuDomainDiskGetTopNodename.patch
new file mode 100644
index 0000000..7687f0f
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Extract-code-to-determine-topmost-nodename-to-qemuDomainDiskGetTopNodename.patch
@@ -0,0 +1,106 @@
+From 4ad02094b6166037a04310dbf9a3eb2dcc21ca61 Mon Sep 17 00:00:00 2001
+Message-Id: <4ad02094b6166037a04310dbf9a3eb2dcc21ca61@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:37 +0100
+Subject: [PATCH] qemu: domain: Extract code to determine topmost nodename to
+ qemuDomainDiskGetTopNodename
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are more places which require getting the topmost nodename to be
+passed to qemu. Separate it out into a new function.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 0b0f389335e5d11150fa60561cae960f20d5ca44)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1792195
+Message-Id: <b3c89cd0893677d101bc8f491bbd323db6133b19.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 38 ++++++++++++++++++++++++++------------
+ src/qemu/qemu_domain.h |  4 ++++
+ 2 files changed, 30 insertions(+), 12 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index e37404340f..be9de75909 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -11598,6 +11598,31 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
+ }
+ 
+ 
++/**
++ * qemuDomainDiskGetTopNodename:
++ *
++ * @disk: disk definition object
++ *
++ * Returns the pointer to the node-name of the topmost layer used by @disk as
++ * backend. Currently returns the nodename of the copy-on-read filter if enabled
++ * or the nodename of the top image's format driver. Empty disks return NULL.
++ * This must be used only when VIR_QEMU_CAPS_BLOCKDEV is enabled.
++ */
++const char *
++qemuDomainDiskGetTopNodename(virDomainDiskDefPtr disk)
++{
++    qemuDomainDiskPrivatePtr priv = QEMU_DOMAIN_DISK_PRIVATE(disk);
++
++    if (virStorageSourceIsEmpty(disk->src))
++        return NULL;
++
++    if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON)
++        return priv->nodeCopyOnRead;
++
++    return disk->src->nodeformat;
++}
++
++
+ /**
+  * qemuDomainDiskGetBackendAlias:
+  * @disk: disk definition
+@@ -11617,8 +11642,6 @@ qemuDomainDiskGetBackendAlias(virDomainDiskDefPtr disk,
+                               virQEMUCapsPtr qemuCaps,
+                               char **backendAlias)
+ {
+-    qemuDomainDiskPrivatePtr priv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+-    const char *nodename = NULL;
+     *backendAlias = NULL;
+ 
+     if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
+@@ -11628,16 +11651,7 @@ qemuDomainDiskGetBackendAlias(virDomainDiskDefPtr disk,
+         return 0;
+     }
+ 
+-    if (virStorageSourceIsEmpty(disk->src))
+-        return 0;
+-
+-    if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON)
+-        nodename = priv->nodeCopyOnRead;
+-    else
+-        nodename = disk->src->nodeformat;
+-
+-    *backendAlias = g_strdup(nodename);
+-
++    *backendAlias = g_strdup(qemuDomainDiskGetTopNodename(disk));
+     return 0;
+ }
+ 
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index 60b80297fa..d1ab5da2c7 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -881,6 +881,10 @@ int qemuDomainStorageFileInit(virQEMUDriverPtr driver,
+                               virStorageSourcePtr parent);
+ char *qemuDomainStorageAlias(const char *device, int depth);
+ 
++const char *
++qemuDomainDiskGetTopNodename(virDomainDiskDefPtr disk)
++    ATTRIBUTE_NONNULL(1);
++
+ int qemuDomainDiskGetBackendAlias(virDomainDiskDefPtr disk,
+                                   virQEMUCapsPtr qemuCaps,
+                                   char **backendAlias)
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-domain-Extract-formatting-of-commit-blockjob-data-into-a-function.patch b/SOURCES/libvirt-qemu-domain-Extract-formatting-of-commit-blockjob-data-into-a-function.patch
new file mode 100644
index 0000000..607dc57
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Extract-formatting-of-commit-blockjob-data-into-a-function.patch
@@ -0,0 +1,72 @@
+From f306de1577b94e303cc6e6d50e48459751dfa02a Mon Sep 17 00:00:00 2001
+Message-Id: <f306de1577b94e303cc6e6d50e48459751dfa02a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:20 +0100
+Subject: [PATCH] qemu: domain: Extract formatting of 'commit' blockjob data
+ into a function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+I'll be adding more fields to care about so splitting the code out will
+be better long-term.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Pavel Mores <pmores@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit c72e9064ce2fd114aa5ac046f935d2a5661c8d20)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <98f3090755fcdb4b54deb37a004c9f0d0e40db31.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index cc47e7a2f0..a8ac68af92 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -2599,6 +2599,24 @@ qemuDomainObjPrivateXMLFormatBlockjobFormatSource(virBufferPtr buf,
+ }
+ 
+ 
++static void
++qemuDomainPrivateBlockJobFormatCommit(qemuBlockJobDataPtr job,
++                                      virBufferPtr buf)
++{
++    if (job->data.commit.base)
++        virBufferAsprintf(buf, "<base node='%s'/>\n", job->data.commit.base->nodeformat);
++
++    if (job->data.commit.top)
++        virBufferAsprintf(buf, "<top node='%s'/>\n", job->data.commit.top->nodeformat);
++
++    if (job->data.commit.topparent)
++        virBufferAsprintf(buf, "<topparent node='%s'/>\n", job->data.commit.topparent->nodeformat);
++
++    if (job->data.commit.deleteCommittedImages)
++        virBufferAddLit(buf, "<deleteCommittedImages/>\n");
++}
++
++
+ static int
+ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
+                                               const void *name G_GNUC_UNUSED,
+@@ -2658,14 +2676,7 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
+ 
+         case QEMU_BLOCKJOB_TYPE_COMMIT:
+         case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
+-            if (job->data.commit.base)
+-                virBufferAsprintf(&childBuf, "<base node='%s'/>\n", job->data.commit.base->nodeformat);
+-            if (job->data.commit.top)
+-                virBufferAsprintf(&childBuf, "<top node='%s'/>\n", job->data.commit.top->nodeformat);
+-            if (job->data.commit.topparent)
+-                virBufferAsprintf(&childBuf, "<topparent node='%s'/>\n", job->data.commit.topparent->nodeformat);
+-            if (job->data.commit.deleteCommittedImages)
+-                virBufferAddLit(&childBuf, "<deleteCommittedImages/>\n");
++            qemuDomainPrivateBlockJobFormatCommit(job, &childBuf);
+             break;
+ 
+         case QEMU_BLOCKJOB_TYPE_CREATE:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-domain-Extract-parsing-of-commit-blockjob-data-into-a-function.patch b/SOURCES/libvirt-qemu-domain-Extract-parsing-of-commit-blockjob-data-into-a-function.patch
new file mode 100644
index 0000000..0dddbe1
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Extract-parsing-of-commit-blockjob-data-into-a-function.patch
@@ -0,0 +1,104 @@
+From 4cbdc7ecefe8351e9e354c1906aba46869f220fd Mon Sep 17 00:00:00 2001
+Message-Id: <4cbdc7ecefe8351e9e354c1906aba46869f220fd@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:21 +0100
+Subject: [PATCH] qemu: domain: Extract parsing of 'commit' blockjob data into
+ a function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+I'll be adding more fields to care about so splitting the code out will
+be better long-term.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Pavel Mores <pmores@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 38d0dd08d61446455ff54e0a7b97b1a48054b7c5)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <9689f027815d6fc799bae46ce9c12c3d55d9c728.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 57 ++++++++++++++++++++++++++----------------
+ 1 file changed, 36 insertions(+), 21 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index a8ac68af92..0faf042145 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -3236,6 +3236,40 @@ qemuDomainObjPrivateXMLParseBlockjobNodename(qemuBlockJobDataPtr job,
+ }
+ 
+ 
++static int
++qemuDomainObjPrivateXMLParseBlockjobDataCommit(qemuBlockJobDataPtr job,
++                                               xmlXPathContextPtr ctxt)
++{
++    if (job->type == QEMU_BLOCKJOB_TYPE_COMMIT) {
++        qemuDomainObjPrivateXMLParseBlockjobNodename(job,
++                                                     "string(./topparent/@node)",
++                                                     &job->data.commit.topparent,
++                                                     ctxt);
++
++        if (!job->data.commit.topparent)
++            return -1;
++    }
++
++    qemuDomainObjPrivateXMLParseBlockjobNodename(job,
++                                                 "string(./top/@node)",
++                                                 &job->data.commit.top,
++                                                 ctxt);
++    qemuDomainObjPrivateXMLParseBlockjobNodename(job,
++                                                 "string(./base/@node)",
++                                                 &job->data.commit.base,
++                                                 ctxt);
++
++    if (virXPathNode("./deleteCommittedImages", ctxt))
++        job->data.commit.deleteCommittedImages = true;
++
++    if (!job->data.commit.top ||
++        !job->data.commit.base)
++        return -1;
++
++    return 0;
++}
++
++
+ static void
+ qemuDomainObjPrivateXMLParseBlockjobDataSpecific(qemuBlockJobDataPtr job,
+                                                  xmlXPathContextPtr ctxt,
+@@ -3255,29 +3289,10 @@ qemuDomainObjPrivateXMLParseBlockjobDataSpecific(qemuBlockJobDataPtr job,
+             break;
+ 
+         case QEMU_BLOCKJOB_TYPE_COMMIT:
+-            qemuDomainObjPrivateXMLParseBlockjobNodename(job,
+-                                                         "string(./topparent/@node)",
+-                                                         &job->data.commit.topparent,
+-                                                         ctxt);
+-
+-            if (!job->data.commit.topparent)
+-                goto broken;
+-
+-            G_GNUC_FALLTHROUGH;
+         case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
+-            qemuDomainObjPrivateXMLParseBlockjobNodename(job,
+-                                                         "string(./top/@node)",
+-                                                         &job->data.commit.top,
+-                                                         ctxt);
+-            qemuDomainObjPrivateXMLParseBlockjobNodename(job,
+-                                                         "string(./base/@node)",
+-                                                         &job->data.commit.base,
+-                                                         ctxt);
+-            if (virXPathNode("./deleteCommittedImages", ctxt))
+-                job->data.commit.deleteCommittedImages = true;
+-            if (!job->data.commit.top ||
+-                !job->data.commit.base)
++            if (qemuDomainObjPrivateXMLParseBlockjobDataCommit(job, ctxt) < 0)
+                 goto broken;
++
+             break;
+ 
+         case QEMU_BLOCKJOB_TYPE_CREATE:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-domain-Refactor-formatting-of-node-names-into-status-XML.patch b/SOURCES/libvirt-qemu-domain-Refactor-formatting-of-node-names-into-status-XML.patch
new file mode 100644
index 0000000..6b8c059
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Refactor-formatting-of-node-names-into-status-XML.patch
@@ -0,0 +1,51 @@
+From 3559a27948b48c93295867ff5c8390aad0456a34 Mon Sep 17 00:00:00 2001
+Message-Id: <3559a27948b48c93295867ff5c8390aad0456a34@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:12 +0100
+Subject: [PATCH] qemu: domain: Refactor formatting of node names into status
+ XML
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use virXMLFormatElement to simplify the logic.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 9fb7ccb3cfc13fc58d9575813f276fa049368cd9)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <772d21f8bcf6d76ceec0d4dc0dc2c507cab70912.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 8e0e919f9a..cf069e2b79 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -2402,15 +2402,12 @@ qemuStorageSourcePrivateDataFormat(virStorageSourcePtr src,
+ {
+     g_auto(virBuffer) tmp = VIR_BUFFER_INIT_CHILD(buf);
+     qemuDomainStorageSourcePrivatePtr srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
++    g_auto(virBuffer) nodenamesChildBuf = VIR_BUFFER_INIT_CHILD(buf);
+ 
+-    if (src->nodestorage || src->nodeformat) {
+-        virBufferAddLit(buf, "<nodenames>\n");
+-        virBufferAdjustIndent(buf, 2);
+-        virBufferEscapeString(buf, "<nodename type='storage' name='%s'/>\n", src->nodestorage);
+-        virBufferEscapeString(buf, "<nodename type='format' name='%s'/>\n", src->nodeformat);
+-        virBufferAdjustIndent(buf, -2);
+-        virBufferAddLit(buf, "</nodenames>\n");
+-    }
++    virBufferEscapeString(&nodenamesChildBuf, "<nodename type='storage' name='%s'/>\n", src->nodestorage);
++    virBufferEscapeString(&nodenamesChildBuf, "<nodename type='format' name='%s'/>\n", src->nodeformat);
++
++    virXMLFormatElement(buf, "nodenames", NULL, &nodenamesChildBuf);
+ 
+     if (src->pr)
+         virBufferAsprintf(buf, "<reservations mgralias='%s'/>\n", src->pr->mgralias);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-domain-Remove-unused-qemuDomainDiskNodeFormatLookup.patch b/SOURCES/libvirt-qemu-domain-Remove-unused-qemuDomainDiskNodeFormatLookup.patch
new file mode 100644
index 0000000..404af1c
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Remove-unused-qemuDomainDiskNodeFormatLookup.patch
@@ -0,0 +1,66 @@
+From 448ed3bee3e5b3a12a7bd0acd40ca0729214fba3 Mon Sep 17 00:00:00 2001
+Message-Id: <448ed3bee3e5b3a12a7bd0acd40ca0729214fba3@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:55 +0100
+Subject: [PATCH] qemu: domain: Remove unused qemuDomainDiskNodeFormatLookup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The function has no users now and there's no need for it as the common
+pattern is to look up the whole disk object anyways.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 180b3422e9a3391a0ee59d0076730ba85778fc7a)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <b6ab98ea54aced2d9aeb9abdca30fc4669b92bbe.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 14 --------------
+ src/qemu/qemu_domain.h |  3 ---
+ 2 files changed, 17 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index be9de75909..94efcdf9b1 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -12092,20 +12092,6 @@ qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk,
+ }
+ 
+ 
+-/* Return the format node name for a given disk of an online guest */
+-const char *
+-qemuDomainDiskNodeFormatLookup(virDomainObjPtr vm,
+-                               const char *disk)
+-{
+-    size_t i;
+-
+-    for (i = 0; i < vm->def->ndisks; i++) {
+-        if (STREQ(vm->def->disks[i]->dst, disk))
+-            return vm->def->disks[i]->src->nodeformat;
+-    }
+-    return NULL;
+-}
+-
+ bool
+ qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk)
+ {
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index d1ab5da2c7..cdcb6ecc7a 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -865,9 +865,6 @@ int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
+ bool qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk,
+                                    virDomainDiskDefPtr orig_disk);
+ 
+-const char *qemuDomainDiskNodeFormatLookup(virDomainObjPtr vm,
+-                                           const char *disk);
+-
+ void qemuDomainGetImageIds(virQEMUDriverConfigPtr cfg,
+                            virDomainObjPtr vm,
+                            virStorageSourcePtr src,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-domain-Store-data-for-secret-object-representing-http-cookies.patch b/SOURCES/libvirt-qemu-domain-Store-data-for-secret-object-representing-http-cookies.patch
new file mode 100644
index 0000000..cb10075
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Store-data-for-secret-object-representing-http-cookies.patch
@@ -0,0 +1,105 @@
+From 270be96a2730304de8f5dd1d24dd367c9ed52b22 Mon Sep 17 00:00:00 2001
+Message-Id: <270be96a2730304de8f5dd1d24dd367c9ed52b22@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:02 +0100
+Subject: [PATCH] qemu: domain: Store data for 'secret' object representing
+ http cookies
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The http cookies can have potentially sensitive values and thus should
+not be leaked into the command line. This means that we'll need to
+instantiate a 'secret' object in qemu to pass the value encrypted.
+
+This patch adds infrastructure for storing of the alias in the status
+XML.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4e8faa5cdc54ce637f760ad4513753e17d2b9a4f)
+
+ Conflicts:
+	src/qemu/qemu_domain.c:
+        Context conflict with missing backport of cleanups. (mentioned
+                                                             earlier)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <b51659e22b0840ca6c5431c4e212445bdeb4c12d.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c                    | 8 +++++++-
+ src/qemu/qemu_domain.h                    | 3 +++
+ tests/qemustatusxml2xmldata/modern-in.xml | 1 +
+ 3 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 2920e699f6..9391bc37e0 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -2341,6 +2341,7 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
+     char *authalias = NULL;
+     char *encalias = NULL;
+     int ret = -1;
++    g_autofree char *httpcookiealias = NULL;
+ 
+     src->nodestorage = virXPathString("string(./nodenames/nodename[@type='storage']/@name)", ctxt);
+     src->nodeformat = virXPathString("string(./nodenames/nodename[@type='format']/@name)", ctxt);
+@@ -2354,8 +2355,9 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
+ 
+     authalias = virXPathString("string(./objects/secret[@type='auth']/@alias)", ctxt);
+     encalias = virXPathString("string(./objects/secret[@type='encryption']/@alias)", ctxt);
++    httpcookiealias = virXPathString("string(./objects/secret[@type='httpcookie']/@alias)", ctxt);
+ 
+-    if (authalias || encalias) {
++    if (authalias || encalias || httpcookiealias) {
+         if (!src->privateData &&
+             !(src->privateData = qemuDomainStorageSourcePrivateNew()))
+             goto cleanup;
+@@ -2367,6 +2369,9 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
+ 
+         if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo, &encalias) < 0)
+             goto cleanup;
++
++        if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->httpcookie, &httpcookiealias) < 0)
++            goto cleanup;
+     }
+ 
+     if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0)
+@@ -2423,6 +2428,7 @@ qemuStorageSourcePrivateDataFormat(virStorageSourcePtr src,
+     if (srcPriv) {
+         qemuStorageSourcePrivateDataFormatSecinfo(&tmp, srcPriv->secinfo, "auth");
+         qemuStorageSourcePrivateDataFormatSecinfo(&tmp, srcPriv->encinfo, "encryption");
++        qemuStorageSourcePrivateDataFormatSecinfo(&tmp, srcPriv->httpcookie, "httpcookie");
+     }
+ 
+     if (src->tlsAlias)
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index bd9ac85ae2..5733954679 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -460,6 +460,9 @@ struct _qemuDomainStorageSourcePrivate {
+ 
+     /* data required for decryption of encrypted storage source */
+     qemuDomainSecretInfoPtr encinfo;
++
++    /* secure passthrough of the http cookie */
++    qemuDomainSecretInfoPtr httpcookie;
+ };
+ 
+ virObjectPtr qemuDomainStorageSourcePrivateNew(void);
+diff --git a/tests/qemustatusxml2xmldata/modern-in.xml b/tests/qemustatusxml2xmldata/modern-in.xml
+index c8d21ceada..cb56cdcef9 100644
+--- a/tests/qemustatusxml2xmldata/modern-in.xml
++++ b/tests/qemustatusxml2xmldata/modern-in.xml
+@@ -332,6 +332,7 @@
+               <objects>
+                 <secret type='auth' alias='test-auth-alias'/>
+                 <secret type='encryption' alias='test-encryption-alias'/>
++                <secret type='httpcookie' alias='http-cookie-alias'/>
+                 <TLSx509 alias='transport-alias'/>
+               </objects>
+             </privateData>
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-domain-Store-nodenames-of-slice-in-status-XML.patch b/SOURCES/libvirt-qemu-domain-Store-nodenames-of-slice-in-status-XML.patch
new file mode 100644
index 0000000..d754855
--- /dev/null
+++ b/SOURCES/libvirt-qemu-domain-Store-nodenames-of-slice-in-status-XML.patch
@@ -0,0 +1,74 @@
+From 32e26f3aff542e642641c32d9fa65577c891e337 Mon Sep 17 00:00:00 2001
+Message-Id: <32e26f3aff542e642641c32d9fa65577c891e337@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:21 +0100
+Subject: [PATCH] qemu: domain: Store nodenames of slice in status XML
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The storage slice will require a specific node name in cases when the
+image format is not raw. Store and format them in the status XML.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit f36d751fa6d091af5f1c2331f607e0ec3d8993fb)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <83b00663d313ed032a6b7723b8427c3224f2c9c8.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c                    | 7 +++++++
+ tests/qemustatusxml2xmldata/modern-in.xml | 4 ++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 7b414b79c7..948bf3011c 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -2348,6 +2348,9 @@ qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt,
+     src->nodeformat = virXPathString("string(./nodenames/nodename[@type='format']/@name)", ctxt);
+     src->tlsAlias = virXPathString("string(./objects/TLSx509/@alias)", ctxt);
+ 
++    if (src->sliceStorage)
++        src->sliceStorage->nodename = virXPathString("string(./nodenames/nodename[@type='slice-storage']/@name)", ctxt);
++
+     if (src->pr)
+         src->pr->mgralias = virXPathString("string(./reservations/@mgralias)", ctxt);
+ 
+@@ -2407,6 +2410,10 @@ qemuStorageSourcePrivateDataFormat(virStorageSourcePtr src,
+     virBufferEscapeString(&nodenamesChildBuf, "<nodename type='storage' name='%s'/>\n", src->nodestorage);
+     virBufferEscapeString(&nodenamesChildBuf, "<nodename type='format' name='%s'/>\n", src->nodeformat);
+ 
++    if (src->sliceStorage)
++        virBufferEscapeString(&nodenamesChildBuf, "<nodename type='slice-storage' name='%s'/>\n",
++                              src->sliceStorage->nodename);
++
+     virXMLFormatElement(buf, "nodenames", NULL, &nodenamesChildBuf);
+ 
+     if (src->pr)
+diff --git a/tests/qemustatusxml2xmldata/modern-in.xml b/tests/qemustatusxml2xmldata/modern-in.xml
+index 8a2718293f..c8d21ceada 100644
+--- a/tests/qemustatusxml2xmldata/modern-in.xml
++++ b/tests/qemustatusxml2xmldata/modern-in.xml
+@@ -312,6 +312,9 @@
+         <backingStore type='file' index='1'>
+           <format type='qcow2'/>
+           <source file='/var/lib/libvirt/images/base.qcow2'>
++            <slices>
++              <slice type='storage' offset='1234' size='3456'/>
++            </slices>
+             <seclabel model='dac' relabel='yes'>
+               <label>qemu:qemu</label>
+             </seclabel>
+@@ -322,6 +325,7 @@
+               <nodenames>
+                 <nodename type='storage' name='test-storage'/>
+                 <nodename type='format' name='test-format'/>
++                <nodename type='slice-storage' name='test-slice-storage'/>
+               </nodenames>
+               <reservations mgralias='test-alias'/>
+               <relPath>base.qcow2</relPath>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-don-t-access-vmdef-within-qemu_agent.c.patch b/SOURCES/libvirt-qemu-don-t-access-vmdef-within-qemu_agent.c.patch
new file mode 100644
index 0000000..23a3544
--- /dev/null
+++ b/SOURCES/libvirt-qemu-don-t-access-vmdef-within-qemu_agent.c.patch
@@ -0,0 +1,947 @@
+From 314e0b35249ff662cb76d9b03f33aeb700c6a43a Mon Sep 17 00:00:00 2001
+Message-Id: <314e0b35249ff662cb76d9b03f33aeb700c6a43a@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Thu, 20 Feb 2020 10:52:26 -0600
+Subject: [PATCH] qemu: don't access vmdef within qemu_agent.c
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In order to avoid holding an agent job and a normal job at the same
+time, we want to avoid accessing the domain's definition while holding
+the agent job. To achieve this, qemuAgentGetFSInfo() only returns the
+raw information from the agent query to the caller. The caller can then
+release the agent job and then proceed to look up the disk alias from
+the vm definition. This necessitates moving a few helper functions to
+qemu_driver.c and exposing the agent data structure (qemuAgentFSInfo) in
+the header.
+
+In addition, because the agent function no longer returns the looked-up
+disk alias, we can't test the alias within qemuagenttest.  Instead we
+simply test that we parse and return the raw agent data correctly.
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 599ae372d8cf0923757c5a3792acb07dcf3e8802)
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1759566
+Message-Id: <20200220165227.11491-5-jjongsma@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_agent.c  | 219 +----------------------------------
+ src/qemu/qemu_agent.h  |  33 ++++--
+ src/qemu/qemu_driver.c | 255 ++++++++++++++++++++++++++++++++++++++---
+ tests/qemuagenttest.c  | 196 +++++--------------------------
+ 4 files changed, 299 insertions(+), 404 deletions(-)
+
+diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
+index 4739faeed8..ef2d2c500b 100644
+--- a/src/qemu/qemu_agent.c
++++ b/src/qemu/qemu_agent.c
+@@ -1844,30 +1844,6 @@ qemuAgentSetTime(qemuAgentPtr mon,
+     return ret;
+ }
+ 
+-typedef struct _qemuAgentDiskInfo qemuAgentDiskInfo;
+-typedef qemuAgentDiskInfo *qemuAgentDiskInfoPtr;
+-struct _qemuAgentDiskInfo {
+-    char *serial;
+-    virPCIDeviceAddress pci_controller;
+-    char *bus_type;
+-    unsigned int bus;
+-    unsigned int target;
+-    unsigned int unit;
+-    char *devnode;
+-};
+-
+-typedef struct _qemuAgentFSInfo qemuAgentFSInfo;
+-typedef qemuAgentFSInfo *qemuAgentFSInfoPtr;
+-struct _qemuAgentFSInfo {
+-    char *mountpoint; /* path to mount point */
+-    char *name;       /* device name in the guest (e.g. "sda1") */
+-    char *fstype;     /* filesystem type */
+-    long long total_bytes;
+-    long long used_bytes;
+-    size_t ndisks;
+-    qemuAgentDiskInfoPtr *disks;
+-};
+-
+ static void
+ qemuAgentDiskInfoFree(qemuAgentDiskInfoPtr info)
+ {
+@@ -1880,7 +1856,7 @@ qemuAgentDiskInfoFree(qemuAgentDiskInfoPtr info)
+     VIR_FREE(info);
+ }
+ 
+-static void
++void
+ qemuAgentFSInfoFree(qemuAgentFSInfoPtr info)
+ {
+     size_t i;
+@@ -1899,47 +1875,6 @@ qemuAgentFSInfoFree(qemuAgentFSInfoPtr info)
+     VIR_FREE(info);
+ }
+ 
+-static virDomainFSInfoPtr
+-qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent,
+-                        virDomainDefPtr vmdef)
+-{
+-    virDomainFSInfoPtr ret = NULL;
+-    size_t i;
+-
+-    if (VIR_ALLOC(ret) < 0)
+-        goto error;
+-
+-    ret->mountpoint = g_strdup(agent->mountpoint);
+-    ret->name = g_strdup(agent->name);
+-    ret->fstype = g_strdup(agent->fstype);
+-
+-    if (agent->disks &&
+-        VIR_ALLOC_N(ret->devAlias, agent->ndisks) < 0)
+-        goto error;
+-
+-    ret->ndevAlias = agent->ndisks;
+-
+-    for (i = 0; i < ret->ndevAlias; i++) {
+-        qemuAgentDiskInfoPtr agentdisk = agent->disks[i];
+-        virDomainDiskDefPtr diskDef;
+-
+-        if (!(diskDef = virDomainDiskByAddress(vmdef,
+-                                               &agentdisk->pci_controller,
+-                                               agentdisk->bus,
+-                                               agentdisk->target,
+-                                               agentdisk->unit)))
+-            continue;
+-
+-        ret->devAlias[i] = g_strdup(diskDef->dst);
+-    }
+-
+-    return ret;
+-
+- error:
+-    virDomainFSInfoFree(ret);
+-    return NULL;
+-}
+-
+ static int
+ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+                             qemuAgentFSInfoPtr fsinfo)
+@@ -2013,7 +1948,6 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+         GET_DISK_ADDR(pci, &disk->pci_controller.bus, "bus");
+         GET_DISK_ADDR(pci, &disk->pci_controller.slot, "slot");
+         GET_DISK_ADDR(pci, &disk->pci_controller.function, "function");
+-
+ #undef GET_DISK_ADDR
+     }
+ 
+@@ -2024,9 +1958,9 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+  *          -2 when agent command is not supported by the agent
+  *          -1 otherwise
+  */
+-static int
+-qemuAgentGetFSInfoInternal(qemuAgentPtr mon,
+-                           qemuAgentFSInfoPtr **info)
++int
++qemuAgentGetFSInfo(qemuAgentPtr mon,
++                   qemuAgentFSInfoPtr **info)
+ {
+     size_t i;
+     int ret = -1;
+@@ -2158,151 +2092,6 @@ qemuAgentGetFSInfoInternal(qemuAgentPtr mon,
+     return ret;
+ }
+ 
+-/* Returns: 0 on success
+- *          -1 otherwise
+- */
+-int
+-qemuAgentGetFSInfo(qemuAgentPtr mon,
+-                   virDomainFSInfoPtr **info,
+-                   virDomainDefPtr vmdef)
+-{
+-    int ret = -1;
+-    qemuAgentFSInfoPtr *agentinfo = NULL;
+-    virDomainFSInfoPtr *info_ret = NULL;
+-    size_t i;
+-    int nfs;
+-
+-    nfs = qemuAgentGetFSInfoInternal(mon, &agentinfo);
+-    if (nfs < 0)
+-        return ret;
+-    if (VIR_ALLOC_N(info_ret, nfs) < 0)
+-        goto cleanup;
+-
+-    for (i = 0; i < nfs; i++) {
+-        if (!(info_ret[i] = qemuAgentFSInfoToPublic(agentinfo[i], vmdef)))
+-            goto cleanup;
+-    }
+-
+-    *info = g_steal_pointer(&info_ret);
+-    ret = nfs;
+-
+- cleanup:
+-    for (i = 0; i < nfs; i++) {
+-        qemuAgentFSInfoFree(agentinfo[i]);
+-        /* if there was an error, free any memory we've allocated for the
+-         * return value */
+-        if (info_ret)
+-            virDomainFSInfoFree(info_ret[i]);
+-    }
+-    VIR_FREE(agentinfo);
+-    VIR_FREE(info_ret);
+-    return ret;
+-}
+-
+-/* Returns: 0 on success
+- *          -2 when agent command is not supported by the agent
+- *          -1 otherwise
+- */
+-int
+-qemuAgentGetFSInfoParams(qemuAgentPtr mon,
+-                         virTypedParameterPtr *params,
+-                         int *nparams, int *maxparams,
+-                         virDomainDefPtr vmdef)
+-{
+-    int ret = -1;
+-    qemuAgentFSInfoPtr *fsinfo = NULL;
+-    size_t i, j;
+-    int nfs;
+-
+-    if ((nfs = qemuAgentGetFSInfoInternal(mon, &fsinfo)) < 0)
+-        return nfs;
+-
+-    if (virTypedParamsAddUInt(params, nparams, maxparams,
+-                              "fs.count", nfs) < 0)
+-        goto cleanup;
+-
+-    for (i = 0; i < nfs; i++) {
+-        char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
+-        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                   "fs.%zu.name", i);
+-        if (virTypedParamsAddString(params, nparams, maxparams,
+-                                    param_name, fsinfo[i]->name) < 0)
+-            goto cleanup;
+-        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                   "fs.%zu.mountpoint", i);
+-        if (virTypedParamsAddString(params, nparams, maxparams,
+-                                    param_name, fsinfo[i]->mountpoint) < 0)
+-            goto cleanup;
+-        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                   "fs.%zu.fstype", i);
+-        if (virTypedParamsAddString(params, nparams, maxparams,
+-                                    param_name, fsinfo[i]->fstype) < 0)
+-            goto cleanup;
+-
+-        /* disk usage values are not returned by older guest agents, so
+-         * only add the params if the value is set */
+-        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                   "fs.%zu.total-bytes", i);
+-        if (fsinfo[i]->total_bytes != -1 &&
+-            virTypedParamsAddULLong(params, nparams, maxparams,
+-                                    param_name, fsinfo[i]->total_bytes) < 0)
+-            goto cleanup;
+-
+-        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                   "fs.%zu.used-bytes", i);
+-        if (fsinfo[i]->used_bytes != -1 &&
+-            virTypedParamsAddULLong(params, nparams, maxparams,
+-                                    param_name, fsinfo[i]->used_bytes) < 0)
+-            goto cleanup;
+-
+-        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                   "fs.%zu.disk.count", i);
+-        if (virTypedParamsAddUInt(params, nparams, maxparams,
+-                                  param_name, fsinfo[i]->ndisks) < 0)
+-            goto cleanup;
+-        for (j = 0; j < fsinfo[i]->ndisks; j++) {
+-            virDomainDiskDefPtr diskdef = NULL;
+-            qemuAgentDiskInfoPtr d = fsinfo[i]->disks[j];
+-            /* match the disk to the target in the vm definition */
+-            diskdef = virDomainDiskByAddress(vmdef,
+-                                             &d->pci_controller,
+-                                             d->bus,
+-                                             d->target,
+-                                             d->unit);
+-            if (diskdef) {
+-                g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                           "fs.%zu.disk.%zu.alias", i, j);
+-                if (diskdef->dst &&
+-                    virTypedParamsAddString(params, nparams, maxparams,
+-                                            param_name, diskdef->dst) < 0)
+-                    goto cleanup;
+-            }
+-
+-            g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                       "fs.%zu.disk.%zu.serial", i, j);
+-            if (d->serial &&
+-                virTypedParamsAddString(params, nparams, maxparams,
+-                                        param_name, d->serial) < 0)
+-                goto cleanup;
+-
+-            g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+-                       "fs.%zu.disk.%zu.device", i, j);
+-            if (d->devnode &&
+-                virTypedParamsAddString(params, nparams, maxparams,
+-                                        param_name, d->devnode) < 0)
+-                goto cleanup;
+-        }
+-    }
+-    ret = nfs;
+-
+- cleanup:
+-    for (i = 0; i < nfs; i++)
+-        qemuAgentFSInfoFree(fsinfo[i]);
+-    VIR_FREE(fsinfo);
+-
+-    return ret;
+-}
+-
+ /*
+  * qemuAgentGetInterfaces:
+  * @mon: Agent monitor
+diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
+index 85e436cf68..5656fe60ff 100644
+--- a/src/qemu/qemu_agent.h
++++ b/src/qemu/qemu_agent.h
+@@ -65,19 +65,38 @@ typedef enum {
+     QEMU_AGENT_SHUTDOWN_LAST,
+ } qemuAgentShutdownMode;
+ 
++typedef struct _qemuAgentDiskInfo qemuAgentDiskInfo;
++typedef qemuAgentDiskInfo *qemuAgentDiskInfoPtr;
++struct _qemuAgentDiskInfo {
++    char *serial;
++    virPCIDeviceAddress pci_controller;
++    char *bus_type;
++    unsigned int bus;
++    unsigned int target;
++    unsigned int unit;
++    char *devnode;
++};
++
++typedef struct _qemuAgentFSInfo qemuAgentFSInfo;
++typedef qemuAgentFSInfo *qemuAgentFSInfoPtr;
++struct _qemuAgentFSInfo {
++    char *mountpoint; /* path to mount point */
++    char *name;       /* device name in the guest (e.g. "sda1") */
++    char *fstype;     /* filesystem type */
++    long long total_bytes;
++    long long used_bytes;
++    size_t ndisks;
++    qemuAgentDiskInfoPtr *disks;
++};
++void qemuAgentFSInfoFree(qemuAgentFSInfoPtr info);
++
+ int qemuAgentShutdown(qemuAgentPtr mon,
+                       qemuAgentShutdownMode mode);
+ 
+ int qemuAgentFSFreeze(qemuAgentPtr mon,
+                       const char **mountpoints, unsigned int nmountpoints);
+ int qemuAgentFSThaw(qemuAgentPtr mon);
+-int qemuAgentGetFSInfo(qemuAgentPtr mon, virDomainFSInfoPtr **info,
+-                       virDomainDefPtr vmdef);
+-
+-int qemuAgentGetFSInfoParams(qemuAgentPtr mon,
+-                             virTypedParameterPtr *params,
+-                             int *nparams, int *maxparams,
+-                             virDomainDefPtr vmdef);
++int qemuAgentGetFSInfo(qemuAgentPtr mon, qemuAgentFSInfoPtr **info);
+ 
+ int qemuAgentSuspend(qemuAgentPtr mon,
+                      unsigned int target);
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 69e4f7264b..ac3a7ad282 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -21839,6 +21839,111 @@ qemuNodeAllocPages(virConnectPtr conn,
+                                 startCell, cellCount, add);
+ }
+ 
++static int
++qemuDomainGetFSInfoAgent(virQEMUDriverPtr driver,
++                         virDomainObjPtr vm,
++                         qemuAgentFSInfoPtr **info)
++{
++    int ret = -1;
++    qemuAgentPtr agent;
++
++    if (qemuDomainObjBeginAgentJob(driver, vm,
++                                   QEMU_AGENT_JOB_QUERY) < 0)
++        return ret;
++
++    if (virDomainObjCheckActive(vm) < 0)
++        goto endjob;
++
++    if (!qemuDomainAgentAvailable(vm, true))
++        goto endjob;
++
++    agent = qemuDomainObjEnterAgent(vm);
++    ret = qemuAgentGetFSInfo(agent, info);
++    qemuDomainObjExitAgent(vm, agent);
++
++ endjob:
++    qemuDomainObjEndAgentJob(vm);
++    return ret;
++}
++
++static virDomainFSInfoPtr
++qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent,
++                        virDomainDefPtr vmdef)
++{
++    virDomainFSInfoPtr ret = NULL;
++    size_t i;
++
++    if (VIR_ALLOC(ret) < 0)
++        goto error;
++
++    ret->mountpoint = g_strdup(agent->mountpoint);
++    ret->name = g_strdup(agent->name);
++    ret->fstype = g_strdup(agent->fstype);
++
++    if (agent->disks &&
++        VIR_ALLOC_N(ret->devAlias, agent->ndisks) < 0)
++        goto error;
++
++    ret->ndevAlias = agent->ndisks;
++
++    for (i = 0; i < ret->ndevAlias; i++) {
++        qemuAgentDiskInfoPtr agentdisk = agent->disks[i];
++        virDomainDiskDefPtr diskDef;
++
++        if (!(diskDef = virDomainDiskByAddress(vmdef,
++                                               &agentdisk->pci_controller,
++                                               agentdisk->bus,
++                                               agentdisk->target,
++                                               agentdisk->unit)))
++            continue;
++
++        ret->devAlias[i] = g_strdup(diskDef->dst);
++    }
++
++    return ret;
++
++ error:
++    virDomainFSInfoFree(ret);
++    return NULL;
++}
++
++/* Returns: 0 on success
++ *          -1 otherwise
++ */
++static int
++virDomainFSInfoFormat(qemuAgentFSInfoPtr *agentinfo,
++                      int nagentinfo,
++                      virDomainDefPtr vmdef,
++                      virDomainFSInfoPtr **info)
++{
++    int ret = -1;
++    virDomainFSInfoPtr *info_ret = NULL;
++    size_t i;
++
++    if (nagentinfo < 0)
++        return ret;
++    if (VIR_ALLOC_N(info_ret, nagentinfo) < 0)
++        goto cleanup;
++
++    for (i = 0; i < nagentinfo; i++) {
++        if (!(info_ret[i] = qemuAgentFSInfoToPublic(agentinfo[i], vmdef)))
++            goto cleanup;
++    }
++
++    *info = g_steal_pointer(&info_ret);
++    ret = nagentinfo;
++
++ cleanup:
++    for (i = 0; i < nagentinfo; i++) {
++        qemuAgentFSInfoFree(agentinfo[i]);
++        /* if there was an error, free any memory we've allocated for the
++         * return value */
++        if (info_ret)
++            virDomainFSInfoFree(info_ret[i]);
++    }
++    VIR_FREE(info_ret);
++    return ret;
++}
+ 
+ static int
+ qemuDomainGetFSInfo(virDomainPtr dom,
+@@ -21847,8 +21952,9 @@ qemuDomainGetFSInfo(virDomainPtr dom,
+ {
+     virQEMUDriverPtr driver = dom->conn->privateData;
+     virDomainObjPtr vm;
+-    qemuAgentPtr agent;
++    qemuAgentFSInfoPtr *agentinfo = NULL;
+     int ret = -1;
++    int nfs;
+ 
+     virCheckFlags(0, ret);
+ 
+@@ -21858,25 +21964,22 @@ qemuDomainGetFSInfo(virDomainPtr dom,
+     if (virDomainGetFSInfoEnsureACL(dom->conn, vm->def) < 0)
+         goto cleanup;
+ 
+-    if (qemuDomainObjBeginJobWithAgent(driver, vm,
+-                                       QEMU_JOB_QUERY,
+-                                       QEMU_AGENT_JOB_QUERY) < 0)
++    if ((nfs = qemuDomainGetFSInfoAgent(driver, vm, &agentinfo)) < 0)
++        goto cleanup;
++
++    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+         goto cleanup;
+ 
+     if (virDomainObjCheckActive(vm) < 0)
+         goto endjob;
+ 
+-    if (!qemuDomainAgentAvailable(vm, true))
+-        goto endjob;
+-
+-    agent = qemuDomainObjEnterAgent(vm);
+-    ret = qemuAgentGetFSInfo(agent, info, vm->def);
+-    qemuDomainObjExitAgent(vm, agent);
++    ret = virDomainFSInfoFormat(agentinfo, nfs, vm->def, info);
+ 
+  endjob:
+-    qemuDomainObjEndJobWithAgent(driver, vm);
++    qemuDomainObjEndJob(driver, vm);
+ 
+  cleanup:
++    g_free(agentinfo);
+     virDomainObjEndAPI(&vm);
+     return ret;
+ }
+@@ -22882,6 +22985,103 @@ qemuDomainGetGuestInfoCheckSupport(unsigned int *types)
+     *types = *types & supportedGuestInfoTypes;
+ }
+ 
++/* Returns: 0 on success
++ *          -1 otherwise
++ */
++static int
++qemuAgentFSInfoFormatParams(qemuAgentFSInfoPtr *fsinfo,
++                            int nfs,
++                            virDomainDefPtr vmdef,
++                            virTypedParameterPtr *params,
++                            int *nparams, int *maxparams)
++{
++    int ret = -1;
++    size_t i, j;
++
++    /* FIXME: get disk target */
++
++    if (virTypedParamsAddUInt(params, nparams, maxparams,
++                              "fs.count", nfs) < 0)
++        goto cleanup;
++
++    for (i = 0; i < nfs; i++) {
++        char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
++        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                   "fs.%zu.name", i);
++        if (virTypedParamsAddString(params, nparams, maxparams,
++                                    param_name, fsinfo[i]->name) < 0)
++            goto cleanup;
++        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                   "fs.%zu.mountpoint", i);
++        if (virTypedParamsAddString(params, nparams, maxparams,
++                                    param_name, fsinfo[i]->mountpoint) < 0)
++            goto cleanup;
++        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                   "fs.%zu.fstype", i);
++        if (virTypedParamsAddString(params, nparams, maxparams,
++                                    param_name, fsinfo[i]->fstype) < 0)
++            goto cleanup;
++
++        /* disk usage values are not returned by older guest agents, so
++         * only add the params if the value is set */
++        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                   "fs.%zu.total-bytes", i);
++        if (fsinfo[i]->total_bytes != -1 &&
++            virTypedParamsAddULLong(params, nparams, maxparams,
++                                    param_name, fsinfo[i]->total_bytes) < 0)
++            goto cleanup;
++
++        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                   "fs.%zu.used-bytes", i);
++        if (fsinfo[i]->used_bytes != -1 &&
++            virTypedParamsAddULLong(params, nparams, maxparams,
++                                    param_name, fsinfo[i]->used_bytes) < 0)
++            goto cleanup;
++
++        g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                   "fs.%zu.disk.count", i);
++        if (virTypedParamsAddUInt(params, nparams, maxparams,
++                                  param_name, fsinfo[i]->ndisks) < 0)
++            goto cleanup;
++        for (j = 0; j < fsinfo[i]->ndisks; j++) {
++            virDomainDiskDefPtr diskdef = NULL;
++            qemuAgentDiskInfoPtr d = fsinfo[i]->disks[j];
++            /* match the disk to the target in the vm definition */
++            diskdef = virDomainDiskByAddress(vmdef,
++                                             &d->pci_controller,
++                                             d->bus,
++                                             d->target,
++                                             d->unit);
++            if (diskdef) {
++                g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                           "fs.%zu.disk.%zu.alias", i, j);
++                if (diskdef->dst &&
++                    virTypedParamsAddString(params, nparams, maxparams,
++                                            param_name, diskdef->dst) < 0)
++                    goto cleanup;
++            }
++
++            g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                       "fs.%zu.disk.%zu.serial", i, j);
++            if (d->serial &&
++                virTypedParamsAddString(params, nparams, maxparams,
++                                        param_name, d->serial) < 0)
++                goto cleanup;
++
++            g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
++                       "fs.%zu.disk.%zu.device", i, j);
++            if (d->devnode &&
++                virTypedParamsAddString(params, nparams, maxparams,
++                                        param_name, d->devnode) < 0)
++                goto cleanup;
++        }
++    }
++    ret = nfs;
++
++ cleanup:
++    return ret;
++}
++
+ static int
+ qemuDomainGetGuestInfo(virDomainPtr dom,
+                        unsigned int types,
+@@ -22897,6 +23097,9 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
+     g_autofree char *hostname = NULL;
+     unsigned int supportedTypes = types;
+     int rc;
++    int nfs = 0;
++    qemuAgentFSInfoPtr *agentfsinfo = NULL;
++    size_t i;
+ 
+     virCheckFlags(0, -1);
+     qemuDomainGetGuestInfoCheckSupport(&supportedTypes);
+@@ -22907,13 +23110,12 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
+     if (virDomainGetGuestInfoEnsureACL(dom->conn, vm->def) < 0)
+         goto cleanup;
+ 
+-    if (qemuDomainObjBeginJobWithAgent(driver, vm,
+-                                       QEMU_JOB_QUERY,
+-                                       QEMU_AGENT_JOB_QUERY) < 0)
++    if (qemuDomainObjBeginAgentJob(driver, vm,
++                                   QEMU_AGENT_JOB_QUERY) < 0)
+         goto cleanup;
+ 
+     if (!qemuDomainAgentAvailable(vm, true))
+-        goto endjob;
++        goto endagentjob;
+ 
+     agent = qemuDomainObjEnterAgent(vm);
+ 
+@@ -22948,7 +23150,7 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
+         }
+     }
+     if (supportedTypes & VIR_DOMAIN_GUEST_INFO_FILESYSTEM) {
+-        rc = qemuAgentGetFSInfoParams(agent, params, nparams, &maxparams, vm->def);
++        rc = nfs = qemuAgentGetFSInfo(agent, &agentfsinfo);
+         if (rc < 0 && !(rc == -2 && types == 0))
+             goto exitagent;
+     }
+@@ -22958,10 +23160,29 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
+  exitagent:
+     qemuDomainObjExitAgent(vm, agent);
+ 
++ endagentjob:
++    qemuDomainObjEndAgentJob(vm);
++
++    if (nfs > 0) {
++        if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
++            goto cleanup;
++
++        if (virDomainObjCheckActive(vm) < 0)
++            goto endjob;
++
++        /* we need to convert the agent fsinfo struct to parameters and match
++         * it to the vm disk target */
++        qemuAgentFSInfoFormatParams(agentfsinfo, nfs, vm->def, params, nparams, &maxparams);
++
+  endjob:
+-    qemuDomainObjEndJobWithAgent(driver, vm);
++        qemuDomainObjEndJob(driver, vm);
++    }
+ 
+  cleanup:
++    for (i = 0; i < nfs; i++)
++        qemuAgentFSInfoFree(agentfsinfo[i]);
++    VIR_FREE(agentfsinfo);
++
+     virDomainObjEndAPI(&vm);
+     return ret;
+ }
+diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c
+index 644dc9d08b..a45ce4f44a 100644
+--- a/tests/qemuagenttest.c
++++ b/tests/qemuagenttest.c
+@@ -247,14 +247,14 @@ testQemuAgentGetFSInfo(const void *data)
+     virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
+     qemuMonitorTestPtr test = NULL;
+     virDomainDefPtr def = NULL;
+-    virDomainFSInfoPtr *info = NULL;
++    qemuAgentFSInfoPtr *info = NULL;
+     int ret = -1, ninfo = 0, i;
+ 
+     if (testQemuAgentGetFSInfoCommon(xmlopt, &test, &def) < 0)
+         goto cleanup;
+ 
+     if ((ninfo = qemuAgentGetFSInfo(qemuMonitorTestGetAgent(test),
+-                                    &info, def)) < 0)
++                                    &info)) < 0)
+         goto cleanup;
+ 
+     if (ninfo != 3) {
+@@ -266,35 +266,48 @@ testQemuAgentGetFSInfo(const void *data)
+     if (STRNEQ(info[2]->name, "sda1") ||
+         STRNEQ(info[2]->mountpoint, "/") ||
+         STRNEQ(info[2]->fstype, "ext4") ||
+-        info[2]->ndevAlias != 1 ||
+-        !info[2]->devAlias || !info[2]->devAlias[0] ||
+-        STRNEQ(info[2]->devAlias[0], "hdc")) {
++        info[2]->ndisks != 1 ||
++        !info[2]->disks || !info[2]->disks[0]) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "unexpected filesystems information returned for sda1 (%s,%s)",
+-            info[2]->name, info[2]->devAlias ? info[2]->devAlias[0] : "null");
++            "unexpected filesystems information returned for sda1 (%s)",
++            info[2]->name);
+         ret = -1;
+         goto cleanup;
+     }
+     if (STRNEQ(info[1]->name, "dm-1") ||
+         STRNEQ(info[1]->mountpoint, "/opt") ||
+         STRNEQ(info[1]->fstype, "vfat") ||
+-        info[1]->ndevAlias != 2 ||
+-        !info[1]->devAlias || !info[1]->devAlias[0] || !info[1]->devAlias[1] ||
+-        STRNEQ(info[1]->devAlias[0], "vda") ||
+-        STRNEQ(info[1]->devAlias[1], "vdb")) {
++        info[1]->ndisks != 2 ||
++        !info[1]->disks || !info[1]->disks[0] || !info[1]->disks[1] ||
++        STRNEQ(info[1]->disks[0]->bus_type, "virtio") ||
++        info[1]->disks[0]->bus != 0 ||
++        info[1]->disks[0]->target != 0 ||
++        info[1]->disks[0]->unit != 0 ||
++        info[1]->disks[0]->pci_controller.domain != 0 ||
++        info[1]->disks[0]->pci_controller.bus != 0 ||
++        info[1]->disks[0]->pci_controller.slot != 6 ||
++        info[1]->disks[0]->pci_controller.function != 0 ||
++        STRNEQ(info[1]->disks[1]->bus_type, "virtio") ||
++        info[1]->disks[1]->bus != 0 ||
++        info[1]->disks[1]->target != 0 ||
++        info[1]->disks[1]->unit != 0 ||
++        info[1]->disks[1]->pci_controller.domain != 0 ||
++        info[1]->disks[1]->pci_controller.bus != 0 ||
++        info[1]->disks[1]->pci_controller.slot != 7 ||
++        info[1]->disks[1]->pci_controller.function != 0) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "unexpected filesystems information returned for dm-1 (%s,%s)",
+-            info[0]->name, info[0]->devAlias ? info[0]->devAlias[0] : "null");
++            "unexpected filesystems information returned for dm-1 (%s)",
++            info[0]->name);
+         ret = -1;
+         goto cleanup;
+     }
+     if (STRNEQ(info[0]->name, "sdb1") ||
+         STRNEQ(info[0]->mountpoint, "/mnt/disk") ||
+         STRNEQ(info[0]->fstype, "xfs") ||
+-        info[0]->ndevAlias != 0 || info[0]->devAlias) {
++        info[0]->ndisks != 0 || info[0]->disks) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "unexpected filesystems information returned for sdb1 (%s,%s)",
+-            info[0]->name, info[0]->devAlias ? info[0]->devAlias[0] : "null");
++            "unexpected filesystems information returned for sdb1 (%s)",
++            info[0]->name);
+         ret = -1;
+         goto cleanup;
+     }
+@@ -313,7 +326,7 @@ testQemuAgentGetFSInfo(const void *data)
+                                "}") < 0)
+         goto cleanup;
+ 
+-    if (qemuAgentGetFSInfo(qemuMonitorTestGetAgent(test), &info, def) != -1) {
++    if (qemuAgentGetFSInfo(qemuMonitorTestGetAgent(test), &info) >= 0) {
+         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        "agent get-fsinfo command should have failed");
+         goto cleanup;
+@@ -323,159 +336,13 @@ testQemuAgentGetFSInfo(const void *data)
+ 
+  cleanup:
+     for (i = 0; i < ninfo; i++)
+-        virDomainFSInfoFree(info[i]);
++        qemuAgentFSInfoFree(info[i]);
+     VIR_FREE(info);
+     virDomainDefFree(def);
+     qemuMonitorTestFree(test);
+     return ret;
+ }
+ 
+-static int
+-testQemuAgentGetFSInfoParams(const void *data)
+-{
+-    virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
+-    qemuMonitorTestPtr test = NULL;
+-    virDomainDefPtr def = NULL;
+-    virTypedParameterPtr params = NULL;
+-    int nparams = 0, maxparams = 0;
+-    int ret = -1;
+-    unsigned int count;
+-    const char *name, *mountpoint, *fstype, *alias, *serial;
+-    unsigned int diskcount;
+-    unsigned long long bytesused, bytestotal;
+-    const char *alias2;
+-
+-    if (testQemuAgentGetFSInfoCommon(xmlopt, &test, &def) < 0)
+-        goto cleanup;
+-
+-    if (qemuAgentGetFSInfoParams(qemuMonitorTestGetAgent(test),
+-                                 &params, &nparams, &maxparams, def) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                       "Failed to execute qemuAgentGetFSInfoParams()");
+-        goto cleanup;
+-    }
+-
+-    if (virTypedParamsGetUInt(params, nparams, "fs.count", &count) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                       "expected filesystem count");
+-        goto cleanup;
+-    }
+-
+-    if (count != 3) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       "expected 3 filesystems information, got %d", count);
+-        goto cleanup;
+-    }
+-
+-    if (virTypedParamsGetString(params, nparams, "fs.2.name", &name) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.2.mountpoint", &mountpoint) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.2.fstype", &fstype) < 0 ||
+-        virTypedParamsGetULLong(params, nparams, "fs.2.used-bytes", &bytesused) <= 0 ||
+-        virTypedParamsGetULLong(params, nparams, "fs.2.total-bytes", &bytestotal) <= 0 ||
+-        virTypedParamsGetUInt(params, nparams, "fs.2.disk.count", &diskcount) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.2.disk.0.alias", &alias) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.2.disk.0.serial", &serial) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "Missing an expected parameter for sda1 (%s,%s)",
+-            name, alias);
+-        goto cleanup;
+-    }
+-
+-    if (STRNEQ(name, "sda1") ||
+-        STRNEQ(mountpoint, "/") ||
+-        STRNEQ(fstype, "ext4") ||
+-        bytesused != 229019648 ||
+-        bytestotal != 952840192 ||
+-        diskcount != 1 ||
+-        STRNEQ(alias, "hdc") ||
+-        STRNEQ(serial, "ARBITRARYSTRING")) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "unexpected filesystems information returned for sda1 (%s,%s)",
+-            name, alias);
+-        goto cleanup;
+-    }
+-
+-    if (virTypedParamsGetString(params, nparams, "fs.1.name", &name) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.1.mountpoint", &mountpoint) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.1.fstype", &fstype) < 0 ||
+-        virTypedParamsGetULLong(params, nparams, "fs.1.used-bytes", &bytesused) == 1 ||
+-        virTypedParamsGetULLong(params, nparams, "fs.1.total-bytes", &bytestotal) == 1 ||
+-        virTypedParamsGetUInt(params, nparams, "fs.1.disk.count", &diskcount) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.1.disk.0.alias", &alias) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.1.disk.1.alias", &alias2) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "Incorrect parameters for dm-1 (%s,%s)",
+-            name, alias);
+-        goto cleanup;
+-    }
+-    if (STRNEQ(name, "dm-1") ||
+-        STRNEQ(mountpoint, "/opt") ||
+-        STRNEQ(fstype, "vfat") ||
+-        diskcount != 2 ||
+-        STRNEQ(alias, "vda") ||
+-        STRNEQ(alias2, "vdb")) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "unexpected filesystems information returned for dm-1 (%s,%s)",
+-            name, alias);
+-        goto cleanup;
+-    }
+-
+-    alias = NULL;
+-    if (virTypedParamsGetString(params, nparams, "fs.0.name", &name) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.0.mountpoint", &mountpoint) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.0.fstype", &fstype) < 0 ||
+-        virTypedParamsGetULLong(params, nparams, "fs.0.used-bytes", &bytesused) == 1 ||
+-        virTypedParamsGetULLong(params, nparams, "fs.0.total-bytes", &bytestotal) == 1 ||
+-        virTypedParamsGetUInt(params, nparams, "fs.0.disk.count", &diskcount) < 0 ||
+-        virTypedParamsGetString(params, nparams, "fs.0.disk.0.alias", &alias) == 1) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "Incorrect parameters for sdb1 (%s,%s)",
+-            name, alias);
+-        goto cleanup;
+-    }
+-
+-    if (STRNEQ(name, "sdb1") ||
+-        STRNEQ(mountpoint, "/mnt/disk") ||
+-        STRNEQ(fstype, "xfs") ||
+-        diskcount != 0 ||
+-        alias != NULL) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-            "unexpected filesystems information returned for sdb1 (%s,%s)",
+-            name, alias);
+-        goto cleanup;
+-    }
+-
+-    if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
+-        goto cleanup;
+-
+-    if (qemuMonitorTestAddItem(test, "guest-get-fsinfo",
+-                               "{\"error\":"
+-                               "    {\"class\":\"CommandDisabled\","
+-                               "     \"desc\":\"The command guest-get-fsinfo "
+-                                               "has been disabled for "
+-                                               "this instance\","
+-                               "     \"data\":{\"name\":\"guest-get-fsinfo\"}"
+-                               "    }"
+-                               "}") < 0)
+-        goto cleanup;
+-
+-    if (qemuAgentGetFSInfoParams(qemuMonitorTestGetAgent(test), &params,
+-                                 &nparams, &maxparams, def) != -2) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                       "agent get-fsinfo command should have failed");
+-        goto cleanup;
+-    }
+-
+-    ret = 0;
+-
+- cleanup:
+-    virTypedParamsFree(params, nparams);
+-    virDomainDefFree(def);
+-    qemuMonitorTestFree(test);
+-    return ret;
+-}
+-
+-
+ static int
+ testQemuAgentSuspend(const void *data)
+ {
+@@ -1438,7 +1305,6 @@ mymain(void)
+     DO_TEST(FSFreeze);
+     DO_TEST(FSThaw);
+     DO_TEST(FSTrim);
+-    DO_TEST(GetFSInfoParams);
+     DO_TEST(GetFSInfo);
+     DO_TEST(Suspend);
+     DO_TEST(Shutdown);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-eliminate-ret-in-qemuExtDevicesStart.patch b/SOURCES/libvirt-qemu-eliminate-ret-in-qemuExtDevicesStart.patch
new file mode 100644
index 0000000..21efa97
--- /dev/null
+++ b/SOURCES/libvirt-qemu-eliminate-ret-in-qemuExtDevicesStart.patch
@@ -0,0 +1,68 @@
+From 9c51a4657bf446bf2ccaba65b2f76d29e5b14f22 Mon Sep 17 00:00:00 2001
+Message-Id: <9c51a4657bf446bf2ccaba65b2f76d29e5b14f22@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:31 +0100
+Subject: [PATCH] qemu: eliminate ret in qemuExtDevicesStart
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+All the callees return either 0 or -1 so there is no need
+for propagating the value. And we bail on the first error.
+
+Remove the variable to make the function simpler.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit d5256cbd5575fb714714de1d543d1e5d41daf8ff)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <1a2cb184deb18bf67e3fdc50785e829f74d89352.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_extdevice.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
+index 1869a42f11..9c0c0fd573 100644
+--- a/src/qemu/qemu_extdevice.c
++++ b/src/qemu/qemu_extdevice.c
+@@ -156,7 +156,6 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
+                     bool incomingMigration)
+ {
+     virDomainDefPtr def = vm->def;
+-    int ret = 0;
+     size_t i;
+ 
+     if (qemuExtDevicesInitPaths(driver, def) < 0)
+@@ -166,14 +165,13 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
+         virDomainVideoDefPtr video = def->videos[i];
+ 
+         if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+-            ret = qemuExtVhostUserGPUStart(driver, vm, video);
+-            if (ret < 0)
+-                return ret;
++            if (qemuExtVhostUserGPUStart(driver, vm, video) < 0)
++                return -1;
+         }
+     }
+ 
+-    if (def->tpm)
+-        ret = qemuExtTPMStart(driver, vm, incomingMigration);
++    if (def->tpm && qemuExtTPMStart(driver, vm, incomingMigration) < 0)
++        return -1;
+ 
+     for (i = 0; i < def->nnets; i++) {
+         virDomainNetDefPtr net = def->nets[i];
+@@ -184,7 +182,7 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
+             return -1;
+     }
+ 
+-    return ret;
++    return 0;
+ }
+ 
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-end-the-agent-job-in-qemuDomainSetTimeAgent.patch b/SOURCES/libvirt-qemu-end-the-agent-job-in-qemuDomainSetTimeAgent.patch
new file mode 100644
index 0000000..b127622
--- /dev/null
+++ b/SOURCES/libvirt-qemu-end-the-agent-job-in-qemuDomainSetTimeAgent.patch
@@ -0,0 +1,41 @@
+From 24405105c86a955a028a915153d1c1dfe450f237 Mon Sep 17 00:00:00 2001
+Message-Id: <24405105c86a955a028a915153d1c1dfe450f237@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Mon, 20 Jan 2020 09:31:21 +0100
+Subject: [PATCH] qemu: end the agent job in qemuDomainSetTimeAgent
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This function grabs an agent job but ends a monitor job.
+End the agent job instead.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1792723
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reported-by: Dan Zheng <dzheng@redhat.com>
+Fixes: e005c95f56fee9ed780be7f8db103d690bd34cbd
+(cherry picked from commit d61f95cf6a6fbd564e104c168d325581acd9cd8d)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <d00e462cf0f84d7d2d105f30f0ec8edf49786403.1579509070.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 217d873671..6163b13e91 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -20373,7 +20373,7 @@ qemuDomainSetTimeAgent(virQEMUDriverPtr driver,
+     qemuDomainObjExitAgent(vm, agent);
+ 
+  endjob:
+-    qemuDomainObjEndJob(driver, vm);
++    qemuDomainObjEndAgentJob(vm);
+     return ret;
+ }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-forbid-migration-with-vhost-user-fs-device.patch b/SOURCES/libvirt-qemu-forbid-migration-with-vhost-user-fs-device.patch
new file mode 100644
index 0000000..7869a63
--- /dev/null
+++ b/SOURCES/libvirt-qemu-forbid-migration-with-vhost-user-fs-device.patch
@@ -0,0 +1,52 @@
+From 5ae52dc252691262663129e52dbf1a775cd92bb8 Mon Sep 17 00:00:00 2001
+Message-Id: <5ae52dc252691262663129e52dbf1a775cd92bb8@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:45 +0100
+Subject: [PATCH] qemu: forbid migration with vhost-user-fs device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is not yet supported.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 5c0444a38bb37ddeb7049683ef72d02beab9e617)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+
+Conflicts: * downstream is missing commit 739bb1f26f9797f69023e221bef7c004adb9c522
+    qemu_migration: Rearrange some checks in qemuMigrationSrcIsAllowed()
+  src/qemu/qemu_migration.c
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <426a6270b1e0265b4977ad70029342ca43f7ff48.1583322091.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_migration.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
+index 03f058051d..a677e270d4 100644
+--- a/src/qemu/qemu_migration.c
++++ b/src/qemu/qemu_migration.c
+@@ -1281,6 +1281,16 @@ qemuMigrationSrcIsAllowed(virQEMUDriverPtr driver,
+                            _("migration with shmem device is not supported"));
+             return false;
+         }
++
++        for (i = 0; i < vm->def->nfss; i++) {
++            virDomainFSDefPtr fs = vm->def->fss[i];
++
++            if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
++                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
++                               _("migration with virtiofs device is not supported"));
++                return false;
++            }
++        }
+     }
+ 
+     return true;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-hotplug-Fix-handling-of-the-copy-on-read-layer-with-blockdev.patch b/SOURCES/libvirt-qemu-hotplug-Fix-handling-of-the-copy-on-read-layer-with-blockdev.patch
new file mode 100644
index 0000000..bcbb7c4
--- /dev/null
+++ b/SOURCES/libvirt-qemu-hotplug-Fix-handling-of-the-copy-on-read-layer-with-blockdev.patch
@@ -0,0 +1,94 @@
+From ec2f52e9e935136d8517567bbe0e56c6e8c40af1 Mon Sep 17 00:00:00 2001
+Message-Id: <ec2f52e9e935136d8517567bbe0e56c6e8c40af1@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:05 +0100
+Subject: [PATCH] qemu: hotplug: Fix handling of the 'copy-on-read' layer with
+ blockdev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+My original implementation was completely broken because it attempted to
+use object-add/del instead of blockdev-add/del.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798366
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit b71cf8726c25ea135ac81051e332544e6b886ad2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798366
+Message-Id: <170358b3722e56fc308e7cf3b0a2625349346ae9.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_hotplug.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
+index 31d455505b..12bc1f9dd5 100644
+--- a/src/qemu/qemu_hotplug.c
++++ b/src/qemu/qemu_hotplug.c
+@@ -680,6 +680,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+     g_autoptr(virJSONValue) corProps = NULL;
+     g_autofree char *corAlias = NULL;
++    bool corAdded = false;
+     bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+ 
+     if (qemuDomainStorageSourceChainAccessAllow(driver, vm, disk->src) < 0)
+@@ -692,9 +693,12 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
+         goto cleanup;
+ 
+     if (blockdev) {
+-        if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON &&
+-            !(corProps = qemuBlockStorageGetCopyOnReadProps(disk)))
+-        goto cleanup;
++        if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON) {
++            if (!(corProps = qemuBlockStorageGetCopyOnReadProps(disk)))
++                goto cleanup;
++
++            corAlias = g_strdup(QEMU_DOMAIN_DISK_PRIVATE(disk)->nodeCopyOnRead);
++        }
+ 
+         if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->src,
+                                                                       priv->qemuCaps)))
+@@ -719,9 +723,12 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
+     if (qemuBlockStorageSourceChainAttach(priv->mon, data) < 0)
+         goto exit_monitor;
+ 
+-    if (corProps &&
+-        qemuMonitorAddObject(priv->mon, &corProps, &corAlias) < 0)
+-        goto exit_monitor;
++    if (corProps) {
++        if (qemuMonitorBlockdevAdd(priv->mon, &corProps) < 0)
++            goto exit_monitor;
++
++        corAdded = true;
++    }
+ 
+     if (qemuDomainAttachExtensionDevice(priv->mon, &disk->info) < 0)
+         goto exit_monitor;
+@@ -763,8 +770,8 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver,
+     return ret;
+ 
+  exit_monitor:
+-    if (corAlias)
+-        ignore_value(qemuMonitorDelObject(priv->mon, corAlias));
++    if (corAdded)
++        ignore_value(qemuMonitorBlockdevDel(priv->mon, corAlias));
+     qemuBlockStorageSourceChainDetach(priv->mon, data);
+ 
+     if (qemuDomainObjExitMonitor(driver, vm) < 0)
+@@ -4252,7 +4259,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
+     qemuDomainObjEnterMonitor(driver, vm);
+ 
+     if (corAlias)
+-        ignore_value(qemuMonitorDelObject(priv->mon, corAlias));
++        ignore_value(qemuMonitorBlockdevDel(priv->mon, corAlias));
+ 
+     if (diskBackend)
+         qemuBlockStorageSourceChainDetach(priv->mon, diskBackend);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-monitor-Add-handler-for-blockdev-reopen.patch b/SOURCES/libvirt-qemu-monitor-Add-handler-for-blockdev-reopen.patch
new file mode 100644
index 0000000..2a394dd
--- /dev/null
+++ b/SOURCES/libvirt-qemu-monitor-Add-handler-for-blockdev-reopen.patch
@@ -0,0 +1,113 @@
+From 56a605626d81ee27ad220f3f949990cc46fca061 Mon Sep 17 00:00:00 2001
+Message-Id: <56a605626d81ee27ad220f3f949990cc46fca061@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:15 +0100
+Subject: [PATCH] qemu: monitor: Add handler for blockdev-reopen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduce the monitor code for using blockdev-reopen.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 9f436e067df2e4465228c8ba536dcf9f9445aabc)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <e74e172e1c5e73fcaeafb7fb3a09414a2fcbe9ad.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_monitor.c      | 13 +++++++++++++
+ src/qemu/qemu_monitor.h      |  3 +++
+ src/qemu/qemu_monitor_json.c | 21 +++++++++++++++++++++
+ src/qemu/qemu_monitor_json.h |  4 ++++
+ 4 files changed, 41 insertions(+)
+
+diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
+index e3ee48613a..c4202d59af 100644
+--- a/src/qemu/qemu_monitor.c
++++ b/src/qemu/qemu_monitor.c
+@@ -4407,6 +4407,19 @@ qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
+ }
+ 
+ 
++int
++qemuMonitorBlockdevReopen(qemuMonitorPtr mon,
++                          virJSONValuePtr *props)
++{
++    VIR_DEBUG("props=%p (node-name=%s)", *props,
++              NULLSTR(virJSONValueObjectGetString(*props, "node-name")));
++
++    QEMU_CHECK_MONITOR(mon);
++
++    return qemuMonitorJSONBlockdevReopen(mon, props);
++}
++
++
+ int
+ qemuMonitorBlockdevDel(qemuMonitorPtr mon,
+                        const char *nodename)
+diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
+index 6a6b8efaee..481fc8e12e 100644
+--- a/src/qemu/qemu_monitor.h
++++ b/src/qemu/qemu_monitor.h
+@@ -1325,6 +1325,9 @@ int qemuMonitorBlockdevCreate(qemuMonitorPtr mon,
+ int qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
+                            virJSONValuePtr *props);
+ 
++int qemuMonitorBlockdevReopen(qemuMonitorPtr mon,
++                              virJSONValuePtr *props);
++
+ int qemuMonitorBlockdevDel(qemuMonitorPtr mon,
+                            const char *nodename);
+ 
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index 3827574ef6..0122b77259 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -8830,6 +8830,27 @@ qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
+ }
+ 
+ 
++int
++qemuMonitorJSONBlockdevReopen(qemuMonitorPtr mon,
++                              virJSONValuePtr *props)
++{
++    g_autoptr(virJSONValue) cmd = NULL;
++    g_autoptr(virJSONValue) reply = NULL;
++    virJSONValuePtr pr = g_steal_pointer(props);
++
++    if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", pr)))
++        return -1;
++
++    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
++        return -1;
++
++    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
++        return -1;
++
++    return 0;
++}
++
++
+ int
+ qemuMonitorJSONBlockdevDel(qemuMonitorPtr mon,
+                            const char *nodename)
+diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
+index fd2e09025e..801babef97 100644
+--- a/src/qemu/qemu_monitor_json.h
++++ b/src/qemu/qemu_monitor_json.h
+@@ -600,6 +600,10 @@ int qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
+                                virJSONValuePtr *props)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+ 
++int qemuMonitorJSONBlockdevReopen(qemuMonitorPtr mon,
++                                  virJSONValuePtr *props)
++    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
++
+ int qemuMonitorJSONBlockdevDel(qemuMonitorPtr mon,
+                                const char *nodename)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-monitor-Improve-error-message-when-QEMU-reply-is-too-large.patch b/SOURCES/libvirt-qemu-monitor-Improve-error-message-when-QEMU-reply-is-too-large.patch
new file mode 100644
index 0000000..da7be2d
--- /dev/null
+++ b/SOURCES/libvirt-qemu-monitor-Improve-error-message-when-QEMU-reply-is-too-large.patch
@@ -0,0 +1,51 @@
+From a3bea49c6960a468ee28b6d8dd0664c1ebcbcd02 Mon Sep 17 00:00:00 2001
+Message-Id: <a3bea49c6960a468ee28b6d8dd0664c1ebcbcd02@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:46 +0100
+Subject: [PATCH] qemu: monitor: Improve error message when QEMU reply is too
+ large
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Don't use ERANGE as it doesn't make much sense in the error message.
+Also point out that the reply from qemu was too large which is not
+obvious from the original error:
+
+ error: No complete monitor response found in 10485760 bytes: Numerical result out of range
+
+The new message will read:
+
+ error: internal error: QEMU monitor reply exceeds buffer size (10485760 bytes)
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 29d43bf96a3e5886f1b32c78bbb16d1507bd0d9e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1524278
+Message-Id: <0e03a38f096e556cb82eecdb72e7dd5f86eec752.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_monitor.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
+index 4f547bf5ec..0e67851690 100644
+--- a/src/qemu/qemu_monitor.c
++++ b/src/qemu/qemu_monitor.c
+@@ -485,9 +485,9 @@ qemuMonitorIORead(qemuMonitorPtr mon)
+ 
+     if (avail < 1024) {
+         if (mon->bufferLength >= QEMU_MONITOR_MAX_RESPONSE) {
+-            virReportSystemError(ERANGE,
+-                                 _("No complete monitor response found in %d bytes"),
+-                                 QEMU_MONITOR_MAX_RESPONSE);
++            virReportError(VIR_ERR_INTERNAL_ERROR,
++                           _("QEMU monitor reply exceeds buffer size (%d bytes)"),
++                           QEMU_MONITOR_MAX_RESPONSE);
+             return -1;
+         }
+         if (VIR_REALLOC_N(mon->buffer,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-pass-virDomainObjPtr-to-qemuExtDevicesSetupCgroup.patch b/SOURCES/libvirt-qemu-pass-virDomainObjPtr-to-qemuExtDevicesSetupCgroup.patch
new file mode 100644
index 0000000..5b8062a
--- /dev/null
+++ b/SOURCES/libvirt-qemu-pass-virDomainObjPtr-to-qemuExtDevicesSetupCgroup.patch
@@ -0,0 +1,66 @@
+From 745aed1c66fcde8c8bf14d67622f02a838dd7ae2 Mon Sep 17 00:00:00 2001
+Message-Id: <745aed1c66fcde8c8bf14d67622f02a838dd7ae2@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:37 +0100
+Subject: [PATCH] qemu: pass virDomainObjPtr to qemuExtDevicesSetupCgroup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 6baf97ef2c7416f3d81bdc6cf20f121b62c8fd4f)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <fcb334eecdc7d85740f1aa5f7cd9f3d151996f99.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_cgroup.c    | 2 +-
+ src/qemu/qemu_extdevice.c | 3 ++-
+ src/qemu/qemu_extdevice.h | 2 +-
+ 3 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
+index 45701b4c6e..57a1231855 100644
+--- a/src/qemu/qemu_cgroup.c
++++ b/src/qemu/qemu_cgroup.c
+@@ -1262,7 +1262,7 @@ qemuSetupCgroupForExtDevices(virDomainObjPtr vm,
+                            false, &cgroup_temp) < 0)
+         goto cleanup;
+ 
+-    ret = qemuExtDevicesSetupCgroup(driver, vm->def, cgroup_temp);
++    ret = qemuExtDevicesSetupCgroup(driver, vm, cgroup_temp);
+ 
+  cleanup:
+     virCgroupFree(&cgroup_temp);
+diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
+index 7f3bb104d9..bb73787b8d 100644
+--- a/src/qemu/qemu_extdevice.c
++++ b/src/qemu/qemu_extdevice.c
+@@ -236,9 +236,10 @@ qemuExtDevicesHasDevice(virDomainDefPtr def)
+ 
+ int
+ qemuExtDevicesSetupCgroup(virQEMUDriverPtr driver,
+-                          virDomainDefPtr def,
++                          virDomainObjPtr vm,
+                           virCgroupPtr cgroup)
+ {
++    virDomainDefPtr def = vm->def;
+     size_t i;
+ 
+     for (i = 0; i < def->nvideos; i++) {
+diff --git a/src/qemu/qemu_extdevice.h b/src/qemu/qemu_extdevice.h
+index df29968e16..49373a15a1 100644
+--- a/src/qemu/qemu_extdevice.h
++++ b/src/qemu/qemu_extdevice.h
+@@ -58,5 +58,5 @@ void qemuExtDevicesStop(virQEMUDriverPtr driver,
+ bool qemuExtDevicesHasDevice(virDomainDefPtr def);
+ 
+ int qemuExtDevicesSetupCgroup(virQEMUDriverPtr driver,
+-                              virDomainDefPtr def,
++                              virDomainObjPtr vm,
+                               virCgroupPtr cgroup);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-preserve-error-on-bandwidth-rollback.patch b/SOURCES/libvirt-qemu-preserve-error-on-bandwidth-rollback.patch
new file mode 100644
index 0000000..d60acfa
--- /dev/null
+++ b/SOURCES/libvirt-qemu-preserve-error-on-bandwidth-rollback.patch
@@ -0,0 +1,59 @@
+From f4c935bfa5bd3e4f4856dfdf660be0fa50d42798 Mon Sep 17 00:00:00 2001
+Message-Id: <f4c935bfa5bd3e4f4856dfdf660be0fa50d42798@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Mon, 10 Feb 2020 17:05:54 +0100
+Subject: [PATCH] qemu: preserve error on bandwidth rollback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We call APIs that reset the error in the rollback code.
+Preserve the error from the original call that failed.
+
+This turns the boringly cryptic:
+  error: Unable to set interface parameters
+  error: An error occurred, but the cause is unknown
+to the unexpectedly anarchist:
+  error: internal error: Child process (/usr/sbin/tc filter add
+  dev vnet1 parent ffff: protocol all u32 match u32 0 0 police
+  rate 4294968kbps burst 4294968kb mtu 64kb drop flowid :1)
+  unexpected exit status 1: Illegal "rate"
+  Illegal "police"
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Fixes: f02e21cb3379a41cd42f2d8116f2d10dabace83b
+https://bugzilla.redhat.com/show_bug.cgi?id=1800505
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 457b0e74888f61b759e334d91479c258663835d5)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <a49ef696966d8b8ca28d298ffab16c3a77b1102a.1581350626.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_driver.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 08f492fa24..af81c4a6e4 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -11642,6 +11642,9 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
+ 
+         if (virNetDevBandwidthSet(net->ifname, newBandwidth, false,
+                                   !virDomainNetTypeSharesHostView(net)) < 0) {
++            virErrorPtr orig_err;
++
++            virErrorPreserveLast(&orig_err);
+             ignore_value(virNetDevBandwidthSet(net->ifname,
+                                                net->bandwidth,
+                                                false,
+@@ -11650,6 +11653,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
+                 ignore_value(virDomainNetBandwidthUpdate(net,
+                                                          net->bandwidth));
+             }
++            virErrorRestore(&orig_err);
+             goto endjob;
+         }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-put-virtiofsd-in-the-emulator-cgroup.patch b/SOURCES/libvirt-qemu-put-virtiofsd-in-the-emulator-cgroup.patch
new file mode 100644
index 0000000..7ce2a85
--- /dev/null
+++ b/SOURCES/libvirt-qemu-put-virtiofsd-in-the-emulator-cgroup.patch
@@ -0,0 +1,108 @@
+From 6c6f1a32c07941d6fe6208e1ad12dc137dbe7c41 Mon Sep 17 00:00:00 2001
+Message-Id: <6c6f1a32c07941d6fe6208e1ad12dc137dbe7c41@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:47 +0100
+Subject: [PATCH] qemu: put virtiofsd in the emulator cgroup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Wire up the code to put virtiofsd in the emulator cgroup on domain
+startup.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 9de5d69c218faa0e25c5d6a56ab5f6bacbd1a132)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <7653ce933656c9a13c9afa2a019ef11fb192bdc4.1583322091.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_extdevice.c | 15 +++++++++++++++
+ src/qemu/qemu_virtiofs.c  | 26 ++++++++++++++++++++++++++
+ src/qemu/qemu_virtiofs.h  |  5 +++++
+ 3 files changed, 46 insertions(+)
+
+diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
+index bfa770f45a..f66bafb62f 100644
+--- a/src/qemu/qemu_extdevice.c
++++ b/src/qemu/qemu_extdevice.c
+@@ -248,6 +248,13 @@ qemuExtDevicesHasDevice(virDomainDefPtr def)
+     if (def->tpm && def->tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR)
+         return true;
+ 
++    for (i = 0; i < def->nfss; i++) {
++        virDomainFSDefPtr fs = def->fss[i];
++
++        if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)
++            return true;
++    }
++
+     return false;
+ }
+ 
+@@ -272,5 +279,13 @@ qemuExtDevicesSetupCgroup(virQEMUDriverPtr driver,
+         qemuExtTPMSetupCgroup(driver, def, cgroup) < 0)
+         return -1;
+ 
++    for (i = 0; i < def->nfss; i++) {
++        virDomainFSDefPtr fs = def->fss[i];
++
++        if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS &&
++            qemuVirtioFSSetupCgroup(vm, fs, cgroup) < 0)
++            return -1;
++    }
++
+     return 0;
+ }
+diff --git a/src/qemu/qemu_virtiofs.c b/src/qemu/qemu_virtiofs.c
+index 09ab2cef27..194855ece8 100644
+--- a/src/qemu/qemu_virtiofs.c
++++ b/src/qemu/qemu_virtiofs.c
+@@ -299,3 +299,29 @@ qemuVirtioFSStop(virQEMUDriverPtr driver G_GNUC_UNUSED,
+  cleanup:
+     virErrorRestore(&orig_err);
+ }
++
++
++int
++qemuVirtioFSSetupCgroup(virDomainObjPtr vm,
++                        virDomainFSDefPtr fs,
++                        virCgroupPtr cgroup)
++{
++    g_autofree char *pidfile = NULL;
++    pid_t pid = -1;
++    int rc;
++
++    if (!(pidfile = qemuVirtioFSCreatePidFilename(vm, fs->info.alias)))
++        return -1;
++
++    rc = virPidFileReadPathIfAlive(pidfile, &pid, NULL);
++    if (rc < 0 || pid == (pid_t) -1) {
++        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                       _("virtiofsd died unexpectedly"));
++        return -1;
++    }
++
++    if (virCgroupAddProcess(cgroup, pid) < 0)
++        return -1;
++
++    return 0;
++}
+diff --git a/src/qemu/qemu_virtiofs.h b/src/qemu/qemu_virtiofs.h
+index b2f0c57d0c..1db59917c6 100644
+--- a/src/qemu/qemu_virtiofs.h
++++ b/src/qemu/qemu_virtiofs.h
+@@ -35,3 +35,8 @@ void
+ qemuVirtioFSStop(virQEMUDriverPtr driver,
+                  virDomainObjPtr vm,
+                  virDomainFSDefPtr fs);
++
++int
++qemuVirtioFSSetupCgroup(virDomainObjPtr vm,
++                        virDomainFSDefPtr fs,
++                        virCgroupPtr cgroup);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-remove-qemuDomainObjBegin-EndJobWithAgent.patch b/SOURCES/libvirt-qemu-remove-qemuDomainObjBegin-EndJobWithAgent.patch
new file mode 100644
index 0000000..0c478d3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-remove-qemuDomainObjBegin-EndJobWithAgent.patch
@@ -0,0 +1,228 @@
+From bac1c96fbf2bd9d6ef728a813fda793ce1e99267 Mon Sep 17 00:00:00 2001
+Message-Id: <bac1c96fbf2bd9d6ef728a813fda793ce1e99267@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Thu, 20 Feb 2020 10:52:27 -0600
+Subject: [PATCH] qemu: remove qemuDomainObjBegin/EndJobWithAgent()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This function potentially grabs both a monitor job and an agent job at
+the same time. This is problematic because it means that a malicious (or
+just buggy) guest agent can cause a denial of service on the host. The
+presence of this function makes it easy to do the wrong thing and hold
+both jobs at the same time. All existing uses have already been removed
+by previous commits.
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 3c436c22a4f94c85c2b5e7b5fb84af48219d78e3)
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1759566
+Message-Id: <20200220165227.11491-6-jjongsma@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/THREADS.txt   | 58 +++++-------------------------------------
+ src/qemu/qemu_domain.c | 56 ++++------------------------------------
+ src/qemu/qemu_domain.h |  7 -----
+ 3 files changed, 11 insertions(+), 110 deletions(-)
+
+diff --git a/src/qemu/THREADS.txt b/src/qemu/THREADS.txt
+index aa428fda6a..a7d8709a43 100644
+--- a/src/qemu/THREADS.txt
++++ b/src/qemu/THREADS.txt
+@@ -61,11 +61,12 @@ There are a number of locks on various objects
+ 
+     Agent job condition is then used when thread wishes to talk to qemu
+     agent monitor. It is possible to acquire just agent job
+-    (qemuDomainObjBeginAgentJob), or only normal job
+-    (qemuDomainObjBeginJob) or both at the same time
+-    (qemuDomainObjBeginJobWithAgent). Which type of job to grab depends
+-    whether caller wishes to communicate only with agent socket, or only
+-    with qemu monitor socket or both, respectively.
++    (qemuDomainObjBeginAgentJob), or only normal job (qemuDomainObjBeginJob)
++    but not both at the same time. Holding an agent job and a normal job would
++    allow an unresponsive or malicious agent to block normal libvirt API and
++    potentially result in a denial of service. Which type of job to grab
++    depends whether caller wishes to communicate only with agent socket, or
++    only with qemu monitor socket.
+ 
+     Immediately after acquiring the virDomainObjPtr lock, any method
+     which intends to update state must acquire asynchronous, normal or
+@@ -141,18 +142,6 @@ To acquire the agent job condition
+ 
+ 
+ 
+-To acquire both normal and agent job condition
+-
+-  qemuDomainObjBeginJobWithAgent()
+-    - Waits until there is no normal and no agent job set
+-    - Sets both job.active and job.agentActive with required job types
+-
+-  qemuDomainObjEndJobWithAgent()
+-    - Sets both job.active and job.agentActive to 0
+-    - Signals on job.cond condition
+-
+-
+-
+ To acquire the asynchronous job condition
+ 
+   qemuDomainObjBeginAsyncJob()
+@@ -292,41 +281,6 @@ Design patterns
+      virDomainObjEndAPI(&obj);
+ 
+ 
+- * Invoking both monitor and agent commands on a virDomainObjPtr
+-
+-     virDomainObjPtr obj;
+-     qemuAgentPtr agent;
+-
+-     obj = qemuDomObjFromDomain(dom);
+-
+-     qemuDomainObjBeginJobWithAgent(obj, QEMU_JOB_TYPE, QEMU_AGENT_JOB_TYPE);
+-
+-     if (!virDomainObjIsActive(dom))
+-         goto cleanup;
+-
+-     ...do prep work...
+-
+-     if (!qemuDomainAgentAvailable(obj, true))
+-         goto cleanup;
+-
+-     agent = qemuDomainObjEnterAgent(obj);
+-     qemuAgentXXXX(agent, ..);
+-     qemuDomainObjExitAgent(obj, agent);
+-
+-     ...
+-
+-     qemuDomainObjEnterMonitor(obj);
+-     qemuMonitorXXXX(priv->mon);
+-     qemuDomainObjExitMonitor(obj);
+-
+-     /* Alternatively, talk to the monitor first and then talk to the agent. */
+-
+-     ...do final work...
+-
+-     qemuDomainObjEndJobWithAgent(obj);
+-     virDomainObjEndAPI(&obj);
+-
+-
+  * Running asynchronous job
+ 
+      virDomainObjPtr obj;
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 0baa80582c..f037f0812e 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -9734,26 +9734,6 @@ qemuDomainObjBeginAgentJob(virQEMUDriverPtr driver,
+                                          QEMU_ASYNC_JOB_NONE, false);
+ }
+ 
+-/**
+- * qemuDomainObjBeginJobWithAgent:
+- *
+- * Grabs both monitor and agent types of job. Use if caller talks to
+- * both monitor and guest agent. However, if @job (or @agentJob) is
+- * QEMU_JOB_NONE (or QEMU_AGENT_JOB_NONE) only agent job is acquired (or
+- * monitor job).
+- *
+- * To end job call qemuDomainObjEndJobWithAgent.
+- */
+-int
+-qemuDomainObjBeginJobWithAgent(virQEMUDriverPtr driver,
+-                               virDomainObjPtr obj,
+-                               qemuDomainJob job,
+-                               qemuDomainAgentJob agentJob)
+-{
+-    return qemuDomainObjBeginJobInternal(driver, obj, job, agentJob,
+-                                         QEMU_ASYNC_JOB_NONE, false);
+-}
+-
+ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
+                                virDomainObjPtr obj,
+                                qemuDomainAsyncJob asyncJob,
+@@ -9868,31 +9848,6 @@ qemuDomainObjEndAgentJob(virDomainObjPtr obj)
+     virCondBroadcast(&priv->job.cond);
+ }
+ 
+-void
+-qemuDomainObjEndJobWithAgent(virQEMUDriverPtr driver,
+-                             virDomainObjPtr obj)
+-{
+-    qemuDomainObjPrivatePtr priv = obj->privateData;
+-    qemuDomainJob job = priv->job.active;
+-    qemuDomainAgentJob agentJob = priv->job.agentActive;
+-
+-    priv->jobs_queued--;
+-
+-    VIR_DEBUG("Stopping both jobs: %s %s (async=%s vm=%p name=%s)",
+-              qemuDomainJobTypeToString(job),
+-              qemuDomainAgentJobTypeToString(agentJob),
+-              qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
+-              obj, obj->def->name);
+-
+-    qemuDomainObjResetJob(priv);
+-    qemuDomainObjResetAgentJob(priv);
+-    if (qemuDomainTrackJob(job))
+-        qemuDomainObjSaveStatus(driver, obj);
+-    /* We indeed need to wake up ALL threads waiting because
+-     * grabbing a job requires checking more variables. */
+-    virCondBroadcast(&priv->job.cond);
+-}
+-
+ void
+ qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj)
+ {
+@@ -9926,9 +9881,9 @@ qemuDomainObjAbortAsyncJob(virDomainObjPtr obj)
+  * obj must be locked before calling
+  *
+  * To be called immediately before any QEMU monitor API call
+- * Must have already either called qemuDomainObjBeginJob() or
+- * qemuDomainObjBeginJobWithAgent() and checked that the VM is
+- * still active; may not be used for nested async jobs.
++ * Must have already called qemuDomainObjBeginJob() and checked
++ * that the VM is still active; may not be used for nested async
++ * jobs.
+  *
+  * To be followed with qemuDomainObjExitMonitor() once complete
+  */
+@@ -10050,9 +10005,8 @@ qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
+  * obj must be locked before calling
+  *
+  * To be called immediately before any QEMU agent API call.
+- * Must have already called qemuDomainObjBeginAgentJob() or
+- * qemuDomainObjBeginJobWithAgent() and checked that the VM is
+- * still active.
++ * Must have already called qemuDomainObjBeginAgentJob() and
++ * checked that the VM is still active.
+  *
+  * To be followed with qemuDomainObjExitAgent() once complete
+  */
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index cdcb6ecc7a..c581b3a162 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -651,11 +651,6 @@ int qemuDomainObjBeginAgentJob(virQEMUDriverPtr driver,
+                                virDomainObjPtr obj,
+                                qemuDomainAgentJob agentJob)
+     G_GNUC_WARN_UNUSED_RESULT;
+-int qemuDomainObjBeginJobWithAgent(virQEMUDriverPtr driver,
+-                                   virDomainObjPtr obj,
+-                                   qemuDomainJob job,
+-                                   qemuDomainAgentJob agentJob)
+-    G_GNUC_WARN_UNUSED_RESULT;
+ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
+                                virDomainObjPtr obj,
+                                qemuDomainAsyncJob asyncJob,
+@@ -674,8 +669,6 @@ int qemuDomainObjBeginJobNowait(virQEMUDriverPtr driver,
+ void qemuDomainObjEndJob(virQEMUDriverPtr driver,
+                          virDomainObjPtr obj);
+ void qemuDomainObjEndAgentJob(virDomainObjPtr obj);
+-void qemuDomainObjEndJobWithAgent(virQEMUDriverPtr driver,
+-                                  virDomainObjPtr obj);
+ void qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver,
+                               virDomainObjPtr obj);
+ void qemuDomainObjAbortAsyncJob(virDomainObjPtr obj);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-rename-qemuAgentGetFSInfoInternalDisk.patch b/SOURCES/libvirt-qemu-rename-qemuAgentGetFSInfoInternalDisk.patch
new file mode 100644
index 0000000..f5a4707
--- /dev/null
+++ b/SOURCES/libvirt-qemu-rename-qemuAgentGetFSInfoInternalDisk.patch
@@ -0,0 +1,53 @@
+From f1ffcda533c6c95e70044aeee86d017ae6132876 Mon Sep 17 00:00:00 2001
+Message-Id: <f1ffcda533c6c95e70044aeee86d017ae6132876@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Thu, 20 Feb 2020 10:52:23 -0600
+Subject: [PATCH] qemu: rename qemuAgentGetFSInfoInternalDisk()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The function name doesn't give a good idea of what the function does.
+Rename to qemuAgentGetFSInfoFillDisks() to make it more obvious than it
+is filling in the disk information in the fsinfo struct.
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit e888c0f66752bb6516d63a612c20f565cbf9c0ca)
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1759566
+Message-Id: <20200220165227.11491-2-jjongsma@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_agent.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
+index f759785050..0f099f3b2a 100644
+--- a/src/qemu/qemu_agent.c
++++ b/src/qemu/qemu_agent.c
+@@ -1925,9 +1925,9 @@ qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent)
+ }
+ 
+ static int
+-qemuAgentGetFSInfoInternalDisk(virJSONValuePtr jsondisks,
+-                               qemuAgentFSInfoPtr fsinfo,
+-                               virDomainDefPtr vmdef)
++qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
++                            qemuAgentFSInfoPtr fsinfo,
++                            virDomainDefPtr vmdef)
+ {
+     size_t ndisks;
+     size_t i;
+@@ -2139,7 +2139,7 @@ qemuAgentGetFSInfoInternal(qemuAgentPtr mon,
+             goto cleanup;
+         }
+ 
+-        if (qemuAgentGetFSInfoInternalDisk(disk, info_ret[i], vmdef) < 0)
++        if (qemuAgentGetFSInfoFillDisks(disk, info_ret[i], vmdef) < 0)
+             goto cleanup;
+     }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-snapshot-Always-rewrite-backingStore-data-when-reusing-existing-images.patch b/SOURCES/libvirt-qemu-snapshot-Always-rewrite-backingStore-data-when-reusing-existing-images.patch
new file mode 100644
index 0000000..003b246
--- /dev/null
+++ b/SOURCES/libvirt-qemu-snapshot-Always-rewrite-backingStore-data-when-reusing-existing-images.patch
@@ -0,0 +1,46 @@
+From 647f43ec778b6d5dafb256d5dbe4ad1f0a4e9776 Mon Sep 17 00:00:00 2001
+Message-Id: <647f43ec778b6d5dafb256d5dbe4ad1f0a4e9776@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:47 +0100
+Subject: [PATCH] qemu: snapshot: Always rewrite backingStore data when reusing
+ existing images
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Don't adopt the backing store data when reusing images provided by the
+user. This will force a backing chain re-probe as users might have
+passed in something unexpected in the overlay where our view of the
+backing chain would not correspond.
+
+This is done only for inactive snapshots as there we have way less
+verification.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 8e9e73a984165d5e9a82ba1f4531bb30482db5a8)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1524278
+Message-Id: <baa37a0240d05d2441a54e7ad1c1a8648c7e7f65.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index e651c9e819..5c72db2544 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -14678,7 +14678,8 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
+         if (virStorageSourceInitChainElement(newsrc, defdisk->src, false) < 0)
+             goto cleanup;
+ 
+-        if (virStorageSourceHasBacking(defdisk->src)) {
++        if (!reuse &&
++            virStorageSourceHasBacking(defdisk->src)) {
+             defdisk->src->readonly = true;
+             newsrc->backingStore = g_steal_pointer(&defdisk->src);
+         } else {
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-snapshot-Prevent-too-nested-domain-XML-when-doing-inactive-snapshot.patch b/SOURCES/libvirt-qemu-snapshot-Prevent-too-nested-domain-XML-when-doing-inactive-snapshot.patch
new file mode 100644
index 0000000..48e23b3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-snapshot-Prevent-too-nested-domain-XML-when-doing-inactive-snapshot.patch
@@ -0,0 +1,48 @@
+From 97dafbcc080bdb3253dbd451c94ab8f687b156ba Mon Sep 17 00:00:00 2001
+Message-Id: <97dafbcc080bdb3253dbd451c94ab8f687b156ba@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:48 +0100
+Subject: [PATCH] qemu: snapshot: Prevent too-nested domain XML when doing
+ inactive snapshot
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Similarly to 510d154a0b41aa70aadabc0918d16dee22882394 we need to prevent
+doing too deeply nested backing chains and reject them with a sane error
+message.
+
+Add a loop to go through the snapshots prior to attempting actually
+creating them to prevent some possible inconsistent scenarios.
+
+We don't need to do it when reusing backing chains as we'll be
+re-detecting the backing chain in that case anyways.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit b168fa88b85dec181882816ab65a59a6c4500667)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1524278
+Message-Id: <3272682df55dcc564055a2badb0c61d4680c81a9.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 5c72db2544..833cf9f3d9 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -14632,6 +14632,9 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
+         if (!snapdisk->src->format)
+             snapdisk->src->format = VIR_STORAGE_FILE_QCOW2;
+ 
++        if (qemuDomainStorageSourceValidateDepth(defdisk->src, 1, defdisk->dst) < 0)
++            return -1;
++
+         /* creates cmd line args: qemu-img create -f qcow2 -o */
+         if (!(cmd = virCommandNewArgList(qemuImgPath,
+                                          "create",
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-snapshot-go-through-cleanup-on-error.patch b/SOURCES/libvirt-qemu-snapshot-go-through-cleanup-on-error.patch
new file mode 100644
index 0000000..d1fefbd
--- /dev/null
+++ b/SOURCES/libvirt-qemu-snapshot-go-through-cleanup-on-error.patch
@@ -0,0 +1,41 @@
+From 1196c633f969dd9457b9b431fbcd944e35249b5f Mon Sep 17 00:00:00 2001
+Message-Id: <1196c633f969dd9457b9b431fbcd944e35249b5f@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:58 +0100
+Subject: [PATCH] qemu: snapshot: go through cleanup on error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A recent commit added an error check for too-nested backing chains
+followed by a return, even though errors above jump to cleanup.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Fixes: b168fa88b85dec181882816ab65a59a6c4500667
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit c07ef7c563c7d661fd4b59bac190cd1db44bd3e5)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1524278
+Message-Id: <5903cd3cb7845ed3151492457a4e92e57a15fef0.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 833cf9f3d9..e19e1da0bb 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -14633,7 +14633,7 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
+             snapdisk->src->format = VIR_STORAGE_FILE_QCOW2;
+ 
+         if (qemuDomainStorageSourceValidateDepth(defdisk->src, 1, defdisk->dst) < 0)
+-            return -1;
++            goto cleanup;
+ 
+         /* creates cmd line args: qemu-img create -f qcow2 -o */
+         if (!(cmd = virCommandNewArgList(qemuImgPath,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-store-complete-agent-filesystem-information.patch b/SOURCES/libvirt-qemu-store-complete-agent-filesystem-information.patch
new file mode 100644
index 0000000..7d76633
--- /dev/null
+++ b/SOURCES/libvirt-qemu-store-complete-agent-filesystem-information.patch
@@ -0,0 +1,116 @@
+From 668555bc90e36fd571ff3ac5aa798e951a84ee19 Mon Sep 17 00:00:00 2001
+Message-Id: <668555bc90e36fd571ff3ac5aa798e951a84ee19@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Thu, 20 Feb 2020 10:52:24 -0600
+Subject: [PATCH] qemu: store complete agent filesystem information
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In an effort to avoid holding both an agent and normal job at the same
+time, we shouldn't access the vm definition from within qemu_agent.c
+(i.e. while the agent job is being held). In preparation, we need to
+store the full filesystem disk information in qemuAgentDiskInfo.  In a
+following commit, we can pass this information back to the caller and
+the caller can search the vm definition to match the filsystem disk to
+an alias.
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit bdb8a800b4920cf9184fd2fd117b17c67ba74dfb)
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1759566
+Message-Id: <20200220165227.11491-3-jjongsma@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_agent.c | 36 ++++++++++++++++++++----------------
+ 1 file changed, 20 insertions(+), 16 deletions(-)
+
+diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
+index 0f099f3b2a..077b5538de 100644
+--- a/src/qemu/qemu_agent.c
++++ b/src/qemu/qemu_agent.c
+@@ -1849,6 +1849,11 @@ typedef qemuAgentDiskInfo *qemuAgentDiskInfoPtr;
+ struct _qemuAgentDiskInfo {
+     char *alias;
+     char *serial;
++    virPCIDeviceAddress pci_controller;
++    char *bus_type;
++    unsigned int bus;
++    unsigned int target;
++    unsigned int unit;
+     char *devnode;
+ };
+ 
+@@ -1872,6 +1877,7 @@ qemuAgentDiskInfoFree(qemuAgentDiskInfoPtr info)
+ 
+     VIR_FREE(info->serial);
+     VIR_FREE(info->alias);
++    VIR_FREE(info->bus_type);
+     VIR_FREE(info->devnode);
+     VIR_FREE(info);
+ }
+@@ -1952,10 +1958,6 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+         qemuAgentDiskInfoPtr disk;
+         virDomainDiskDefPtr diskDef;
+         const char *val;
+-        unsigned int bus;
+-        unsigned int target;
+-        unsigned int unit;
+-        virPCIDeviceAddress pci_address;
+ 
+         if (!jsondisk) {
+             virReportError(VIR_ERR_INTERNAL_ERROR,
+@@ -1969,6 +1971,9 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+             return -1;
+         disk = fsinfo->disks[i];
+ 
++        if ((val = virJSONValueObjectGetString(jsondisk, "bus-type")))
++            disk->bus_type = g_strdup(val);
++
+         if ((val = virJSONValueObjectGetString(jsondisk, "serial")))
+             disk->serial = g_strdup(val);
+ 
+@@ -1985,9 +1990,9 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+             } \
+         } while (0)
+ 
+-        GET_DISK_ADDR(jsondisk, &bus, "bus");
+-        GET_DISK_ADDR(jsondisk, &target, "target");
+-        GET_DISK_ADDR(jsondisk, &unit, "unit");
++        GET_DISK_ADDR(jsondisk, &disk->bus, "bus");
++        GET_DISK_ADDR(jsondisk, &disk->target, "target");
++        GET_DISK_ADDR(jsondisk, &disk->unit, "unit");
+ 
+         if (!(pci = virJSONValueObjectGet(jsondisk, "pci-controller"))) {
+             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+@@ -1996,18 +2001,17 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+             return -1;
+         }
+ 
+-        GET_DISK_ADDR(pci, &pci_address.domain, "domain");
+-        GET_DISK_ADDR(pci, &pci_address.bus, "bus");
+-        GET_DISK_ADDR(pci, &pci_address.slot, "slot");
+-        GET_DISK_ADDR(pci, &pci_address.function, "function");
++        GET_DISK_ADDR(pci, &disk->pci_controller.domain, "domain");
++        GET_DISK_ADDR(pci, &disk->pci_controller.bus, "bus");
++        GET_DISK_ADDR(pci, &disk->pci_controller.slot, "slot");
++        GET_DISK_ADDR(pci, &disk->pci_controller.function, "function");
+ 
+ #undef GET_DISK_ADDR
+-
+         if (!(diskDef = virDomainDiskByAddress(vmdef,
+-                                               &pci_address,
+-                                               bus,
+-                                               target,
+-                                               unit)))
++                                               &disk->pci_controller,
++                                               disk->bus,
++                                               disk->target,
++                                               disk->unit)))
+             continue;
+ 
+         disk->alias = g_strdup(diskDef->dst);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-support-interface-teaming-functionality.patch b/SOURCES/libvirt-qemu-support-interface-teaming-functionality.patch
new file mode 100644
index 0000000..524c2aa
--- /dev/null
+++ b/SOURCES/libvirt-qemu-support-interface-teaming-functionality.patch
@@ -0,0 +1,222 @@
+From 16ba1d0258765d9c3b5e2da666ed6d4d933e26d9 Mon Sep 17 00:00:00 2001
+Message-Id: <16ba1d0258765d9c3b5e2da666ed6d4d933e26d9@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Thu, 30 Jan 2020 14:12:41 -0500
+Subject: [PATCH] qemu: support interface <teaming> functionality
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The QEMU driver uses the <teaming type='persistent|transient'
+persistent='blah'/> element to setup a "failover" pair of devices -
+the persistent device must be a virtio emulated NIC, with the only
+extra configuration being the addition of ",failover=on" to the device
+commandline, and the transient device must be a hostdev NIC
+(<interface type='hostdev'> or <interface type='network'> with a
+network that is a pool of SRIOV VFs) where the extra configuration is
+the addition of ",failover_pair_id=$aliasOfVirtio" to the device
+commandline. These new options are supported in QEMU 4.2.0 and later.
+
+Extra qemu-specific validation is added to ensure that the device
+type/model is appropriate and that the qemu binary supports these
+commandline options.
+
+The result of this will be:
+
+1) The virtio device presented to the guest will have an extra bit set
+in its PCI capabilities indicating that it can be used as a failover
+backup device. The virtio guest driver will need to be equipped to do
+something with this information - this is included in the Linux
+virtio-net driver in kernel 4.18 and above (and also backported to
+some older distro kernels). Unfortunately there is no way for libvirt
+to learn whether or not the guest driver supports failover - if it
+doesn't then the extra PCI capability will be ignored and the guest OS
+will just see two independent devices. (NB: the current virtio guest
+driver also requires that the MAC addresses of the two NICs match in
+order to pair them into a bond).
+
+2) When a migration is requested, QEMu will automatically unplug the
+transient/hostdev NIC from the guest on the source host before
+starting migration, and automatically re-plug a similar device after
+restarting the guest CPUs on the destination host. While the transient
+NIC is unplugged, all network traffic will go through the
+persistent/virtio device, but when the hostdev NIC is plugged in, it
+will get all the traffic. This means that in normal circumstances the
+guest gets the performance advantage of vfio-assigned "real hardware"
+networking, but it can still be migrated with the only downside being
+a performance penalty (due to using an emulated NIC) during the
+migration.
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit eb9f6cc4b3464707cf689fda9812e5129003bf27)
+
+https://bugzilla.redhat.com/1693587
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20200130191244.24174-4-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_command.c                       |  9 +++++
+ src/qemu/qemu_domain.c                        | 36 +++++++++++++++--
+ .../qemuxml2argvdata/net-virtio-teaming.args  | 40 +++++++++++++++++++
+ tests/qemuxml2argvtest.c                      |  4 ++
+ 4 files changed, 86 insertions(+), 3 deletions(-)
+ create mode 100644 tests/qemuxml2argvdata/net-virtio-teaming.args
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 7a184c229e..d144855b0d 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -3833,6 +3833,8 @@ qemuBuildNicDevStr(virDomainDefPtr def,
+         }
+         virBufferAsprintf(&buf, ",host_mtu=%u", net->mtu);
+     }
++    if (usingVirtio && net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_PERSISTENT)
++       virBufferAddLit(&buf, ",failover=on");
+ 
+     virBufferAsprintf(&buf, ",netdev=host%s", net->info.alias);
+     virBufferAsprintf(&buf, ",id=%s", net->info.alias);
+@@ -4704,6 +4706,13 @@ qemuBuildPCIHostdevDevStr(const virDomainDef *def,
+     if (qemuBuildRomStr(&buf, dev->info) < 0)
+         return NULL;
+ 
++    if (dev->parentnet &&
++        dev->parentnet->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT &&
++        dev->parentnet->teaming.persistent) {
++        virBufferAsprintf(&buf,  ",failover_pair_id=%s",
++                          dev->parentnet->teaming.persistent);
++    }
++
+     return virBufferContentAndReset(&buf);
+ }
+ 
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 91a9f0481b..e37404340f 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -6391,12 +6391,20 @@ qemuDomainValidateActualNetDef(const virDomainNetDef *net,
+         return -1;
+     }
+ 
++    if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT &&
++        actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                       _("interface %s - teaming transient device must be type='hostdev', not '%s'"),
++                       macstr, virDomainNetTypeToString(actualType));
++        return -1;
++    }
+     return 0;
+ }
+ 
+ 
+ static int
+-qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net)
++qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net,
++                                   virQEMUCapsPtr qemuCaps)
+ {
+     bool hasIPv4 = false;
+     bool hasIPv6 = false;
+@@ -6481,7 +6489,29 @@ qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net)
+         return -1;
+     }
+ 
+-    if (net->coalesce && !qemuDomainNetSupportsCoalesce(net->type)) {
++    if (net->teaming.type != VIR_DOMAIN_NET_TEAMING_TYPE_NONE &&
++        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_FAILOVER)) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                       _("virtio-net failover (teaming) is not supported with this QEMU binary"));
++        return -1;
++    }
++    if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_PERSISTENT
++        && !virDomainNetIsVirtioModel(net)) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                       _("virtio-net teaming persistent interface must be <model type='virtio'/>, not '%s'"),
++                       virDomainNetGetModelString(net));
++        return -1;
++    }
++    if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT &&
++        net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
++        net->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                       _("virtio-net teaming transient interface must be type='hostdev', not '%s'"),
++                       virDomainNetTypeToString(net->type));
++        return -1;
++    }
++
++   if (net->coalesce && !qemuDomainNetSupportsCoalesce(net->type)) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                        _("coalesce settings on interface type %s are not supported"),
+                        virDomainNetTypeToString(net->type));
+@@ -8377,7 +8407,7 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
+ 
+     switch ((virDomainDeviceType)dev->type) {
+     case VIR_DOMAIN_DEVICE_NET:
+-        ret = qemuDomainDeviceDefValidateNetwork(dev->data.net);
++        ret = qemuDomainDeviceDefValidateNetwork(dev->data.net, qemuCaps);
+         break;
+ 
+     case VIR_DOMAIN_DEVICE_CHR:
+diff --git a/tests/qemuxml2argvdata/net-virtio-teaming.args b/tests/qemuxml2argvdata/net-virtio-teaming.args
+new file mode 100644
+index 0000000000..19e7260843
+--- /dev/null
++++ b/tests/qemuxml2argvdata/net-virtio-teaming.args
+@@ -0,0 +1,40 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-QEMUGuest1 \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-i386 \
++-name QEMUGuest1 \
++-S \
++-machine pc,accel=tcg,usb=off,dump-guest-core=off \
++-m 214 \
++-realtime mlock=off \
++-smp 1,sockets=1,cores=1,threads=1 \
++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
++server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-no-acpi \
++-usb \
++-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
++-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
++-netdev user,id=hostua-backup0 \
++-device virtio-net-pci,failover=on,netdev=hostua-backup0,id=ua-backup0,\
++mac=00:11:22:33:44:55,bus=pci.0,addr=0x3 \
++-netdev user,id=hostua-backup1 \
++-device virtio-net-pci,failover=on,netdev=hostua-backup1,id=ua-backup1,\
++mac=66:44:33:22:11:00,bus=pci.0,addr=0x4 \
++-device vfio-pci,host=0000:03:07.1,id=hostdev0,bus=pci.0,addr=0x5,\
++failover_pair_id=ua-backup0 \
++-device vfio-pci,host=0000:03:07.2,id=hostdev1,bus=pci.0,addr=0x6,\
++failover_pair_id=ua-backup1 \
++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index b923590930..4d26fe0b55 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1308,6 +1308,10 @@ mymain(void)
+             QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE,
+             QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE);
+     DO_TEST_PARSE_ERROR("net-virtio-rxqueuesize-invalid-size", NONE);
++    DO_TEST("net-virtio-teaming",
++            QEMU_CAPS_VIRTIO_NET_FAILOVER,
++            QEMU_CAPS_DEVICE_VFIO_PCI);
++    DO_TEST_PARSE_ERROR("net-virtio-teaming", NONE);
+     DO_TEST("net-eth", NONE);
+     DO_TEST("net-eth-ifname", NONE);
+     DO_TEST("net-eth-names", NONE);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu-use-def-instead-of-vm-def-in-qemuExtDevicesStart.patch b/SOURCES/libvirt-qemu-use-def-instead-of-vm-def-in-qemuExtDevicesStart.patch
new file mode 100644
index 0000000..f8cd2ff
--- /dev/null
+++ b/SOURCES/libvirt-qemu-use-def-instead-of-vm-def-in-qemuExtDevicesStart.patch
@@ -0,0 +1,54 @@
+From ea0983a0cca71ba3fdefe94881fe75ee624adf5f Mon Sep 17 00:00:00 2001
+Message-Id: <ea0983a0cca71ba3fdefe94881fe75ee624adf5f@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:30 +0100
+Subject: [PATCH] qemu: use def instead of vm->def in qemuExtDevicesStart
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We have a helper variable to make the code more concise,
+use it consistently.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit e2ca6eb08731255b9b7cf3e938d20f4eae9fb427)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <3876fc88964781aec976d1a92b810aa9cf53c656.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_extdevice.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
+index 463f76c21a..1869a42f11 100644
+--- a/src/qemu/qemu_extdevice.c
++++ b/src/qemu/qemu_extdevice.c
+@@ -159,11 +159,11 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
+     int ret = 0;
+     size_t i;
+ 
+-    if (qemuExtDevicesInitPaths(driver, vm->def) < 0)
++    if (qemuExtDevicesInitPaths(driver, def) < 0)
+         return -1;
+ 
+-    for (i = 0; i < vm->def->nvideos; i++) {
+-        virDomainVideoDefPtr video = vm->def->videos[i];
++    for (i = 0; i < def->nvideos; i++) {
++        virDomainVideoDefPtr video = def->videos[i];
+ 
+         if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+             ret = qemuExtVhostUserGPUStart(driver, vm, video);
+@@ -172,7 +172,7 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
+         }
+     }
+ 
+-    if (vm->def->tpm)
++    if (def->tpm)
+         ret = qemuExtTPMStart(driver, vm, incomingMigration);
+ 
+     for (i = 0; i < def->nnets; i++) {
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-use-the-vhost-user-schemas-to-find-binary.patch b/SOURCES/libvirt-qemu-use-the-vhost-user-schemas-to-find-binary.patch
new file mode 100644
index 0000000..965141d
--- /dev/null
+++ b/SOURCES/libvirt-qemu-use-the-vhost-user-schemas-to-find-binary.patch
@@ -0,0 +1,150 @@
+From f15a4eb66ecbfb80340bbab65150b22ab3a313fe Mon Sep 17 00:00:00 2001
+Message-Id: <f15a4eb66ecbfb80340bbab65150b22ab3a313fe@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:48 +0100
+Subject: [PATCH] qemu: use the vhost-user schemas to find binary
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Look into /usr/share/qemu/vhost-user to see whether we can find
+a suitable virtiofsd binary, in case the user did not provide one
+in the domain XML.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 071a1ab92fbbd58f68fb4929d004d6155759067e)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <e422c33d2c825f91b90eb10ef1530406a3492e0e.1583322091.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_extdevice.c  |  9 +++++++++
+ src/qemu/qemu_vhost_user.c | 39 ++++++++++++++++++++++++++++++++++++++
+ src/qemu/qemu_vhost_user.h |  4 ++++
+ src/qemu/qemu_virtiofs.c   | 11 +++++++++++
+ src/qemu/qemu_virtiofs.h   |  4 ++++
+ 5 files changed, 67 insertions(+)
+
+diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
+index f66bafb62f..07b9117f57 100644
+--- a/src/qemu/qemu_extdevice.c
++++ b/src/qemu/qemu_extdevice.c
+@@ -105,6 +105,15 @@ qemuExtDevicesPrepareDomain(virQEMUDriverPtr driver,
+         }
+     }
+ 
++    for (i = 0; i < vm->def->nfss; i++) {
++        virDomainFSDefPtr fs = vm->def->fss[i];
++
++        if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
++            if (qemuVirtioFSPrepareDomain(driver, fs) < 0)
++                return -1;
++        }
++    }
++
+     return ret;
+ }
+ 
+diff --git a/src/qemu/qemu_vhost_user.c b/src/qemu/qemu_vhost_user.c
+index 4c25b30664..a3d5ac0fc7 100644
+--- a/src/qemu/qemu_vhost_user.c
++++ b/src/qemu/qemu_vhost_user.c
+@@ -416,3 +416,42 @@ qemuVhostUserFillDomainGPU(virQEMUDriverPtr driver,
+     VIR_FREE(vus);
+     return ret;
+ }
++
++
++int
++qemuVhostUserFillDomainFS(virQEMUDriverPtr driver,
++                          virDomainFSDefPtr fs)
++{
++    qemuVhostUserPtr *vus = NULL;
++    ssize_t nvus = 0;
++    ssize_t i;
++    int ret = -1;
++
++    if ((nvus = qemuVhostUserFetchParsedConfigs(driver->privileged,
++                                                &vus, NULL)) < 0)
++        goto end;
++
++    for (i = 0; i < nvus; i++) {
++        qemuVhostUserPtr vu = vus[i];
++
++        if (vu->type != QEMU_VHOST_USER_TYPE_FS)
++            continue;
++
++        fs->binary = g_strdup(vu->binary);
++        break;
++    }
++
++    if (i == nvus) {
++        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
++                       _("Unable to find a satisfying virtiofsd"));
++        goto end;
++    }
++
++    ret = 0;
++
++ end:
++    for (i = 0; i < nvus; i++)
++        qemuVhostUserFree(vus[i]);
++    g_free(vus);
++    return ret;
++}
+diff --git a/src/qemu/qemu_vhost_user.h b/src/qemu/qemu_vhost_user.h
+index 369ba00caa..e505c8a473 100644
+--- a/src/qemu/qemu_vhost_user.h
++++ b/src/qemu/qemu_vhost_user.h
+@@ -45,3 +45,7 @@ qemuVhostUserFetchConfigs(char ***configs,
+ int
+ qemuVhostUserFillDomainGPU(virQEMUDriverPtr driver,
+                            virDomainVideoDefPtr video);
++
++int
++qemuVhostUserFillDomainFS(virQEMUDriverPtr driver,
++                          virDomainFSDefPtr fs);
+diff --git a/src/qemu/qemu_virtiofs.c b/src/qemu/qemu_virtiofs.c
+index 194855ece8..d579ce1d33 100644
+--- a/src/qemu/qemu_virtiofs.c
++++ b/src/qemu/qemu_virtiofs.c
+@@ -28,6 +28,7 @@
+ #include "qemu_conf.h"
+ #include "qemu_extdevice.h"
+ #include "qemu_security.h"
++#include "qemu_vhost_user.h"
+ #include "qemu_virtiofs.h"
+ #include "virpidfile.h"
+ #include "virqemu.h"
+@@ -325,3 +326,13 @@ qemuVirtioFSSetupCgroup(virDomainObjPtr vm,
+ 
+     return 0;
+ }
++
++int
++qemuVirtioFSPrepareDomain(virQEMUDriverPtr driver,
++                          virDomainFSDefPtr fs)
++{
++    if (fs->binary)
++        return 0;
++
++    return qemuVhostUserFillDomainFS(driver, fs);
++}
+diff --git a/src/qemu/qemu_virtiofs.h b/src/qemu/qemu_virtiofs.h
+index 1db59917c6..7de4ea6190 100644
+--- a/src/qemu/qemu_virtiofs.h
++++ b/src/qemu/qemu_virtiofs.h
+@@ -40,3 +40,7 @@ int
+ qemuVirtioFSSetupCgroup(virDomainObjPtr vm,
+                         virDomainFSDefPtr fs,
+                         virCgroupPtr cgroup);
++
++int
++qemuVirtioFSPrepareDomain(virQEMUDriverPtr driver,
++                          virDomainFSDefPtr fs);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-validate-virtiofs-filesystems.patch b/SOURCES/libvirt-qemu-validate-virtiofs-filesystems.patch
new file mode 100644
index 0000000..40be59b
--- /dev/null
+++ b/SOURCES/libvirt-qemu-validate-virtiofs-filesystems.patch
@@ -0,0 +1,137 @@
+From 3366d4df5aac258013848cf5df7c95d45693c1e0 Mon Sep 17 00:00:00 2001
+Message-Id: <3366d4df5aac258013848cf5df7c95d45693c1e0@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:44 +0100
+Subject: [PATCH] qemu: validate virtiofs filesystems
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Reject unsupported configurations.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+(cherry picked from commit efaf46811c909ee5333360fba1d75ae82352964a)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <1fcb6b7d58c3791799c5d436edaa2faa07e92305.1583322091.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_domain.c | 82 +++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 77 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 402b079b09..79d8de2e42 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -8329,11 +8329,52 @@ qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu,
+     return 0;
+ }
+ 
++static int
++qemuDomainDefValidateVirtioFSSharedMemory(const virDomainDef *def)
++{
++    size_t numa_nodes = virDomainNumaGetNodeCount(def->numa);
++    size_t i;
++
++    if (numa_nodes == 0) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                       _("virtiofs requires one or more NUMA nodes"));
++        return -1;
++    }
++
++    for (i = 0; i < numa_nodes; i++) {
++        virDomainMemoryAccess node_access =
++            virDomainNumaGetNodeMemoryAccessMode(def->numa, i);
++
++        switch (node_access) {
++        case VIR_DOMAIN_MEMORY_ACCESS_DEFAULT:
++            if (def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_SHARED) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                               _("virtiofs requires shared memory"));
++                return -1;
++            }
++            break;
++        case VIR_DOMAIN_MEMORY_ACCESS_SHARED:
++            break;
++        case VIR_DOMAIN_MEMORY_ACCESS_PRIVATE:
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("virtiofs requires shared memory"));
++            return -1;
++
++        case VIR_DOMAIN_MEMORY_ACCESS_LAST:
++        default:
++            virReportEnumRangeError(virDomainMemoryAccess, node_access);
++            return -1;
++
++        }
++    }
++    return 0;
++}
+ 
+ static int
+ qemuDomainDeviceDefValidateFS(virDomainFSDefPtr fs,
+-                              const virDomainDef *def G_GNUC_UNUSED,
+-                              virQEMUCapsPtr qemuCaps G_GNUC_UNUSED)
++                              const virDomainDef *def,
++                              virQEMUDriverPtr driver,
++                              virQEMUCapsPtr qemuCaps)
+ {
+     if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+@@ -8362,8 +8403,39 @@ qemuDomainDeviceDefValidateFS(virDomainFSDefPtr fs,
+         return -1;
+ 
+     case VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS:
+-        /* TODO: vhost-user-fs-pci */
+-        return 0;
++        if (!virQEMUDriverIsPrivileged(driver)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("virtiofs is not yet supported in session mode"));
++            return -1;
++        }
++        if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("virtiofs only supports passthrough accessmode"));
++            return -1;
++        }
++        if (fs->wrpolicy != VIR_DOMAIN_FS_WRPOLICY_DEFAULT) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("virtiofs does not support wrpolicy"));
++            return -1;
++        }
++        if (fs->model != VIR_DOMAIN_FS_MODEL_DEFAULT) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("virtiofs does not support model"));
++            return -1;
++        }
++        if (fs->format != VIR_STORAGE_FILE_NONE) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("virtiofs does not support format"));
++            return -1;
++        }
++        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_USER_FS)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("virtiofs is not supported with this QEMU binary"));
++            return -1;
++        }
++        if (qemuDomainDefValidateVirtioFSSharedMemory(def) < 0)
++            return -1;
++        break;
+ 
+     case VIR_DOMAIN_FS_DRIVER_TYPE_LAST:
+     default:
+@@ -8542,7 +8614,7 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
+         break;
+ 
+     case VIR_DOMAIN_DEVICE_FS:
+-        ret = qemuDomainDeviceDefValidateFS(dev->data.fs, def, qemuCaps);
++        ret = qemuDomainDeviceDefValidateFS(dev->data.fs, def, driver, qemuCaps);
+         break;
+ 
+     case VIR_DOMAIN_DEVICE_NVRAM:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemu-virtiofs-shorten-pid-filename.patch b/SOURCES/libvirt-qemu-virtiofs-shorten-pid-filename.patch
new file mode 100644
index 0000000..357d4f9
--- /dev/null
+++ b/SOURCES/libvirt-qemu-virtiofs-shorten-pid-filename.patch
@@ -0,0 +1,49 @@
+From aa95c0fea0aa938873717ccb91319b2c3e48d000 Mon Sep 17 00:00:00 2001
+Message-Id: <aa95c0fea0aa938873717ccb91319b2c3e48d000@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 24 Mar 2020 11:30:17 +0100
+Subject: [PATCH] qemu: virtiofs: shorten pid filename
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There is no need to repeat the shortName, since it's
+already present in the directory path.
+
+Also use just 'fs' instead of 'virtiofsd'.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1816577
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Suggested-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 7055af6c2253666cd0b7c4c459c5a019da789140)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <619956878ec3e09fe6481c7e25b2820753aa57e5.1585045801.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_virtiofs.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_virtiofs.c b/src/qemu/qemu_virtiofs.c
+index d579ce1d33..b47e19a562 100644
+--- a/src/qemu/qemu_virtiofs.c
++++ b/src/qemu/qemu_virtiofs.c
+@@ -42,13 +42,9 @@ qemuVirtioFSCreatePidFilename(virDomainObjPtr vm,
+                               const char *alias)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+-    g_autofree char *shortName = NULL;
+     g_autofree char *name = NULL;
+ 
+-    if (!(shortName = virDomainDefGetShortName(vm->def)))
+-        return NULL;
+-
+-    name = g_strdup_printf("%s-%s-virtiofsd", shortName, alias);
++    name = g_strdup_printf("%s-fs", alias);
+ 
+     return virPidFileBuildPath(priv->libDir, name);
+ }
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemu-virtiofs-shorten-socket-filename.patch b/SOURCES/libvirt-qemu-virtiofs-shorten-socket-filename.patch
new file mode 100644
index 0000000..66e1e52
--- /dev/null
+++ b/SOURCES/libvirt-qemu-virtiofs-shorten-socket-filename.patch
@@ -0,0 +1,39 @@
+From 33bca0809e436c0040aa17d546c2145e5432b023 Mon Sep 17 00:00:00 2001
+Message-Id: <33bca0809e436c0040aa17d546c2145e5432b023@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 24 Mar 2020 11:30:18 +0100
+Subject: [PATCH] qemu: virtiofs: shorten socket filename
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use just 'fs' instead of 'virtiofsd'.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1816577
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 223b370aaa6fcbcbfbd4045fde4ae67e047180ad)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <ecf76c8829f804dcdb83eeb90f236316a240795e.1585045801.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_virtiofs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_virtiofs.c b/src/qemu/qemu_virtiofs.c
+index b47e19a562..d9ace4aafe 100644
+--- a/src/qemu/qemu_virtiofs.c
++++ b/src/qemu/qemu_virtiofs.c
+@@ -56,7 +56,7 @@ qemuVirtioFSCreateSocketFilename(virDomainObjPtr vm,
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+ 
+-    return virFileBuildPath(priv->libDir, alias, "-virtiofsd.sock");
++    return virFileBuildPath(priv->libDir, alias, "-fs.sock");
+ }
+ 
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuAgentFSInfoFormatParams-Remove-pointless-returned-value.patch b/SOURCES/libvirt-qemuAgentFSInfoFormatParams-Remove-pointless-returned-value.patch
new file mode 100644
index 0000000..d811826
--- /dev/null
+++ b/SOURCES/libvirt-qemuAgentFSInfoFormatParams-Remove-pointless-returned-value.patch
@@ -0,0 +1,137 @@
+From d5bc155a97d1938e0e19f6040ae76cdd0a92ed62 Mon Sep 17 00:00:00 2001
+Message-Id: <d5bc155a97d1938e0e19f6040ae76cdd0a92ed62@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:34 +0100
+Subject: [PATCH] qemuAgentFSInfoFormatParams: Remove pointless returned value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The only caller doesn't check the value and also there are no real
+errors to report anyways.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit da1b1932271ee135537b2809e87dc621748d4630)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1812965
+Message-Id: <04feacc921ce5c6f0333a4c4af7ccef8b22db6a1.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 31 ++++++++++++-------------------
+ 1 file changed, 12 insertions(+), 19 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 26f100177b..8c7e90531a 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -22996,24 +22996,20 @@ qemuDomainGetGuestInfoCheckSupport(unsigned int *types)
+     *types = *types & supportedGuestInfoTypes;
+ }
+ 
+-/* Returns: 0 on success
+- *          -1 otherwise
+- */
+-static int
++static void
+ qemuAgentFSInfoFormatParams(qemuAgentFSInfoPtr *fsinfo,
+                             int nfs,
+                             virDomainDefPtr vmdef,
+                             virTypedParameterPtr *params,
+                             int *nparams, int *maxparams)
+ {
+-    int ret = -1;
+     size_t i, j;
+ 
+     /* FIXME: get disk target */
+ 
+     if (virTypedParamsAddUInt(params, nparams, maxparams,
+                               "fs.count", nfs) < 0)
+-        goto cleanup;
++        return;
+ 
+     for (i = 0; i < nfs; i++) {
+         char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
+@@ -23021,17 +23017,17 @@ qemuAgentFSInfoFormatParams(qemuAgentFSInfoPtr *fsinfo,
+                    "fs.%zu.name", i);
+         if (virTypedParamsAddString(params, nparams, maxparams,
+                                     param_name, fsinfo[i]->name) < 0)
+-            goto cleanup;
++            return;
+         g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                    "fs.%zu.mountpoint", i);
+         if (virTypedParamsAddString(params, nparams, maxparams,
+                                     param_name, fsinfo[i]->mountpoint) < 0)
+-            goto cleanup;
++            return;
+         g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                    "fs.%zu.fstype", i);
+         if (virTypedParamsAddString(params, nparams, maxparams,
+                                     param_name, fsinfo[i]->fstype) < 0)
+-            goto cleanup;
++            return;
+ 
+         /* disk usage values are not returned by older guest agents, so
+          * only add the params if the value is set */
+@@ -23040,20 +23036,20 @@ qemuAgentFSInfoFormatParams(qemuAgentFSInfoPtr *fsinfo,
+         if (fsinfo[i]->total_bytes != -1 &&
+             virTypedParamsAddULLong(params, nparams, maxparams,
+                                     param_name, fsinfo[i]->total_bytes) < 0)
+-            goto cleanup;
++            return;
+ 
+         g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                    "fs.%zu.used-bytes", i);
+         if (fsinfo[i]->used_bytes != -1 &&
+             virTypedParamsAddULLong(params, nparams, maxparams,
+                                     param_name, fsinfo[i]->used_bytes) < 0)
+-            goto cleanup;
++            return;
+ 
+         g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                    "fs.%zu.disk.count", i);
+         if (virTypedParamsAddUInt(params, nparams, maxparams,
+                                   param_name, fsinfo[i]->ndisks) < 0)
+-            goto cleanup;
++            return;
+         for (j = 0; j < fsinfo[i]->ndisks; j++) {
+             virDomainDiskDefPtr diskdef = NULL;
+             qemuAgentDiskInfoPtr d = fsinfo[i]->disks[j];
+@@ -23069,7 +23065,7 @@ qemuAgentFSInfoFormatParams(qemuAgentFSInfoPtr *fsinfo,
+                 if (diskdef->dst &&
+                     virTypedParamsAddString(params, nparams, maxparams,
+                                             param_name, diskdef->dst) < 0)
+-                    goto cleanup;
++                    return;
+             }
+ 
+             g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+@@ -23077,22 +23073,19 @@ qemuAgentFSInfoFormatParams(qemuAgentFSInfoPtr *fsinfo,
+             if (d->serial &&
+                 virTypedParamsAddString(params, nparams, maxparams,
+                                         param_name, d->serial) < 0)
+-                goto cleanup;
++                return;
+ 
+             g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
+                        "fs.%zu.disk.%zu.device", i, j);
+             if (d->devnode &&
+                 virTypedParamsAddString(params, nparams, maxparams,
+                                         param_name, d->devnode) < 0)
+-                goto cleanup;
++                return;
+         }
+     }
+-    ret = nfs;
+-
+- cleanup:
+-    return ret;
+ }
+ 
++
+ static int
+ qemuDomainGetGuestInfo(virDomainPtr dom,
+                        unsigned int types,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuBackupBegin-Fix-monitor-access-when-rolling-back-due-to-failure.patch b/SOURCES/libvirt-qemuBackupBegin-Fix-monitor-access-when-rolling-back-due-to-failure.patch
new file mode 100644
index 0000000..8be9606
--- /dev/null
+++ b/SOURCES/libvirt-qemuBackupBegin-Fix-monitor-access-when-rolling-back-due-to-failure.patch
@@ -0,0 +1,43 @@
+From 54b47c1f5bf860e2fadeb17a954a109aafd62067 Mon Sep 17 00:00:00 2001
+Message-Id: <54b47c1f5bf860e2fadeb17a954a109aafd62067@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 26 Mar 2020 18:25:12 +0100
+Subject: [PATCH] qemuBackupBegin: Fix monitor access when rolling back due to
+ failure
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The code attempting to clean up after a failed pull mode backup job
+wrongly entered monitor but didn't clean up nor exit monitor due to a
+logic bug. Fix the condition.
+
+Introduced in a1521f84a53
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1817327
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit e060b0624d1b78438b759cc5a25da87b28c9736c)
+Message-Id: <95ad49e5316e5f9dd992e463bc7536e3046140d4.1585243469.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_backup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
+index 8b66ee8d1f..9a056fa407 100644
+--- a/src/qemu/qemu_backup.c
++++ b/src/qemu/qemu_backup.c
+@@ -894,7 +894,7 @@ qemuBackupBegin(virDomainObjPtr vm,
+     qemuCheckpointRollbackMetadata(vm, chk);
+ 
+     if (!job_started && nbd_running &&
+-        qemuDomainObjEnterMonitorAsync(priv->driver, vm, QEMU_ASYNC_JOB_BACKUP) < 0) {
++        qemuDomainObjEnterMonitorAsync(priv->driver, vm, QEMU_ASYNC_JOB_BACKUP) == 0) {
+         ignore_value(qemuMonitorNBDServerStop(priv->mon));
+         ignore_value(qemuDomainObjExitMonitor(priv->driver, vm));
+     }
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuBlockBitmapsHandleCommitFinish-Use-proper-variable-to-iterate.patch b/SOURCES/libvirt-qemuBlockBitmapsHandleCommitFinish-Use-proper-variable-to-iterate.patch
new file mode 100644
index 0000000..7b828d8
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockBitmapsHandleCommitFinish-Use-proper-variable-to-iterate.patch
@@ -0,0 +1,42 @@
+From 60d5a8463c380b005f16698bca7b38c11b122e03 Mon Sep 17 00:00:00 2001
+Message-Id: <60d5a8463c380b005f16698bca7b38c11b122e03@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 17 Mar 2020 17:12:45 +0100
+Subject: [PATCH] qemuBlockBitmapsHandleCommitFinish: Use proper variable to
+ iterate
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The function repeatedly checked the first element rather than iterating
+through the array.
+
+Reported-by: Daniel P. Berrangé <berrange@redhat.com>
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Tested-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 7a16318855811ac4ae55d30b77969528099fd180)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <25addb80a3899e5789c32aecab8184066e80cbd0.1584461519.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index dad3e2317f..73cb5ba4bc 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -3175,7 +3175,7 @@ qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc,
+                     char **disabledbitmaps;
+ 
+                     for (disabledbitmaps = disabledBitmapsBase; *disabledbitmaps; disabledbitmaps++) {
+-                        if (STREQ(*disabledBitmapsBase, bitmap->name)) {
++                        if (STREQ(*disabledbitmaps, bitmap->name)) {
+                             bitmapdata = g_new0(struct qemuBlockBitmapsHandleCommitData, 1);
+ 
+                             bitmapdata->create = false;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuBlockBitmapsHandleCommitStart-Fix-allocation-of-string-list.patch b/SOURCES/libvirt-qemuBlockBitmapsHandleCommitStart-Fix-allocation-of-string-list.patch
new file mode 100644
index 0000000..67416a9
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockBitmapsHandleCommitStart-Fix-allocation-of-string-list.patch
@@ -0,0 +1,41 @@
+From 83452775d46c10e2a33c2727f6c5e1d6e22ebdfe Mon Sep 17 00:00:00 2001
+Message-Id: <83452775d46c10e2a33c2727f6c5e1d6e22ebdfe@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 17 Mar 2020 17:12:44 +0100
+Subject: [PATCH] qemuBlockBitmapsHandleCommitStart: Fix allocation of string
+ list
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allocate space also for the terminating NULL.
+
+Reported-by: Daniel P. Berrangé <berrange@redhat.com>
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Tested-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 061057e75461814e36aad1e78e96363d373ac34b)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <562a7faef6100c757b5556592093382b016755bb.1584461519.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 099ceeb802..dad3e2317f 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -3019,7 +3019,7 @@ qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc,
+     if (!(entry = virHashLookup(blockNamedNodeData, basesrc->nodeformat)))
+         return 0;
+ 
+-    bitmaplist = g_new0(char *, entry->nbitmaps);
++    bitmaplist = g_new0(char *, entry->nbitmaps + 1);
+ 
+     for (i = 0; i < entry->nbitmaps; i++) {
+         qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuBlockGetBackingStoreString-Add-extra-wrapping-object-to-JSON-strings.patch b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Add-extra-wrapping-object-to-JSON-strings.patch
new file mode 100644
index 0000000..5d00325
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Add-extra-wrapping-object-to-JSON-strings.patch
@@ -0,0 +1,129 @@
+From d4877aae453a0ed1104dfd8aa12806a110f08b07 Mon Sep 17 00:00:00 2001
+Message-Id: <d4877aae453a0ed1104dfd8aa12806a110f08b07@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:05 +0100
+Subject: [PATCH] qemuBlockGetBackingStoreString: Add extra wrapping object to
+ JSON strings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QEMU requires an extra wrapper object where only the "file" member is
+populated. This is basically a placeholder for establishing the format
+layer. We did the same in qemuDiskSourceGetProps for the old-school
+JSON usage with -drive but forgot to adopt this for -blockdev.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 7ba2208addf1cad4d6c06d3c172cca93f84ead11)
+Message-Id: <9a56b9f7e03d41bf99399b14f399bc9007ed1a4e.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c                                          | 2 +-
+ .../imagecreate/qcow2-backing-qcow2-slice.json                 | 2 +-
+ .../qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json | 2 +-
+ .../network-qcow2-backing-chain-cache-unsafe-srconly.json      | 3 ++-
+ .../network-qcow2-backing-chain-encryption_auth-srconly.json   | 3 ++-
+ tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json  | 3 ++-
+ 6 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 5a7364576a..73a424f7a8 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2091,7 +2091,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
+     if (!(backingJSON = virJSONValueToString(props, pretty)))
+         return NULL;
+ 
+-    return g_strdup_printf("json:%s", backingJSON);
++    return g_strdup_printf("json:{\"file\":%s}", backingJSON);
+ }
+ 
+ 
+diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json
+index 2fa27c1933..2526740b9a 100644
+--- a/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json
++++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json
+@@ -10,6 +10,6 @@ format:
+   "driver": "qcow2",
+   "file": "0123456789ABCDEF0123456789ABCDE",
+   "size": 8589934590,
+-  "backing-file": "json:{\"driver\":\"raw\",\"offset\":1234,\"size\":5768,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.qcow2\"}}",
++  "backing-file": "json:{\"file\":{\"driver\":\"raw\",\"offset\":1234,\"size\":5768,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.qcow2\"}}}",
+   "backing-fmt": "qcow2"
+ }
+diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json
+index 761002afd9..e76221da16 100644
+--- a/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json
++++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json
+@@ -10,6 +10,6 @@ format:
+   "driver": "qcow2",
+   "file": "0123456789ABCDEF0123456789ABCDE",
+   "size": 8589934590,
+-  "backing-file": "json:{\"driver\":\"raw\",\"offset\":9876,\"size\":54321,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.img\"}}",
++  "backing-file": "json:{\"file\":{\"driver\":\"raw\",\"offset\":9876,\"size\":54321,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.img\"}}}",
+   "backing-fmt": "raw"
+ }
+diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json
+index 2d7eeb3bca..0fb0b8eff9 100644
+--- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json
++++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json
+@@ -16,7 +16,7 @@
+     ]
+   }
+   backing store string:
+-  json:{
++  json:{"file":{
+     "driver": "rbd",
+     "pool": "rbdpool",
+     "image": "rbdimg",
+@@ -31,6 +31,7 @@
+       }
+     ]
+   }
++  }
+ )
+ (
+   source only properties:
+diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json
+index 5679318fbe..777a372471 100644
+--- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json
++++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json
+@@ -16,7 +16,7 @@
+     ]
+   }
+   backing store string:
+-  json:{
++  json:{"file":{
+     "driver": "rbd",
+     "pool": "rbdpool",
+     "image": "rbdimg",
+@@ -31,6 +31,7 @@
+       }
+     ]
+   }
++  }
+ )
+ (
+   source only properties:
+diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
+index 970e1bb8af..26f9557c80 100644
+--- a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
+@@ -6,9 +6,10 @@
+     "namespace": 1
+   }
+   backing store string:
+-  json:{
++  json:{"file":{
+     "driver": "nvme",
+     "device": "0000:01:00.0",
+     "namespace": 1
+   }
++  }
+ )
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuBlockGetBackingStoreString-Add-pretty-argument.patch b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Add-pretty-argument.patch
new file mode 100644
index 0000000..8ac3fe8
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Add-pretty-argument.patch
@@ -0,0 +1,103 @@
+From 47842f81b667134e873f4380dfb432ca86a1e50d Mon Sep 17 00:00:00 2001
+Message-Id: <47842f81b667134e873f4380dfb432ca86a1e50d@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:00 +0100
+Subject: [PATCH] qemuBlockGetBackingStoreString: Add 'pretty' argument
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for pretty-printing of the JSON variant of the output for
+consumption in tests. All current callers pass 'false'.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit a83c1dc70e724b9313436c63f57ea24023fd7076)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <9b133a1d7bf6304e0dc9017222bdc09640c11518.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c  | 8 +++++---
+ src/qemu/qemu_block.h  | 3 ++-
+ src/qemu/qemu_driver.c | 4 ++--
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 5697d4fc73..279b4a38b8 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2014,13 +2014,15 @@ qemuBlockStorageGetCopyOnReadProps(virDomainDiskDefPtr disk)
+ /**
+  * qemuBlockGetBackingStoreString:
+  * @src: storage source to get the string for
++ * @pretty: pretty-print the JSON (if applicable, used by tests)
+  *
+  * Formats a string used in the backing store field of a disk image which
+  * supports backing store. Non-local storage may result in use of the json:
+  * pseudo protocol for any complex configuration.
+  */
+ char *
+-qemuBlockGetBackingStoreString(virStorageSourcePtr src)
++qemuBlockGetBackingStoreString(virStorageSourcePtr src,
++                               bool pretty)
+ {
+     int actualType = virStorageSourceGetActualType(src);
+     g_autoptr(virJSONValue) backingProps = NULL;
+@@ -2087,7 +2089,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src)
+         props = sliceProps;
+     }
+ 
+-    if (!(backingJSON = virJSONValueToString(props, false)))
++    if (!(backingJSON = virJSONValueToString(props, pretty)))
+         return NULL;
+ 
+     ret = g_strdup_printf("json:%s", backingJSON);
+@@ -2115,7 +2117,7 @@ qemuBlockStorageSourceCreateAddBacking(virStorageSourcePtr backing,
+             backingFormatStr = virStorageFileFormatTypeToString(backing->format);
+     }
+ 
+-    if (!(backingFileStr = qemuBlockGetBackingStoreString(backing)))
++    if (!(backingFileStr = qemuBlockGetBackingStoreString(backing, false)))
+         return -1;
+ 
+     if (virJSONValueObjectAdd(props,
+diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
+index 75b25bfea5..506957c3d5 100644
+--- a/src/qemu/qemu_block.h
++++ b/src/qemu/qemu_block.h
+@@ -178,7 +178,8 @@ qemuBlockSnapshotAddBlockdev(virJSONValuePtr actions,
+                              virStorageSourcePtr newsrc);
+ 
+ char *
+-qemuBlockGetBackingStoreString(virStorageSourcePtr src)
++qemuBlockGetBackingStoreString(virStorageSourcePtr src,
++                               bool pretty)
+     ATTRIBUTE_NONNULL(1);
+ 
+ int
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 175a1961c2..3c3c7b6041 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17773,7 +17773,7 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm,
+         if (baseSource) {
+             nodebase = baseSource->nodeformat;
+             if (!backingPath &&
+-                !(backingPath = qemuBlockGetBackingStoreString(baseSource)))
++                !(backingPath = qemuBlockGetBackingStoreString(baseSource, false)))
+                 goto endjob;
+         }
+         device = disk->src->nodeformat;
+@@ -18941,7 +18941,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
+         nodebase = baseSource->nodeformat;
+         device = qemuDomainDiskGetTopNodename(disk);
+         if (!backingPath && top_parent &&
+-            !(backingPath = qemuBlockGetBackingStoreString(baseSource)))
++            !(backingPath = qemuBlockGetBackingStoreString(baseSource, false)))
+             goto endjob;
+ 
+         if (bitmapDisableActions) {
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuBlockGetBackingStoreString-Properly-handle-http-s-with-cookies-and-others.patch b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Properly-handle-http-s-with-cookies-and-others.patch
new file mode 100644
index 0000000..0cbae72
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Properly-handle-http-s-with-cookies-and-others.patch
@@ -0,0 +1,226 @@
+From 282f6724e64787451e69dd0f261c7239fa0e79ac Mon Sep 17 00:00:00 2001
+Message-Id: <282f6724e64787451e69dd0f261c7239fa0e79ac@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:07 +0100
+Subject: [PATCH] qemuBlockGetBackingStoreString: Properly handle 'http/s' with
+ cookies and others
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Format cookies into the backing store string without encryption as they
+will not be visible on the command line when formatting a 'target' only
+string. In cases when cookies or other options are used we must use the
+JSON format rather than pure URI.
+
+Add tests to validate the scenario.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 3b06103e695829c4720baaee8286f20568133ebd)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <aea5c926b86d5dad7dc78f30f2f0e8d95807e58e.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c                         | 12 ++++++++++-
+ tests/qemublocktest.c                         |  2 ++
+ .../network-http-curlopts-srconly.json        | 17 ++++++++++++++++
+ .../xml2json/network-http-curlopts.json       | 15 ++++++++++++++
+ .../xml2json/network-http-curlopts.xml        | 20 +++++++++++++++++++
+ .../xml2json/network-http-noopts-srconly.json |  9 +++++++++
+ .../xml2json/network-http-noopts.json         | 14 +++++++++++++
+ .../xml2json/network-http-noopts.xml          | 15 ++++++++++++++
+ 8 files changed, 103 insertions(+), 1 deletion(-)
+ create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json
+ create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts.json
+ create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts.xml
+ create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json
+ create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts.json
+ create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts.xml
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 1f48f559e3..ba7318b074 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -685,6 +685,7 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+     virJSONValuePtr ret = NULL;
+     g_autoptr(virURI) uri = NULL;
+     g_autofree char *uristr = NULL;
++    g_autofree char *cookiestr = NULL;
+ 
+     /**
+      * Common options:
+@@ -714,6 +715,9 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+         if (srcPriv &&
+             srcPriv->httpcookie)
+             cookiealias = srcPriv->httpcookie->s.aes.alias;
++    } else {
++        /* format target string along with cookies */
++        cookiestr = qemuBlockStorageSourceGetCookieString(src);
+     }
+ 
+     ignore_value(virJSONValueObjectCreate(&ret,
+@@ -721,6 +725,7 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src,
+                                           "S:username", username,
+                                           "S:password-secret", passwordalias,
+                                           "T:sslverify", src->sslverify,
++                                          "S:cookie", cookiestr,
+                                           "S:cookie-secret", cookiealias,
+                                           "P:timeout", src->timeout,
+                                           "P:readahead", src->readahead,
+@@ -2043,7 +2048,12 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
+         /* generate simplified URIs for the easy cases */
+         if (actualType == VIR_STORAGE_TYPE_NETWORK &&
+             src->nhosts == 1 &&
+-            src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
++            src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP &&
++            src->timeout == 0 &&
++            src->ncookies == 0 &&
++            src->sslverify == VIR_TRISTATE_BOOL_ABSENT &&
++            src->timeout == 0 &&
++            src->readahead == 0) {
+ 
+             switch ((virStorageNetProtocol) src->protocol) {
+             case VIR_STORAGE_NET_PROTOCOL_NBD:
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index cf56c8a983..8b7a50712d 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1212,6 +1212,8 @@ mymain(void)
+     TEST_DISK_TO_JSON("network-qcow2-backing-chain-cache-unsafe");
+     TEST_DISK_TO_JSON("dir-fat-cache");
+     TEST_DISK_TO_JSON("network-nbd-tls");
++    TEST_DISK_TO_JSON("network-http-noopts");
++    TEST_DISK_TO_JSON("network-http-curlopts");
+ 
+     TEST_DISK_TO_JSON("block-raw-noopts");
+     TEST_DISK_TO_JSON("block-raw-reservations");
+diff --git a/tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json b/tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json
+new file mode 100644
+index 0000000000..f5645ac2a6
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json
+@@ -0,0 +1,17 @@
++(
++  source only properties:
++  {
++    "driver": "https",
++    "url": "https://host1.example.com:443/something",
++    "sslverify": false,
++    "cookie": "test=123456; blurb=here"
++  }
++  backing store string:
++  json:{"file":{
++    "driver": "https",
++    "url": "https://host1.example.com:443/something",
++    "sslverify": false,
++    "cookie": "test=123456; blurb=here"
++  }
++  }
++)
+diff --git a/tests/qemublocktestdata/xml2json/network-http-curlopts.json b/tests/qemublocktestdata/xml2json/network-http-curlopts.json
+new file mode 100644
+index 0000000000..08dfd1b300
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/network-http-curlopts.json
+@@ -0,0 +1,15 @@
++{
++  "node-name": "node-b-f",
++  "read-only": false,
++  "driver": "qcow2",
++  "file": "node-a-s",
++  "backing": null
++}
++{
++  "driver": "https",
++  "url": "https://host1.example.com:443/something",
++  "sslverify": false,
++  "node-name": "node-a-s",
++  "auto-read-only": true,
++  "discard": "unmap"
++}
+diff --git a/tests/qemublocktestdata/xml2json/network-http-curlopts.xml b/tests/qemublocktestdata/xml2json/network-http-curlopts.xml
+new file mode 100644
+index 0000000000..a656247e2e
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/network-http-curlopts.xml
+@@ -0,0 +1,20 @@
++<disk type='network' device='disk'>
++  <driver name='qemu' type='qcow2'/>
++  <source protocol='https' name='/something'>
++    <host name='host1.example.com'/>
++    <ssl verify='no'/>
++    <cookies>
++      <cookie name='test'>123456</cookie>
++      <cookie name='blurb'>here</cookie>
++    </cookies>
++    <privateData>
++      <nodenames>
++        <nodename type='storage' name='node-a-s'/>
++        <nodename type='format' name='node-b-f'/>
++      </nodenames>
++    </privateData>
++  </source>
++  <backingStore/>
++  <target dev='vda' bus='virtio'/>
++  <alias name='virtio-disk0'/>
++</disk>
+diff --git a/tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json b/tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json
+new file mode 100644
+index 0000000000..1303623036
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json
+@@ -0,0 +1,9 @@
++(
++  source only properties:
++  {
++    "driver": "https",
++    "url": "https://host1.example.com:443/something"
++  }
++  backing store string:
++  https://host1.example.com:443/something
++)
+diff --git a/tests/qemublocktestdata/xml2json/network-http-noopts.json b/tests/qemublocktestdata/xml2json/network-http-noopts.json
+new file mode 100644
+index 0000000000..d577858236
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/network-http-noopts.json
+@@ -0,0 +1,14 @@
++{
++  "node-name": "node-b-f",
++  "read-only": false,
++  "driver": "qcow2",
++  "file": "node-a-s",
++  "backing": null
++}
++{
++  "driver": "https",
++  "url": "https://host1.example.com:443/something",
++  "node-name": "node-a-s",
++  "auto-read-only": true,
++  "discard": "unmap"
++}
+diff --git a/tests/qemublocktestdata/xml2json/network-http-noopts.xml b/tests/qemublocktestdata/xml2json/network-http-noopts.xml
+new file mode 100644
+index 0000000000..f09ff7ba67
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/network-http-noopts.xml
+@@ -0,0 +1,15 @@
++<disk type='network' device='disk'>
++  <driver name='qemu' type='qcow2'/>
++  <source protocol='https' name='/something'>
++    <host name='host1.example.com'/>
++    <privateData>
++      <nodenames>
++        <nodename type='storage' name='node-a-s'/>
++        <nodename type='format' name='node-b-f'/>
++      </nodenames>
++    </privateData>
++  </source>
++  <backingStore/>
++  <target dev='vda' bus='virtio'/>
++  <alias name='virtio-disk0'/>
++</disk>
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuBlockGetBackingStoreString-Remove-ret-variable.patch b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Remove-ret-variable.patch
new file mode 100644
index 0000000..5f1d249
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockGetBackingStoreString-Remove-ret-variable.patch
@@ -0,0 +1,67 @@
+From 11ec875ccebe3035bb4b6e38406f22d52ed4b7fe Mon Sep 17 00:00:00 2001
+Message-Id: <11ec875ccebe3035bb4b6e38406f22d52ed4b7fe@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:03 +0100
+Subject: [PATCH] qemuBlockGetBackingStoreString: Remove 'ret' variable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We can return the appropriate string directly.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit c60fe3106e8b91478e54129b4b1b81cc0543399e)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <b3cb9b35035b7e2d3de21de3f067966de5e6765b.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 279b4a38b8..20579ec7b3 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2030,13 +2030,10 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
+     virJSONValuePtr props = NULL;
+     g_autoptr(virURI) uri = NULL;
+     g_autofree char *backingJSON = NULL;
+-    char *ret = NULL;
+ 
+     if (!src->sliceStorage) {
+-        if (virStorageSourceIsLocalStorage(src)) {
+-            ret = g_strdup(src->path);
+-            return ret;
+-        }
++        if (virStorageSourceIsLocalStorage(src))
++            return g_strdup(src->path);
+ 
+         /* generate simplified URIs for the easy cases */
+         if (actualType == VIR_STORAGE_TYPE_NETWORK &&
+@@ -2055,10 +2052,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
+                 if (!(uri = qemuBlockStorageSourceGetURI(src)))
+                     return NULL;
+ 
+-                if (!(ret = virURIFormat(uri)))
+-                    return NULL;
+-
+-                return ret;
++                return virURIFormat(uri);
+ 
+             case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
+             case VIR_STORAGE_NET_PROTOCOL_RBD:
+@@ -2092,9 +2086,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
+     if (!(backingJSON = virJSONValueToString(props, pretty)))
+         return NULL;
+ 
+-    ret = g_strdup_printf("json:%s", backingJSON);
+-
+-    return ret;
++    return g_strdup_printf("json:%s", backingJSON);
+ }
+ 
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuBlockJobDiskNewCommit-Propagate-disabledBitmapsBase.patch b/SOURCES/libvirt-qemuBlockJobDiskNewCommit-Propagate-disabledBitmapsBase.patch
new file mode 100644
index 0000000..551a140
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockJobDiskNewCommit-Propagate-disabledBitmapsBase.patch
@@ -0,0 +1,72 @@
+From 7943ddf8cee3ffa4ca2b2bfe3b440da344aebdd8 Mon Sep 17 00:00:00 2001
+Message-Id: <7943ddf8cee3ffa4ca2b2bfe3b440da344aebdd8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:28 +0100
+Subject: [PATCH] qemuBlockJobDiskNewCommit: Propagate 'disabledBitmapsBase'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add an argument to qemuBlockJobDiskNewCommit to propagate the list of
+disabled bitmaps into the job data structure.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit a2bf4a13acf55864ddb11261cbaade4aedd28b9f)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <312a928fcee253b6a2657a2f30a6a0aa6d51cae9.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_blockjob.c | 2 ++
+ src/qemu/qemu_blockjob.h | 1 +
+ src/qemu/qemu_driver.c   | 2 +-
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index e894e1634d..63f1cc79c3 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -285,6 +285,7 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm,
+                           virStorageSourcePtr topparent,
+                           virStorageSourcePtr top,
+                           virStorageSourcePtr base,
++                          char ***disabledBitmapsBase,
+                           bool delete_imgs,
+                           unsigned int jobflags)
+ {
+@@ -310,6 +311,7 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm,
+     job->data.commit.top = top;
+     job->data.commit.base = base;
+     job->data.commit.deleteCommittedImages = delete_imgs;
++    job->data.commit.disabledBitmapsBase = g_steal_pointer(disabledBitmapsBase);
+     job->jobflags = jobflags;
+ 
+     if (qemuBlockJobRegister(job, vm, disk, true) < 0)
+diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
+index c1d95ea3d8..ee83d318f3 100644
+--- a/src/qemu/qemu_blockjob.h
++++ b/src/qemu/qemu_blockjob.h
+@@ -187,6 +187,7 @@ qemuBlockJobDiskNewCommit(virDomainObjPtr vm,
+                           virStorageSourcePtr topparent,
+                           virStorageSourcePtr top,
+                           virStorageSourcePtr base,
++                          char ***disabledBitmapsBase,
+                           bool delete_imgs,
+                           unsigned int jobflags);
+ 
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 062e028b28..5c2b3cddf1 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -18881,7 +18881,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
+     }
+ 
+     if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
+-                                          baseSource,
++                                          baseSource, NULL,
+                                           flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
+                                           flags)))
+         goto endjob;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuBlockStorageSourceDetachPrepare-Get-rid-of-cleanup-section.patch b/SOURCES/libvirt-qemuBlockStorageSourceDetachPrepare-Get-rid-of-cleanup-section.patch
new file mode 100644
index 0000000..141bba5
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockStorageSourceDetachPrepare-Get-rid-of-cleanup-section.patch
@@ -0,0 +1,55 @@
+From f6f1f6ccc4ade458c159e45d51d627bcde61b303 Mon Sep 17 00:00:00 2001
+Message-Id: <f6f1f6ccc4ade458c159e45d51d627bcde61b303@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:40 +0100
+Subject: [PATCH] qemuBlockStorageSourceDetachPrepare: Get rid of cleanup
+ section
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use g_new0 to completely avoid the 'cleanup' label.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4415b11d6b68643b93014d0e505cb23c5ce63bf0)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <378b5200c9dbf740d695333b367b4a2d24746049.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 5bd5c955a4..5144cf266f 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1734,10 +1734,8 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
+ {
+     qemuDomainStorageSourcePrivatePtr srcpriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
+     g_autoptr(qemuBlockStorageSourceAttachData) data = NULL;
+-    qemuBlockStorageSourceAttachDataPtr ret = NULL;
+ 
+-    if (VIR_ALLOC(data) < 0)
+-        goto cleanup;
++    data = g_new0(qemuBlockStorageSourceAttachData, 1);
+ 
+     if (driveAlias) {
+         data->driveAlias = g_steal_pointer(&driveAlias);
+@@ -1771,11 +1769,7 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
+             data->encryptsecretAlias = g_strdup(srcpriv->encinfo->s.aes.alias);
+     }
+ 
+-    ret = g_steal_pointer(&data);
+-
+- cleanup:
+-    VIR_FREE(driveAlias);
+-    return ret;
++    return g_steal_pointer(&data);
+ }
+ 
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuBlockStorageSourceGetBackendProps-Report-errors-on-all-switch-cases.patch b/SOURCES/libvirt-qemuBlockStorageSourceGetBackendProps-Report-errors-on-all-switch-cases.patch
new file mode 100644
index 0000000..a34a367
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockStorageSourceGetBackendProps-Report-errors-on-all-switch-cases.patch
@@ -0,0 +1,65 @@
+From d08dae3e94778cf5860b6bd7b34bfbdc4741464c Mon Sep 17 00:00:00 2001
+Message-Id: <d08dae3e94778cf5860b6bd7b34bfbdc4741464c@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:52 +0100
+Subject: [PATCH] qemuBlockStorageSourceGetBackendProps: Report errors on all
+ switch cases
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Few switch cases returned failure but didn't report an error. For a
+situation when the backingStore type='volume' was not translated the
+following error would occur:
+
+ $ virsh start VM
+ error: Failed to start domain VM
+ error: An error occurred, but the cause is unknown
+
+After this patch:
+
+ $ virsh start VM
+ error: Failed to start domain VM
+ error: internal error: storage source pool 'tmp' volume 'pull3.qcow2' is not translated
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4e3e69fed45ac58bf19ebbe910213cb552d51f01)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <43cca40afafd5de0aad1f477d63b21d1b10ba796.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 63116ef5f2..0ee10dd770 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1081,8 +1081,14 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
+         break;
+ 
+     case VIR_STORAGE_TYPE_VOLUME:
++        virReportError(VIR_ERR_INTERNAL_ERROR,
++                       _("storage source pool '%s' volume '%s' is not translated"),
++                       src->srcpool->pool, src->srcpool->volume);
++        return NULL;
++
+     case VIR_STORAGE_TYPE_NONE:
+     case VIR_STORAGE_TYPE_LAST:
++        virReportEnumRangeError(virStorageType, actualType);
+         return NULL;
+ 
+     case VIR_STORAGE_TYPE_NETWORK:
+@@ -1141,6 +1147,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
+ 
+         case VIR_STORAGE_NET_PROTOCOL_NONE:
+         case VIR_STORAGE_NET_PROTOCOL_LAST:
++            virReportEnumRangeError(virStorageNetProtocol, src->protocol);
+             return NULL;
+         }
+         break;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuBlockStorageSourceGetFormatRawProps-format-offset-and-size-for-slice.patch b/SOURCES/libvirt-qemuBlockStorageSourceGetFormatRawProps-format-offset-and-size-for-slice.patch
new file mode 100644
index 0000000..70bec7d
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockStorageSourceGetFormatRawProps-format-offset-and-size-for-slice.patch
@@ -0,0 +1,58 @@
+From 23fcd1d6a87e0fcbffc8d4ddfa9cf2b7a226cdd5 Mon Sep 17 00:00:00 2001
+Message-Id: <23fcd1d6a87e0fcbffc8d4ddfa9cf2b7a226cdd5@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:16 +0100
+Subject: [PATCH] qemuBlockStorageSourceGetFormatRawProps: format 'offset' and
+ 'size' for slice
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If we have a 'format' type slice for a raw driver we can directly format
+the values.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit c4818812831967b8f882b2c33780aab129e245a2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <beee894a1f4af469391cee6a42a3e95e8946df98.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 710ddfd2cf..b408d4c81f 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1194,16 +1194,21 @@ qemuBlockStorageSourceGetFormatRawProps(virStorageSourcePtr src,
+         secretalias = srcPriv->encinfo->s.aes.alias;
+     }
+ 
+-    /* currently unhandled properties for the 'raw' driver:
+-     * 'offset'
+-     * 'size'
+-     */
+-
+     if (virJSONValueObjectAdd(props,
+                               "s:driver", driver,
+                               "S:key-secret", secretalias, NULL) < 0)
+         return -1;
+ 
++    /* Currently only storage slices are supported. We'll have to calculate
++     * the union of the slices here if we don't want to be adding needless
++     * 'raw' nodes. */
++    if (src->sliceStorage &&
++        virJSONValueObjectAdd(props,
++                              "U:offset", src->sliceStorage->offset,
++                              "U:size", src->sliceStorage->size,
++                              NULL) < 0)
++        return -1;
++
+     return 0;
+ }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuBlockStorageSourceGetURI-Pass-through-query-component.patch b/SOURCES/libvirt-qemuBlockStorageSourceGetURI-Pass-through-query-component.patch
new file mode 100644
index 0000000..259f558
--- /dev/null
+++ b/SOURCES/libvirt-qemuBlockStorageSourceGetURI-Pass-through-query-component.patch
@@ -0,0 +1,136 @@
+From 2d27c71da092e9232c2d79738a431c04db649a96 Mon Sep 17 00:00:00 2001
+Message-Id: <2d27c71da092e9232c2d79738a431c04db649a96@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:46 +0200
+Subject: [PATCH] qemuBlockStorageSourceGetURI: Pass through query component
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If the storage source has the query part set, format it in the output.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 216860dd8b93c7da4d625055cf353e0eedda6093)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <832f573fd69341b7d730925c9df5b23e5f168408.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_block.c                                    | 2 ++
+ src/qemu/qemu_domain.c                                   | 9 +++++++++
+ tests/qemuxml2argvdata/disk-cdrom-network.args           | 4 ++--
+ .../disk-cdrom-network.x86_64-2.12.0.args                | 4 ++--
+ .../disk-cdrom-network.x86_64-latest.args                | 3 ++-
+ tests/qemuxml2argvdata/disk-cdrom-network.xml            | 2 +-
+ .../disk-network-http.x86_64-latest.args                 | 5 +++--
+ 7 files changed, 21 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index e7577c1312..6790f05ff7 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -437,6 +437,8 @@ qemuBlockStorageSourceGetURI(virStorageSourcePtr src)
+         }
+     }
+ 
++    uri->query = g_strdup(src->query);
++
+     uri->server = g_strdup(src->hosts->name);
+ 
+     return g_steal_pointer(&uri);
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 4007b4dbda..bb28716ff0 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -7107,6 +7107,15 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src,
+         }
+     }
+ 
++    if (src->query &&
++        (actualType != VIR_STORAGE_TYPE_NETWORK ||
++         (src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&
++          src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP))) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                       _("query is supported only with HTTP(S) protocols"));
++        return -1;
++    }
++
+     return 0;
+ }
+ 
+diff --git a/tests/qemuxml2argvdata/disk-cdrom-network.args b/tests/qemuxml2argvdata/disk-cdrom-network.args
+index be19bad68a..81ff324a0f 100644
+--- a/tests/qemuxml2argvdata/disk-cdrom-network.args
++++ b/tests/qemuxml2argvdata/disk-cdrom-network.args
+@@ -30,8 +30,8 @@ id=drive-ide0-0-0,readonly=on \
+ -drive file=ftps://host.name:990/url/path/file.iso,format=raw,if=none,\
+ id=drive-ide0-0-1,readonly=on \
+ -device ide-cd,bus=ide.0,unit=1,drive=drive-ide0-0-1,id=ide0-0-1 \
+--drive file=https://host.name:443/url/path/file.iso,format=raw,if=none,\
+-id=drive-ide0-1-0,readonly=on \
++-drive 'file=https://host.name:443/url/path/file.iso?test=val,format=raw,\
++if=none,id=drive-ide0-1-0,readonly=on' \
+ -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
+ -drive file=tftp://host.name:69/url/path/file.iso,format=raw,if=none,\
+ id=drive-ide0-1-1,readonly=on \
+diff --git a/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-2.12.0.args b/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-2.12.0.args
+index 1ece3d6f46..81f6b400aa 100644
+--- a/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-2.12.0.args
++++ b/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-2.12.0.args
+@@ -32,8 +32,8 @@ id=drive-ide0-0-0,readonly=on \
+ -drive file=ftps://host.name:990/url/path/file.iso,format=raw,if=none,\
+ id=drive-ide0-0-1,readonly=on \
+ -device ide-cd,bus=ide.0,unit=1,drive=drive-ide0-0-1,id=ide0-0-1 \
+--drive file=https://host.name:443/url/path/file.iso,format=raw,if=none,\
+-id=drive-ide0-1-0,readonly=on \
++-drive 'file=https://host.name:443/url/path/file.iso?test=val,format=raw,\
++if=none,id=drive-ide0-1-0,readonly=on' \
+ -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
+ -drive file=tftp://host.name:69/url/path/file.iso,format=raw,if=none,\
+ id=drive-ide0-1-1,readonly=on \
+diff --git a/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-latest.args b/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-latest.args
+index 0b4ac07f07..2515b256d0 100644
+--- a/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-cdrom-network.x86_64-latest.args
+@@ -37,7 +37,8 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -blockdev '{"node-name":"libvirt-3-format","read-only":true,"driver":"raw",\
+ "file":"libvirt-3-storage"}' \
+ -device ide-cd,bus=ide.0,unit=1,drive=libvirt-3-format,id=ide0-0-1 \
+--blockdev '{"driver":"https","url":"https://host.name:443/url/path/file.iso",\
++-blockdev '{"driver":"https",\
++"url":"https://host.name:443/url/path/file.iso?test=val",\
+ "node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-2-format","read-only":true,"driver":"raw",\
+ "file":"libvirt-2-storage"}' \
+diff --git a/tests/qemuxml2argvdata/disk-cdrom-network.xml b/tests/qemuxml2argvdata/disk-cdrom-network.xml
+index 0bdc0e1883..44473f8ad4 100644
+--- a/tests/qemuxml2argvdata/disk-cdrom-network.xml
++++ b/tests/qemuxml2argvdata/disk-cdrom-network.xml
+@@ -39,7 +39,7 @@
+     </disk>
+     <disk type='network' device='cdrom'>
+       <driver name='qemu' type='raw'/>
+-      <source protocol='https' name='/url/path/file.iso'>
++      <source protocol='https' name='/url/path/file.iso' query='test=val'>
+         <host name='host.name' port='443'/>
+       </source>
+       <target dev='hdc' bus='ide'/>
+diff --git a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+index 46aa5f23ce..d1bf0b9caa 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+@@ -54,8 +54,9 @@ id=virtio-disk2 \
+ -object secret,id=libvirt-1-storage-httpcookie-secret0,\
+ data=DrPR9NA6GKJb7qi1KbjHaealKEMVtOWUl2h3yvO5lgIh6cyLHemmlg+h9fcgwREA,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+--blockdev '{"driver":"https","url":"https://example.org:1234/test4.img",\
+-"sslverify":false,"cookie-secret":"libvirt-1-storage-httpcookie-secret0",\
++-blockdev '{"driver":"https",\
++"url":"https://example.org:1234/test4.img?par=val&other=ble","sslverify":false,\
++"cookie-secret":"libvirt-1-storage-httpcookie-secret0",\
+ "node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-1-storage"}' \
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuCheckpointCreateXML-Check-VM-liveness-first.patch b/SOURCES/libvirt-qemuCheckpointCreateXML-Check-VM-liveness-first.patch
new file mode 100644
index 0000000..ec95846
--- /dev/null
+++ b/SOURCES/libvirt-qemuCheckpointCreateXML-Check-VM-liveness-first.patch
@@ -0,0 +1,57 @@
+From 5155fcbbff955e9c1446b3564af2252a5c15548a Mon Sep 17 00:00:00 2001
+Message-Id: <5155fcbbff955e9c1446b3564af2252a5c15548a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 3 Apr 2020 14:32:56 +0200
+Subject: [PATCH] qemuCheckpointCreateXML: Check VM liveness first
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move the liveness check prior to the capability check. If the VM is
+offline the capabilities are not initialized and thus we'd report the
+wrong error.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1812531
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 4257c203737e5ef616588e80794cc705a5fb475a)
+
+Note that this patch is backported as a conflict resolution for the bugs
+below
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1819755
+
+Message-Id: <94fcc1654f3e2fb2d4c1da07347d686180bac532.1585916255.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 19822bd74d..16480518fa 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -649,15 +649,15 @@ qemuCheckpointCreateXML(virDomainPtr domain,
+         update_current = false;
+     }
+ 
+-    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP)) {
++    if (!virDomainObjIsActive(vm)) {
+         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+-                       _("incremental backup is not supported yet"));
++                       _("cannot create checkpoint for inactive domain"));
+         return NULL;
+     }
+ 
+-    if (!virDomainObjIsActive(vm)) {
++    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP)) {
+         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+-                       _("cannot create checkpoint for inactive domain"));
++                       _("incremental backup is not supported yet"));
+         return NULL;
+     }
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuCheckpointDiscardBitmaps-Reopen-images-for-bitmap-modifications.patch b/SOURCES/libvirt-qemuCheckpointDiscardBitmaps-Reopen-images-for-bitmap-modifications.patch
new file mode 100644
index 0000000..a5fc7df
--- /dev/null
+++ b/SOURCES/libvirt-qemuCheckpointDiscardBitmaps-Reopen-images-for-bitmap-modifications.patch
@@ -0,0 +1,54 @@
+From 74ee4616dd3159f4456ec9d4fd22b4604394440b Mon Sep 17 00:00:00 2001
+Message-Id: <74ee4616dd3159f4456ec9d4fd22b4604394440b@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:17 +0100
+Subject: [PATCH] qemuCheckpointDiscardBitmaps: Reopen images for bitmap
+ modifications
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Qemu's bitmap APIs don't reopen the appropriate images read-write for
+modification. It's libvirt's duty to reopen them via blockdev-reopen
+if we wish to modify the bitmaps.
+
+Use the new helpers to reopen the images for bitmap manipulation.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit c6d117528cc0ddb325abd67d69b6d4ebc1bfe608)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <c5378d64ab79d29e62b5b65d1566825b5bc88eff.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index fe54af74ec..6e3a432022 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -302,6 +302,10 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                                                false, false, false) < 0)
+             goto relabel;
+ 
++        if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN) &&
++            qemuBlockReopenReadWrite(vm, src, QEMU_ASYNC_JOB_NONE) < 0)
++            goto relabel;
++
+         relabelimages = g_slist_prepend(relabelimages, src);
+     }
+ 
+@@ -314,6 +318,9 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+     for (next = relabelimages; next; next = next->next) {
+         virStorageSourcePtr src = next->data;
+ 
++        if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
++            ignore_value(qemuBlockReopenReadOnly(vm, src, QEMU_ASYNC_JOB_NONE));
++
+         ignore_value(qemuDomainStorageSourceAccessAllow(driver, vm, src,
+                                                         true, false, false));
+     }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuCheckpointDiscardBitmaps-Use-correct-field-for-checkpoint-bitmap-name.patch b/SOURCES/libvirt-qemuCheckpointDiscardBitmaps-Use-correct-field-for-checkpoint-bitmap-name.patch
new file mode 100644
index 0000000..493690d
--- /dev/null
+++ b/SOURCES/libvirt-qemuCheckpointDiscardBitmaps-Use-correct-field-for-checkpoint-bitmap-name.patch
@@ -0,0 +1,40 @@
+From ec3392c1d5a9886279ee086ee3d421106b9b1e32 Mon Sep 17 00:00:00 2001
+Message-Id: <ec3392c1d5a9886279ee086ee3d421106b9b1e32@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:18 +0100
+Subject: [PATCH] qemuCheckpointDiscardBitmaps: Use correct field for
+ checkpoint bitmap name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The code deleting checkpoints needs the name of the parent checkpoint's
+disk's bitmap but was using the disk alias instead. This would create
+wrong bitmaps after deleting some checkpoints.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 0ce8b0fbe2d0cbaf26da0402270720b776ebfb0f)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <c32db1af44e71870d172233acdfddf050ed73441.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_checkpoint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 6e3a432022..19822bd74d 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -285,7 +285,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+          * ancestor. */
+         if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, parent,
+                                                                   chkdisk->name)))
+-            parentbitmap = parentchkdisk->name;
++            parentbitmap = parentchkdisk->bitmap;
+ 
+         if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData,
+                                              chkdisk->bitmap, parentbitmap,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainBlockCommit-Handle-bitmaps-on-start-of-commit.patch b/SOURCES/libvirt-qemuDomainBlockCommit-Handle-bitmaps-on-start-of-commit.patch
new file mode 100644
index 0000000..d21c343
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockCommit-Handle-bitmaps-on-start-of-commit.patch
@@ -0,0 +1,96 @@
+From e735d0f163806b34f9e65dacdf5e10b52c0478fd Mon Sep 17 00:00:00 2001
+Message-Id: <e735d0f163806b34f9e65dacdf5e10b52c0478fd@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:29 +0100
+Subject: [PATCH] qemuDomainBlockCommit: Handle bitmaps on start of commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+On start of the commit job, we need to disable any active bitmap in the
+base. Use qemuBlockBitmapsHandleCommitStart to calculate which and call
+the appropriate QMP APIs. We use blockdev-reopen to make the 'base'
+writable to disable the bitmaps.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 2b9091f089279a7bac523095a2ccd146fa20800b)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <2aca5706f8412d27ff38da69582c522aca058054.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 43 +++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 42 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 5c2b3cddf1..2f8fee2ef0 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -18724,6 +18724,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
+     const char *nodebase = NULL;
+     bool persistjob = false;
+     bool blockdev = false;
++    g_autoptr(virJSONValue) bitmapDisableActions = NULL;
++    VIR_AUTOSTRINGLIST bitmapDisableList = NULL;
+ 
+     virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW |
+                   VIR_DOMAIN_BLOCK_COMMIT_ACTIVE |
+@@ -18880,8 +18882,29 @@ qemuDomainBlockCommit(virDomainPtr dom,
+             goto endjob;
+     }
+ 
++    if (blockdev &&
++        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) {
++        g_autoptr(virHashTable) blockNamedNodeData = NULL;
++        if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
++            goto endjob;
++
++        if (qemuBlockBitmapsHandleCommitStart(topSource, baseSource,
++                                              blockNamedNodeData,
++                                              &bitmapDisableActions,
++                                              &bitmapDisableList) < 0)
++            goto endjob;
++
++        /* if we don't have terminator on 'base' we can't reopen it */
++        if (bitmapDisableActions && !baseSource->backingStore) {
++            virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
++                           _("can't handle bitmaps on unterminated backing image '%s'"),
++                           base);
++            goto endjob;
++        }
++    }
++
+     if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
+-                                          baseSource, NULL,
++                                          baseSource, &bitmapDisableList,
+                                           flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
+                                           flags)))
+         goto endjob;
+@@ -18903,6 +18926,24 @@ qemuDomainBlockCommit(virDomainPtr dom,
+         if (!backingPath && top_parent &&
+             !(backingPath = qemuBlockGetBackingStoreString(baseSource)))
+             goto endjob;
++
++        if (bitmapDisableActions) {
++            int rc;
++
++            if (qemuBlockReopenReadWrite(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
++                goto endjob;
++
++            qemuDomainObjEnterMonitor(driver, vm);
++            rc = qemuMonitorTransaction(priv->mon, &bitmapDisableActions);
++            if (qemuDomainObjExitMonitor(driver, vm) < 0)
++                goto endjob;
++
++            if (qemuBlockReopenReadOnly(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
++                goto endjob;
++
++            if (rc < 0)
++                goto endjob;
++        }
+     } else {
+         device = job->name;
+     }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainBlockCommit-Move-checks-depending-on-capabilities-after-liveness-check.patch b/SOURCES/libvirt-qemuDomainBlockCommit-Move-checks-depending-on-capabilities-after-liveness-check.patch
new file mode 100644
index 0000000..e377e10
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockCommit-Move-checks-depending-on-capabilities-after-liveness-check.patch
@@ -0,0 +1,70 @@
+From b482f451983e159f3e9752c8d4f2f5d36e6e9dce Mon Sep 17 00:00:00 2001
+Message-Id: <b482f451983e159f3e9752c8d4f2f5d36e6e9dce@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:19 +0100
+Subject: [PATCH] qemuDomainBlockCommit: Move checks depending on capabilities
+ after liveness check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since capabilities are not present for inactive VMs we'd report that we
+don't support '--delete' or committing while checkpoints exist rather
+than the proper error.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit d4b5bb5d56e0ba346a01c605b7316f4394907115)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <74ee257babd3eb042be2fcc5d3a101d503b99ad2.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 441bb02b6b..062e028b28 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -18738,9 +18738,6 @@ qemuDomainBlockCommit(virDomainPtr dom,
+     if (virDomainBlockCommitEnsureACL(dom->conn, vm->def) < 0)
+         goto cleanup;
+ 
+-    if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
+-        goto cleanup;
+-
+     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+         goto cleanup;
+ 
+@@ -18749,12 +18746,6 @@ qemuDomainBlockCommit(virDomainPtr dom,
+ 
+     blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+ 
+-    if (!blockdev && (flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE)) {
+-        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+-                       _("deleting committed images is not supported by this VM"));
+-        goto endjob;
+-    }
+-
+     /* Convert bandwidth MiB to bytes, if necessary */
+     if (!(flags & VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES)) {
+         if (speed > LLONG_MAX >> 20) {
+@@ -18779,6 +18770,15 @@ qemuDomainBlockCommit(virDomainPtr dom,
+     if (qemuDomainDiskBlockJobIsActive(disk))
+         goto endjob;
+ 
++    if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
++        goto endjob;
++
++    if (!blockdev && (flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE)) {
++        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
++                       _("deleting committed images is not supported by this VM"));
++        goto endjob;
++    }
++
+     if (!top || STREQ(top, disk->dst))
+         topSource = disk->src;
+     else if (virStorageFileParseChainIndex(disk->dst, top, &topIndex) < 0 ||
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainBlockCopyCommon-Record-updated-flags-to-block-job.patch b/SOURCES/libvirt-qemuDomainBlockCopyCommon-Record-updated-flags-to-block-job.patch
new file mode 100644
index 0000000..cf6e8b3
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockCopyCommon-Record-updated-flags-to-block-job.patch
@@ -0,0 +1,49 @@
+From 60e014701c6406fd3e1c68a1745e25ffcf918288 Mon Sep 17 00:00:00 2001
+Message-Id: <60e014701c6406fd3e1c68a1745e25ffcf918288@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:37 +0100
+Subject: [PATCH] qemuDomainBlockCopyCommon: Record updated flags to block job
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+For a long time we've masked out VIR_DOMAIN_BLOCK_COPY_SHALLOW if
+there's no backing chain for the copied disk to simplify the code.
+
+One of the refactors of the block copy code caused that we no longer
+update the 'flags' variable just the local copies. This was okay until
+in ccd4228afff we started storing the job flags in the block job data.
+
+Given that we modify how we call qemu we also should modify @flags so
+that the correct value is recorded in the block job data.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit c2b6bc73774f6202e6368ea6823ce9b1cf3521f7)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1803092
+Message-Id: <71dccc8326d856c3d014c6290524a9da4a75e2df.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index bedd69ea2b..5a4e979907 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -18242,8 +18242,10 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
+     }
+ 
+     /* clear the _SHALLOW flag if there is only one layer */
+-    if (!virStorageSourceHasBacking(disk->src))
++    if (!virStorageSourceHasBacking(disk->src)) {
++        flags &= ~VIR_DOMAIN_BLOCK_COPY_SHALLOW;
+         mirror_shallow = false;
++    }
+ 
+     if (qemuDomainBlockCopyCommonValidateUserMirrorBackingStore(mirror,
+                                                                 mirror_shallow,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainBlockPivot-Copy-bitmaps-backing-checkpoints-for-virDomainBlockCopy.patch b/SOURCES/libvirt-qemuDomainBlockPivot-Copy-bitmaps-backing-checkpoints-for-virDomainBlockCopy.patch
new file mode 100644
index 0000000..79b9b89
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockPivot-Copy-bitmaps-backing-checkpoints-for-virDomainBlockCopy.patch
@@ -0,0 +1,84 @@
+From 85658fdaaf7b24f64c31950f4bf710c0dcdafacd Mon Sep 17 00:00:00 2001
+Message-Id: <85658fdaaf7b24f64c31950f4bf710c0dcdafacd@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:27 +0100
+Subject: [PATCH] qemuDomainBlockPivot: Copy bitmaps backing checkpoints for
+ virDomainBlockCopy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use qemuBlockBitmapsHandleBlockcopy to calculate bitmaps to copy over
+for a block-copy job.
+
+We copy them when pivoting to the new image as at that point we are
+certain that we don't dirty any bitmap unnecessarily.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 54030892f5122ef120c1e8ffb6e0546871030272)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <c60a7a567a634836370fc9c0c38317569fa5a22d.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 71c75b25a6..caeb76a20c 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17552,6 +17552,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+     int ret = -1;
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
++    g_autoptr(virJSONValue) actions = NULL;
+ 
+     switch ((qemuBlockJobType) job->type) {
+     case QEMU_BLOCKJOB_TYPE_NONE:
+@@ -17572,6 +17573,20 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+         return -1;
+ 
+     case QEMU_BLOCKJOB_TYPE_COPY:
++        if (blockdev && !job->jobflagsmissing) {
++            g_autoptr(virHashTable) blockNamedNodeData = NULL;
++            bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW;
++
++            if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
++                return -1;
++
++            if (qemuBlockBitmapsHandleBlockcopy(disk->src, disk->mirror,
++                                                blockNamedNodeData,
++                                                shallow, &actions) < 0)
++                return -1;
++        }
++        break;
++
+     case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
+         break;
+     }
+@@ -17584,10 +17599,17 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+     }
+ 
+     qemuDomainObjEnterMonitor(driver, vm);
+-    if (blockdev)
+-        ret = qemuMonitorJobComplete(priv->mon, job->name);
+-    else
++    if (blockdev) {
++        int rc = 0;
++
++        if (actions)
++            rc = qemuMonitorTransaction(priv->mon, &actions);
++
++        if (rc == 0)
++            ret = qemuMonitorJobComplete(priv->mon, job->name);
++    } else {
+         ret = qemuMonitorDrivePivot(priv->mon, job->name);
++    }
+     if (qemuDomainObjExitMonitor(driver, vm) < 0)
+         return -1;
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuDomainBlockPivot-Handle-merging-of-bitmaps-when-pivoting-an-active-block-commit.patch b/SOURCES/libvirt-qemuDomainBlockPivot-Handle-merging-of-bitmaps-when-pivoting-an-active-block-commit.patch
new file mode 100644
index 0000000..6d902d1
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockPivot-Handle-merging-of-bitmaps-when-pivoting-an-active-block-commit.patch
@@ -0,0 +1,61 @@
+From fa5d6a3c048e15f466a5bd2f7cc6de0b106d69a2 Mon Sep 17 00:00:00 2001
+Message-Id: <fa5d6a3c048e15f466a5bd2f7cc6de0b106d69a2@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:30 +0100
+Subject: [PATCH] qemuDomainBlockPivot: Handle merging of bitmaps when pivoting
+ an active block-commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Active layer block commit makes the 'base' image the new top image of
+the disk after it finishes. This means that all bitmap operations need
+to be handled prior to this happening as we'd lose writes otherwise.
+
+The ideal place is to handle it when pivoting to the new image as only
+guest-writes would be happening after this point.
+
+Use qemuBlockBitmapsHandleCommitFinish to calculate the merging
+transaction.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 8502b4b0595ac040f22e1ec8c2ab6375506c14a3)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <7fbaf9f9a8533489334c5b08e6451b23011ab657.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 2f8fee2ef0..05e525e935 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17626,6 +17626,23 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+         break;
+ 
+     case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
++        /* we technically don't need reopen here, but we couldn't prepare
++         * the bitmaps if it wasn't present thus must skip this */
++        if (blockdev &&
++            virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) {
++            g_autoptr(virHashTable) blockNamedNodeData = NULL;
++
++            if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
++                return -1;
++
++            if (qemuBlockBitmapsHandleCommitFinish(job->data.commit.top,
++                                                   job->data.commit.base,
++                                                   blockNamedNodeData,
++                                                   &actions,
++                                                   job->data.commit.disabledBitmapsBase) < 0)
++                return -1;
++        }
++
+         break;
+     }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainBlockPivot-Move-check-prior-to-executing-the-pivot-steps.patch b/SOURCES/libvirt-qemuDomainBlockPivot-Move-check-prior-to-executing-the-pivot-steps.patch
new file mode 100644
index 0000000..946b816
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockPivot-Move-check-prior-to-executing-the-pivot-steps.patch
@@ -0,0 +1,60 @@
+From 5e36101be25d8e80eb14635d9e3eccccaba43550 Mon Sep 17 00:00:00 2001
+Message-Id: <5e36101be25d8e80eb14635d9e3eccccaba43550@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:36 +0100
+Subject: [PATCH] qemuDomainBlockPivot: Move check prior to executing the pivot
+ steps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move the check whether the job is already synchronised to the beginning
+of the function so that we don't try to do some of the steps necessary
+for pivoting prior to actually wanting to pivot.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit a89ba6524c01473f3e5272dc787f01f806df32bb)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1803092
+Message-Id: <17682fad2c82b2f48505b3f8776bb75201eb2d89.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 0bdb2851ec..bedd69ea2b 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17561,6 +17561,13 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+     bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+     g_autoptr(virJSONValue) actions = NULL;
+ 
++    if (job->state != QEMU_BLOCKJOB_STATE_READY) {
++        virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
++                       _("block job '%s' not ready for pivot yet"),
++                       job->name);
++        return -1;
++    }
++
+     switch ((qemuBlockJobType) job->type) {
+     case QEMU_BLOCKJOB_TYPE_NONE:
+     case QEMU_BLOCKJOB_TYPE_LAST:
+@@ -17598,13 +17605,6 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+         break;
+     }
+ 
+-    if (job->state != QEMU_BLOCKJOB_STATE_READY) {
+-        virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
+-                       _("block job '%s' not ready for pivot yet"),
+-                       job->name);
+-        return -1;
+-    }
+-
+     qemuDomainObjEnterMonitor(driver, vm);
+     if (blockdev) {
+         int rc = 0;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainDeviceDiskDefPostParseRestoreSecAlias-Hardcode-restored-aliases.patch b/SOURCES/libvirt-qemuDomainDeviceDiskDefPostParseRestoreSecAlias-Hardcode-restored-aliases.patch
new file mode 100644
index 0000000..7f3cc34
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainDeviceDiskDefPostParseRestoreSecAlias-Hardcode-restored-aliases.patch
@@ -0,0 +1,58 @@
+From 1246cae822ca95a8392463631af1126d915eaf5e Mon Sep 17 00:00:00 2001
+Message-Id: <1246cae822ca95a8392463631af1126d915eaf5e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:51 +0100
+Subject: [PATCH] qemuDomainDeviceDiskDefPostParseRestoreSecAlias: Hardcode
+ restored aliases
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In order to be able to change the function generating the alias and thus
+also the aliases itself, we must hardcode the old format for the case of
+upgrading form libvirt which didn't record them in the status XML yet.
+
+Note that this code path is tested by
+'tests/qemustatusxml2xmldata/disk-secinfo-upgrade-in.xml'
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 95a8c4332dd42ab6a558117a07134a7fdb2ce8f4)
+
+ Conflicts:
+	src/qemu/qemu_domain.c
+        Global cleanups from ae9f630e502 not backported.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <4b880854049d398ffe424b811af69f4b1a074c9d.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 6221e7090f..897e21726a 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -9062,16 +9062,14 @@ qemuDomainDeviceDiskDefPostParseRestoreSecAlias(virDomainDiskDefPtr disk,
+     }
+ 
+     if (restoreAuthSecret) {
+-        if (!(authalias = qemuDomainGetSecretAESAlias(disk->info.alias, false)))
+-            goto cleanup;
++        authalias = g_strdup_printf("%s-secret0", disk->info.alias);
+ 
+         if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->secinfo, &authalias) < 0)
+             goto cleanup;
+     }
+ 
+     if (restoreEncSecret) {
+-        if (!(encalias = qemuDomainGetSecretAESAlias(disk->info.alias, true)))
+-            goto cleanup;
++        encalias = g_strdup_printf("%s-luks-secret0", disk->info.alias);
+ 
+         if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo, &encalias) < 0)
+             goto cleanup;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainGetGuestInfo-Don-t-try-to-free-a-negative-number-of-entries.patch b/SOURCES/libvirt-qemuDomainGetGuestInfo-Don-t-try-to-free-a-negative-number-of-entries.patch
new file mode 100644
index 0000000..677b0ad
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainGetGuestInfo-Don-t-try-to-free-a-negative-number-of-entries.patch
@@ -0,0 +1,77 @@
+From c03fef652341b4ee8969b2a0229e2ef9046a9cee Mon Sep 17 00:00:00 2001
+Message-Id: <c03fef652341b4ee8969b2a0229e2ef9046a9cee@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:35 +0100
+Subject: [PATCH] qemuDomainGetGuestInfo: Don't try to free a negative number
+ of entries
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+'nfs' variable was set to -1 or -2 on agent failure. Cleanup then tried
+to free 'nfs' elements of the array which resulted into a crash.
+
+Make 'nfs' size_t and assign it only on successful agent call.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1812965
+
+Broken by commit 599ae372d8cf092
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 0fdb7385e416c9a0830dc60c0a56d55428963d74)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1812965
+Message-Id: <6eb97463bb380d32591ef82336095bf1ef370bca.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_agent.c  |  2 +-
+ src/qemu/qemu_driver.c | 12 ++++++++----
+ 2 files changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
+index ef2d2c500b..f13126aeee 100644
+--- a/src/qemu/qemu_agent.c
++++ b/src/qemu/qemu_agent.c
+@@ -1954,7 +1954,7 @@ qemuAgentGetFSInfoFillDisks(virJSONValuePtr jsondisks,
+     return 0;
+ }
+ 
+-/* Returns: 0 on success
++/* Returns: number of entries in '@info' on success
+  *          -2 when agent command is not supported by the agent
+  *          -1 otherwise
+  */
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 8c7e90531a..0bdb2851ec 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -23101,7 +23101,7 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
+     g_autofree char *hostname = NULL;
+     unsigned int supportedTypes = types;
+     int rc;
+-    int nfs = 0;
++    size_t nfs = 0;
+     qemuAgentFSInfoPtr *agentfsinfo = NULL;
+     size_t i;
+ 
+@@ -23154,9 +23154,13 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
+         }
+     }
+     if (supportedTypes & VIR_DOMAIN_GUEST_INFO_FILESYSTEM) {
+-        rc = nfs = qemuAgentGetFSInfo(agent, &agentfsinfo);
+-        if (rc < 0 && !(rc == -2 && types == 0))
+-            goto exitagent;
++        rc = qemuAgentGetFSInfo(agent, &agentfsinfo);
++        if (rc < 0) {
++            if (!(rc == -2 && types == 0))
++                goto exitagent;
++        } else {
++            nfs = rc;
++        }
+     }
+ 
+     ret = 0;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainGetGuestInfo-don-t-assign-NULL-hostname.patch b/SOURCES/libvirt-qemuDomainGetGuestInfo-don-t-assign-NULL-hostname.patch
new file mode 100644
index 0000000..40e3ec7
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainGetGuestInfo-don-t-assign-NULL-hostname.patch
@@ -0,0 +1,49 @@
+From 1e8e5094ee8112244c32704539202dd02866cfd6 Mon Sep 17 00:00:00 2001
+Message-Id: <1e8e5094ee8112244c32704539202dd02866cfd6@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:33 +0100
+Subject: [PATCH] qemuDomainGetGuestInfo: don't assign NULL hostname
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Don't rely on error check and assign hostname only when non-NULL.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 530ac288618b2f46e49f3ce86d4d89e7607ee3fe)
+https://bugzilla.redhat.com/show_bug.cgi?id=1812965
+Message-Id: <cb3528a36549edc5fdd23cb1e573e99fc43e9d15.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 05e525e935..175a1961c2 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -23254,14 +23254,14 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
+     }
+     if (supportedTypes & VIR_DOMAIN_GUEST_INFO_HOSTNAME) {
+         rc = qemuAgentGetHostname(agent, &hostname);
+-        if (rc < 0 && !(rc == -2 && types == 0)) {
++        if (rc < 0 && !(rc == -2 && types == 0))
+             goto exitagent;
+-        } else {
+-            if (virTypedParamsAddString(params, nparams, &maxparams, "hostname",
+-                                        hostname) < 0)
+-                goto exitagent;
+-        }
+     }
++
++    if (hostname &&
++        virTypedParamsAddString(params, nparams, &maxparams, "hostname", hostname) < 0)
++        goto exitagent;
++
+     if (supportedTypes & VIR_DOMAIN_GUEST_INFO_FILESYSTEM) {
+         rc = qemuAgentGetFSInfo(agent, &agentfsinfo);
+         if (rc < 0) {
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainGetSecretAESAlias-Replace-outstanding-uses-with-qemuAliasForSecret.patch b/SOURCES/libvirt-qemuDomainGetSecretAESAlias-Replace-outstanding-uses-with-qemuAliasForSecret.patch
new file mode 100644
index 0000000..baf5d1a
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainGetSecretAESAlias-Replace-outstanding-uses-with-qemuAliasForSecret.patch
@@ -0,0 +1,110 @@
+From a3072c4077a72bf85636a7f0fe63fb40b96410f4 Mon Sep 17 00:00:00 2001
+Message-Id: <a3072c4077a72bf85636a7f0fe63fb40b96410f4@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:55 +0100
+Subject: [PATCH] qemuDomainGetSecretAESAlias: Replace outstanding uses with
+ qemuAliasForSecret
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are two last callers of this function. Replace them by
+qemuAliasForSecret and delete qemuDomainGetSecretAESAlias.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 43a3d2e02ed09fafa04b61815c23651b0a94ef58)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <b70522a89f40d60b92029c6c7c5d10842c175fbb.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_alias.c            | 29 -----------------------------
+ src/qemu/qemu_alias.h            |  3 ---
+ src/qemu/qemu_hotplug.c          |  2 +-
+ src/qemu/qemu_migration_params.c |  2 +-
+ 4 files changed, 2 insertions(+), 34 deletions(-)
+
+diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
+index 50ad054c6c..7889f16bb2 100644
+--- a/src/qemu/qemu_alias.c
++++ b/src/qemu/qemu_alias.c
+@@ -763,35 +763,6 @@ qemuDomainGetMasterKeyAlias(void)
+ }
+ 
+ 
+-/* qemuDomainGetSecretAESAlias:
+- * @srcalias: Source alias used to generate the secret alias
+- * @isLuks: True when we are generating a secret for LUKS encrypt/decrypt
+- *
+- * Generate and return an alias for the encrypted secret
+- *
+- * Returns NULL or a string containing the alias
+- */
+-char *
+-qemuDomainGetSecretAESAlias(const char *srcalias,
+-                            bool isLuks)
+-{
+-    char *alias;
+-
+-    if (!srcalias) {
+-        virReportError(VIR_ERR_INVALID_ARG, "%s",
+-                       _("encrypted secret alias requires valid source alias"));
+-        return NULL;
+-    }
+-
+-    if (isLuks)
+-        alias = g_strdup_printf("%s-luks-secret0", srcalias);
+-    else
+-        alias = g_strdup_printf("%s-secret0", srcalias);
+-
+-    return alias;
+-}
+-
+-
+ /* qemuAliasForSecret:
+  * @parentalias: alias of the parent object
+  * @obj: optional sub-object of the parent device the secret is for
+diff --git a/src/qemu/qemu_alias.h b/src/qemu/qemu_alias.h
+index 645956d024..490aa568a9 100644
+--- a/src/qemu/qemu_alias.h
++++ b/src/qemu/qemu_alias.h
+@@ -83,9 +83,6 @@ char *qemuAliasFromHostdev(const virDomainHostdevDef *hostdev);
+ 
+ char *qemuDomainGetMasterKeyAlias(void);
+ 
+-char *qemuDomainGetSecretAESAlias(const char *srcalias,
+-                                  bool isLuks);
+-
+ char *qemuAliasForSecret(const char *parentalias,
+                          const char *obj);
+ 
+diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
+index a473bab3e1..3ccc01f0b7 100644
+--- a/src/qemu/qemu_hotplug.c
++++ b/src/qemu/qemu_hotplug.c
+@@ -1844,7 +1844,7 @@ qemuDomainDelChardevTLSObjects(virQEMUDriverPtr driver,
+      * secret UUID and we have a serial TCP chardev, then formulate a
+      * secAlias which we'll attempt to destroy. */
+     if (cfg->chardevTLSx509secretUUID &&
+-        !(secAlias = qemuDomainGetSecretAESAlias(inAlias, false)))
++        !(secAlias = qemuAliasForSecret(inAlias, NULL)))
+         return -1;
+ 
+     qemuDomainObjEnterMonitor(driver, vm);
+diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
+index 0a3b0f8741..28fb006374 100644
+--- a/src/qemu/qemu_migration_params.c
++++ b/src/qemu/qemu_migration_params.c
+@@ -1084,7 +1084,7 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver,
+         return;
+ 
+     tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE);
+-    secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false);
++    secAlias = qemuAliasForSecret(QEMU_MIGRATION_TLS_ALIAS_BASE, NULL);
+ 
+     qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias);
+     g_clear_pointer(&QEMU_DOMAIN_PRIVATE(vm)->migSecinfo, qemuDomainSecretInfoFree);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainGetStatsIOThread-Don-t-leak-array-with-0-iothreads.patch b/SOURCES/libvirt-qemuDomainGetStatsIOThread-Don-t-leak-array-with-0-iothreads.patch
new file mode 100644
index 0000000..9b92a10
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainGetStatsIOThread-Don-t-leak-array-with-0-iothreads.patch
@@ -0,0 +1,48 @@
+From 388611da8330fb19693caf927680e9af08d5738e Mon Sep 17 00:00:00 2001
+Message-Id: <388611da8330fb19693caf927680e9af08d5738e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:27 +0100
+Subject: [PATCH] qemuDomainGetStatsIOThread: Don't leak array with 0 iothreads
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+qemuMonitorGetIOThreads returns a NULL-terminated list even when 0
+iothreads are present. The caller didn't perform cleanup if there were 0
+iothreads leaking the array.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804548
+
+Fixes: d1eac92784573559b6fd56836e33b215c89308e3
+Reported-by: Jing Yan <jiyan@redhat.com>
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 9bf9e0ae6af38c806f4672ca7b12a6b38d5a9581)
+Message-Id: <eef614566ad383a1393a295caa6e2550381eb3e7.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index af81c4a6e4..69e4f7264b 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -21532,8 +21532,12 @@ qemuDomainGetStatsIOThread(virQEMUDriverPtr driver,
+     if ((niothreads = qemuDomainGetIOThreadsMon(driver, dom, &iothreads)) < 0)
+         return -1;
+ 
+-    if (niothreads == 0)
+-        return 0;
++    /* qemuDomainGetIOThreadsMon returns a NULL-terminated list, so we must free
++     * it even if it returns 0 */
++    if (niothreads == 0) {
++        ret = 0;
++        goto cleanup;
++    }
+ 
+     if (virTypedParamListAddUInt(params, niothreads, "iothread.count") < 0)
+         goto cleanup;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuDomainSaveImageStartVM-Use-VIR_AUTOCLOSE-for-intermediatefd.patch b/SOURCES/libvirt-qemuDomainSaveImageStartVM-Use-VIR_AUTOCLOSE-for-intermediatefd.patch
new file mode 100644
index 0000000..c29aa79
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSaveImageStartVM-Use-VIR_AUTOCLOSE-for-intermediatefd.patch
@@ -0,0 +1,56 @@
+From 6442aa5565de857371a7076c56ced84fbea0ec66 Mon Sep 17 00:00:00 2001
+Message-Id: <6442aa5565de857371a7076c56ced84fbea0ec66@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Thu, 16 Jan 2020 10:03:51 +0100
+Subject: [PATCH] qemuDomainSaveImageStartVM: Use VIR_AUTOCLOSE for
+ @intermediatefd
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1718707
+
+(cherry picked from commit 1c16f261d0764ff70fb33ece4367f25e741cdb74)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <f181efbc202853298ca06eecf78e7dad1063dc16.1579165329.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index d6b1e9f00c..9de5bc6a32 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -6803,7 +6803,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+     int ret = -1;
+     bool restored = false;
+     virObjectEventPtr event;
+-    int intermediatefd = -1;
++    VIR_AUTOCLOSE intermediatefd = -1;
+     virCommandPtr cmd = NULL;
+     g_autofree char *errbuf = NULL;
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+@@ -6829,6 +6829,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+ 
+         if (virCommandRunAsync(cmd, NULL) < 0) {
+             *fd = intermediatefd;
++            intermediatefd = -1;
+             goto cleanup;
+         }
+     }
+@@ -6872,8 +6873,6 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+ 
+         virErrorRestore(&orig_err);
+     }
+-    VIR_FORCE_CLOSE(intermediatefd);
+-
+     if (VIR_CLOSE(*fd) < 0) {
+         virReportSystemError(errno, _("cannot close file: %s"), path);
+         restored = false;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuDomainSaveImageStartVM-Use-g_autoptr-for-virCommand.patch b/SOURCES/libvirt-qemuDomainSaveImageStartVM-Use-g_autoptr-for-virCommand.patch
new file mode 100644
index 0000000..3ef3c35
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSaveImageStartVM-Use-g_autoptr-for-virCommand.patch
@@ -0,0 +1,46 @@
+From 09776b6ac6421a03fe2ff72eb6146a9ca0119259 Mon Sep 17 00:00:00 2001
+Message-Id: <09776b6ac6421a03fe2ff72eb6146a9ca0119259@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Thu, 16 Jan 2020 10:03:52 +0100
+Subject: [PATCH] qemuDomainSaveImageStartVM: Use g_autoptr() for virCommand
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1718707
+
+(cherry picked from commit 82e127e34350dc0ed908611a3b2a4fbd78ad9903)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <5d41d06ee27842659082e67dd6abf40c3c59ae5d.1579165329.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 9de5bc6a32..e1c0550b9a 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -6804,7 +6804,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+     bool restored = false;
+     virObjectEventPtr event;
+     VIR_AUTOCLOSE intermediatefd = -1;
+-    virCommandPtr cmd = NULL;
++    g_autoptr(virCommand) cmd = NULL;
+     g_autofree char *errbuf = NULL;
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+     virQEMUSaveHeaderPtr header = &data->header;
+@@ -6920,7 +6920,6 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
+ 
+  cleanup:
+     virObjectUnref(cookie);
+-    virCommandFree(cmd);
+     if (qemuSecurityRestoreSavedStateLabel(driver, vm, path) < 0)
+         VIR_WARN("failed to restore save state label on %s", path);
+     return ret;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuDomainSecretAESSetup-Allocate-and-return-secinfo-here.patch b/SOURCES/libvirt-qemuDomainSecretAESSetup-Allocate-and-return-secinfo-here.patch
new file mode 100644
index 0000000..335c90c
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretAESSetup-Allocate-and-return-secinfo-here.patch
@@ -0,0 +1,146 @@
+From fe42b8bb2e4a456a5b2297313f3859221013fdfc Mon Sep 17 00:00:00 2001
+Message-Id: <fe42b8bb2e4a456a5b2297313f3859221013fdfc@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:46 +0100
+Subject: [PATCH] qemuDomainSecretAESSetup: Allocate and return 'secinfo' here
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Rather than passing in an empty qemuDomainSecretInfoPtr allocate it
+in this function and return it. This is done by absorbing the check from
+qemuDomainSecretInfoNew and removing the internals of
+qemuDomainSecretInfoNew.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit bad8637892ae8fc310b252651876738ca4fdee0d)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <94071336dbc97ed64a1a5dcbb82da32e5199f117.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 53 ++++++++++++++++++------------------------
+ 1 file changed, 22 insertions(+), 31 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index b26187659e..37e361b1f4 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1529,21 +1529,20 @@ qemuDomainSecretPlainSetup(qemuDomainSecretInfoPtr secinfo,
+  * @seclookupdef: Pointer to seclookupdef data
+  * @isLuks: True/False for is for luks (alias generation)
+  *
+- * Taking a secinfo, fill in the AES specific information using the
++ * Encrypts a secret looked up via @seclookupdef for use with qemu.
+  *
+- * Returns 0 on success, -1 on failure with error message
++ * Returns qemuDomainSecretInfoPtr filled with the necessary information.
+  */
+-static int
++static qemuDomainSecretInfoPtr
+ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+-                         qemuDomainSecretInfoPtr secinfo,
+                          const char *srcalias,
+                          virSecretUsageType usageType,
+                          const char *username,
+                          virSecretLookupTypeDefPtr seclookupdef,
+                          bool isLuks)
+ {
++    g_autoptr(qemuDomainSecretInfo) secinfo = NULL;
+     g_autoptr(virConnect) conn = virGetConnectSecret();
+-    int ret = -1;
+     g_autofree uint8_t *raw_iv = NULL;
+     size_t ivlen = QEMU_DOMAIN_AES_IV_LEN;
+     uint8_t *secret = NULL;
+@@ -1552,19 +1551,27 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+     size_t ciphertextlen = 0;
+ 
+     if (!conn)
+-        return -1;
++        return NULL;
++
++    if (!qemuDomainSupportsEncryptedSecret(priv)) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                       _("encrypted secrets are not supported"));
++        return NULL;
++    }
++
++    secinfo = g_new0(qemuDomainSecretInfo, 1);
+ 
+     secinfo->type = VIR_DOMAIN_SECRET_INFO_TYPE_AES;
+     secinfo->s.aes.username = g_strdup(username);
+ 
+     if (!(secinfo->s.aes.alias = qemuDomainGetSecretAESAlias(srcalias, isLuks)))
+-        return -1;
++        return NULL;
+ 
+     raw_iv = g_new0(uint8_t, ivlen);
+ 
+     /* Create a random initialization vector */
+     if (virRandomBytes(raw_iv, ivlen) < 0)
+-        return -1;
++        return NULL;
+ 
+     /* Encode the IV and save that since qemu will need it */
+     secinfo->s.aes.iv = g_base64_encode(raw_iv, ivlen);
+@@ -1572,13 +1579,13 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+     /* Grab the unencoded secret */
+     if (virSecretGetSecretString(conn, seclookupdef, usageType,
+                                  &secret, &secretlen) < 0)
+-        goto cleanup;
++        goto error;
+ 
+     if (virCryptoEncryptData(VIR_CRYPTO_CIPHER_AES256CBC,
+                              priv->masterKey, QEMU_DOMAIN_MASTER_KEY_LEN,
+                              raw_iv, ivlen, secret, secretlen,
+                              &ciphertext, &ciphertextlen) < 0)
+-        goto cleanup;
++        goto error;
+ 
+     /* Clear out the secret */
+     memset(secret, 0, secretlen);
+@@ -1587,11 +1594,11 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+     secinfo->s.aes.ciphertext = g_base64_encode(ciphertext,
+                                                 ciphertextlen);
+ 
+-    ret = 0;
++    return g_steal_pointer(&secinfo);
+ 
+- cleanup:
++ error:
+     VIR_DISPOSE_N(secret, secretlen);
+-    return ret;
++    return NULL;
+ }
+ 
+ 
+@@ -1663,24 +1670,8 @@ qemuDomainSecretInfoNew(qemuDomainObjPrivatePtr priv,
+                         virSecretLookupTypeDefPtr lookupDef,
+                         bool isLuks)
+ {
+-    qemuDomainSecretInfoPtr secinfo = NULL;
+-
+-    if (!qemuDomainSupportsEncryptedSecret(priv)) {
+-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+-                       _("encrypted secrets are not supported"));
+-        return NULL;
+-    }
+-
+-    if (VIR_ALLOC(secinfo) < 0)
+-        return NULL;
+-
+-    if (qemuDomainSecretAESSetup(priv, secinfo, srcAlias, usageType, username,
+-                                 lookupDef, isLuks) < 0) {
+-        g_clear_pointer(&secinfo, qemuDomainSecretInfoFree);
+-        return NULL;
+-    }
+-
+-    return secinfo;
++    return qemuDomainSecretAESSetup(priv, srcAlias, usageType, username,
++                                    lookupDef, isLuks);
+ }
+ 
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSecretAESSetup-Automatically-free-non-secret-locals.patch b/SOURCES/libvirt-qemuDomainSecretAESSetup-Automatically-free-non-secret-locals.patch
new file mode 100644
index 0000000..89984ae
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretAESSetup-Automatically-free-non-secret-locals.patch
@@ -0,0 +1,88 @@
+From 044e5a7db716235c167f76974d4bd7566248cf9a Mon Sep 17 00:00:00 2001
+Message-Id: <044e5a7db716235c167f76974d4bd7566248cf9a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:45 +0100
+Subject: [PATCH] qemuDomainSecretAESSetup: Automatically free non-secret
+ locals
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use g_autofree for the ciphertext and init vector as they are not
+secret and thus don't have to be cleared and use g_new0 to allocate the
+iv for parity.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 88126d5f0ec3899dbc3bc223d120de159ded9dca)
+
+ Conflicts:
+    src/qemu/qemu_domain.c:
+    20fa2bc6e52e01feaf39d12d38bcf8eaec4c9a46 was not backported
+    and thus this patch also effectively backports the modification
+    the patch mentioned above did to qemuDomainSecretAESSetup as it
+    would not result in a clean backport.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <6d4512020332b977f8de5843469e0d030f4f65d3.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index b77488026a..b26187659e 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1542,16 +1542,15 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+                          virSecretLookupTypeDefPtr seclookupdef,
+                          bool isLuks)
+ {
+-    virConnectPtr conn;
++    g_autoptr(virConnect) conn = virGetConnectSecret();
+     int ret = -1;
+-    uint8_t *raw_iv = NULL;
++    g_autofree uint8_t *raw_iv = NULL;
+     size_t ivlen = QEMU_DOMAIN_AES_IV_LEN;
+     uint8_t *secret = NULL;
+     size_t secretlen = 0;
+-    uint8_t *ciphertext = NULL;
++    g_autofree uint8_t *ciphertext = NULL;
+     size_t ciphertextlen = 0;
+ 
+-    conn = virGetConnectSecret();
+     if (!conn)
+         return -1;
+ 
+@@ -1559,14 +1558,13 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+     secinfo->s.aes.username = g_strdup(username);
+ 
+     if (!(secinfo->s.aes.alias = qemuDomainGetSecretAESAlias(srcalias, isLuks)))
+-        goto cleanup;
++        return -1;
+ 
+-    if (VIR_ALLOC_N(raw_iv, ivlen) < 0)
+-        goto cleanup;
++    raw_iv = g_new0(uint8_t, ivlen);
+ 
+     /* Create a random initialization vector */
+     if (virRandomBytes(raw_iv, ivlen) < 0)
+-        goto cleanup;
++        return -1;
+ 
+     /* Encode the IV and save that since qemu will need it */
+     secinfo->s.aes.iv = g_base64_encode(raw_iv, ivlen);
+@@ -1592,10 +1590,7 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+     ret = 0;
+ 
+  cleanup:
+-    VIR_DISPOSE_N(raw_iv, ivlen);
+     VIR_DISPOSE_N(secret, secretlen);
+-    VIR_DISPOSE_N(ciphertext, ciphertextlen);
+-    virObjectUnref(conn);
+     return ret;
+ }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSecretAESSetup-Split-out-lookup-of-secret-data.patch b/SOURCES/libvirt-qemuDomainSecretAESSetup-Split-out-lookup-of-secret-data.patch
new file mode 100644
index 0000000..03eed00
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretAESSetup-Split-out-lookup-of-secret-data.patch
@@ -0,0 +1,174 @@
+From 881121d506d6482d4bdbf557994f31d6eb55af3f Mon Sep 17 00:00:00 2001
+Message-Id: <881121d506d6482d4bdbf557994f31d6eb55af3f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:47 +0100
+Subject: [PATCH] qemuDomainSecretAESSetup: Split out lookup of secret data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Split out the lookup of the secret from the secret driver into
+qemuDomainSecretAESSetupFromSecret so that we can also instantiate
+secret objects in qemu with data from other sources.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 88663e59ef62346cdea7e260c5d598c2e738c674)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <159609ccfe0ca42a20409e83f3f0d521113d8938.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 87 ++++++++++++++++++++++++++----------------
+ 1 file changed, 54 insertions(+), 33 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 37e361b1f4..c286f50650 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1522,37 +1522,28 @@ qemuDomainSecretPlainSetup(qemuDomainSecretInfoPtr secinfo,
+ 
+ /* qemuDomainSecretAESSetup:
+  * @priv: pointer to domain private object
+- * @secinfo: Pointer to secret info
+- * @srcalias: Alias of the disk/hostdev used to generate the secret alias
+- * @usageType: The virSecretUsageType
+- * @username: username to use for authentication (may be NULL)
+- * @seclookupdef: Pointer to seclookupdef data
+- * @isLuks: True/False for is for luks (alias generation)
++ * @alias: alias of the secret
++ * @username: username to use (may be NULL)
++ * @secret: secret data
++ * @secretlen: length of @secret
+  *
+- * Encrypts a secret looked up via @seclookupdef for use with qemu.
++ * Encrypts @secret for use with qemu.
+  *
+  * Returns qemuDomainSecretInfoPtr filled with the necessary information.
+  */
+ static qemuDomainSecretInfoPtr
+ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+-                         const char *srcalias,
+-                         virSecretUsageType usageType,
++                         const char *alias,
+                          const char *username,
+-                         virSecretLookupTypeDefPtr seclookupdef,
+-                         bool isLuks)
++                         uint8_t *secret,
++                         size_t secretlen)
+ {
+     g_autoptr(qemuDomainSecretInfo) secinfo = NULL;
+-    g_autoptr(virConnect) conn = virGetConnectSecret();
+     g_autofree uint8_t *raw_iv = NULL;
+     size_t ivlen = QEMU_DOMAIN_AES_IV_LEN;
+-    uint8_t *secret = NULL;
+-    size_t secretlen = 0;
+     g_autofree uint8_t *ciphertext = NULL;
+     size_t ciphertextlen = 0;
+ 
+-    if (!conn)
+-        return NULL;
+-
+     if (!qemuDomainSupportsEncryptedSecret(priv)) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("encrypted secrets are not supported"));
+@@ -1562,11 +1553,9 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+     secinfo = g_new0(qemuDomainSecretInfo, 1);
+ 
+     secinfo->type = VIR_DOMAIN_SECRET_INFO_TYPE_AES;
++    secinfo->s.aes.alias = g_strdup(alias);
+     secinfo->s.aes.username = g_strdup(username);
+ 
+-    if (!(secinfo->s.aes.alias = qemuDomainGetSecretAESAlias(srcalias, isLuks)))
+-        return NULL;
+-
+     raw_iv = g_new0(uint8_t, ivlen);
+ 
+     /* Create a random initialization vector */
+@@ -1576,29 +1565,61 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+     /* Encode the IV and save that since qemu will need it */
+     secinfo->s.aes.iv = g_base64_encode(raw_iv, ivlen);
+ 
+-    /* Grab the unencoded secret */
+-    if (virSecretGetSecretString(conn, seclookupdef, usageType,
+-                                 &secret, &secretlen) < 0)
+-        goto error;
+-
+     if (virCryptoEncryptData(VIR_CRYPTO_CIPHER_AES256CBC,
+                              priv->masterKey, QEMU_DOMAIN_MASTER_KEY_LEN,
+                              raw_iv, ivlen, secret, secretlen,
+                              &ciphertext, &ciphertextlen) < 0)
+-        goto error;
+-
+-    /* Clear out the secret */
+-    memset(secret, 0, secretlen);
++        return NULL;
+ 
+     /* Now encode the ciphertext and store to be passed to qemu */
+     secinfo->s.aes.ciphertext = g_base64_encode(ciphertext,
+                                                 ciphertextlen);
+ 
+     return g_steal_pointer(&secinfo);
++}
++
++
++/**
++ * qemuDomainSecretAESSetupFromSecret:
++ * @priv: pointer to domain private object
++ * @srcalias: Alias of the disk/hostdev used to generate the secret alias
++ * @usageType: The virSecretUsageType
++ * @username: username to use for authentication (may be NULL)
++ * @seclookupdef: Pointer to seclookupdef data
++ * @isLuks: True/False for is for luks (alias generation)
++ *
++ * Looks up a secret in the secret driver based on @usageType and @seclookupdef
++ * and builds qemuDomainSecretInfoPtr from it.
++ */
++static qemuDomainSecretInfoPtr
++qemuDomainSecretAESSetupFromSecret(qemuDomainObjPrivatePtr priv,
++                                   const char *srcalias,
++                                   virSecretUsageType usageType,
++                                   const char *username,
++                                   virSecretLookupTypeDefPtr seclookupdef,
++                                   bool isLuks)
++{
++    g_autoptr(virConnect) conn = virGetConnectSecret();
++    qemuDomainSecretInfoPtr secinfo;
++    g_autofree char *alias = NULL;
++    uint8_t *secret = NULL;
++    size_t secretlen = 0;
++
++    if (!conn)
++        return NULL;
++
++    if (!(alias = qemuDomainGetSecretAESAlias(srcalias, isLuks)))
++        return NULL;
++
++    if (virSecretGetSecretString(conn, seclookupdef, usageType,
++                                 &secret, &secretlen) < 0)
++        return NULL;
++
++    secinfo = qemuDomainSecretAESSetup(priv, alias, username, secret, secretlen);
+ 
+- error:
+     VIR_DISPOSE_N(secret, secretlen);
+-    return NULL;
++
++    return secinfo;
+ }
+ 
+ 
+@@ -1670,8 +1691,8 @@ qemuDomainSecretInfoNew(qemuDomainObjPrivatePtr priv,
+                         virSecretLookupTypeDefPtr lookupDef,
+                         bool isLuks)
+ {
+-    return qemuDomainSecretAESSetup(priv, srcAlias, usageType, username,
+-                                    lookupDef, isLuks);
++    return qemuDomainSecretAESSetupFromSecret(priv, srcAlias, usageType, username,
++                                              lookupDef, isLuks);
+ }
+ 
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSecretAESSetupFromSecret-Use-qemuAliasForSecret.patch b/SOURCES/libvirt-qemuDomainSecretAESSetupFromSecret-Use-qemuAliasForSecret.patch
new file mode 100644
index 0000000..2aba2b0
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretAESSetupFromSecret-Use-qemuAliasForSecret.patch
@@ -0,0 +1,123 @@
+From 055d76ce856aecab3dfe3106429c926df405143b Mon Sep 17 00:00:00 2001
+Message-Id: <055d76ce856aecab3dfe3106429c926df405143b@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:53 +0100
+Subject: [PATCH] qemuDomainSecretAESSetupFromSecret: Use 'qemuAliasForSecret'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Replace qemuDomainGetSecretAESAlias by the new function so that we can
+reuse qemuDomainSecretAESSetupFromSecret also for setting up other kinds
+of objects.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 86fecaedf556dbd4d32efe28638c811be0e595d3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <88a582c0e5b8a73dd88f6872530c80b404149fb3.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 30 ++++++++++++++----------------
+ 1 file changed, 14 insertions(+), 16 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 0047a1d316..3599e0c9aa 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1583,34 +1583,32 @@ qemuDomainSecretAESSetup(qemuDomainObjPrivatePtr priv,
+  * qemuDomainSecretAESSetupFromSecret:
+  * @priv: pointer to domain private object
+  * @srcalias: Alias of the disk/hostdev used to generate the secret alias
++ * @secretuse: specific usage for the secret (may be NULL if main object is using it)
+  * @usageType: The virSecretUsageType
+  * @username: username to use for authentication (may be NULL)
+  * @seclookupdef: Pointer to seclookupdef data
+- * @isLuks: True/False for is for luks (alias generation)
+  *
+  * Looks up a secret in the secret driver based on @usageType and @seclookupdef
+- * and builds qemuDomainSecretInfoPtr from it.
++ * and builds qemuDomainSecretInfoPtr from it. @use describes the usage of the
++ * secret in case if @srcalias requires more secrets for various usage cases.
+  */
+ static qemuDomainSecretInfoPtr
+ qemuDomainSecretAESSetupFromSecret(qemuDomainObjPrivatePtr priv,
+                                    const char *srcalias,
++                                   const char *secretuse,
+                                    virSecretUsageType usageType,
+                                    const char *username,
+-                                   virSecretLookupTypeDefPtr seclookupdef,
+-                                   bool isLuks)
++                                   virSecretLookupTypeDefPtr seclookupdef)
+ {
+     g_autoptr(virConnect) conn = virGetConnectSecret();
+     qemuDomainSecretInfoPtr secinfo;
+-    g_autofree char *alias = NULL;
++    g_autofree char *alias = qemuAliasForSecret(srcalias, secretuse);
+     uint8_t *secret = NULL;
+     size_t secretlen = 0;
+ 
+     if (!conn)
+         return NULL;
+ 
+-    if (!(alias = qemuDomainGetSecretAESAlias(srcalias, isLuks)))
+-        return NULL;
+-
+     if (virSecretGetSecretString(conn, seclookupdef, usageType,
+                                  &secret, &secretlen) < 0)
+         return NULL;
+@@ -1695,9 +1693,9 @@ qemuDomainSecretInfoTLSNew(qemuDomainObjPrivatePtr priv,
+     }
+     seclookupdef.type = VIR_SECRET_LOOKUP_TYPE_UUID;
+ 
+-    return qemuDomainSecretAESSetupFromSecret(priv, srcAlias,
++    return qemuDomainSecretAESSetupFromSecret(priv, srcAlias, NULL,
+                                               VIR_SECRET_USAGE_TYPE_TLS,
+-                                              NULL, &seclookupdef, false);
++                                              NULL, &seclookupdef);
+ }
+ 
+ 
+@@ -1788,10 +1786,10 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+                                                             &src->auth->seclookupdef);
+         } else {
+             srcPriv->secinfo = qemuDomainSecretAESSetupFromSecret(priv, aliasprotocol,
++                                                                  NULL,
+                                                                   usageType,
+                                                                   src->auth->username,
+-                                                                  &src->auth->seclookupdef,
+-                                                                  false);
++                                                                  &src->auth->seclookupdef);
+         }
+ 
+         if (!srcPriv->secinfo)
+@@ -1800,10 +1798,10 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+ 
+     if (hasEnc) {
+         if (!(srcPriv->encinfo = qemuDomainSecretAESSetupFromSecret(priv, aliasformat,
++                                                                    "luks",
+                                                                     VIR_SECRET_USAGE_TYPE_VOLUME,
+                                                                     NULL,
+-                                                                    &src->encryption->secrets[0]->seclookupdef,
+-                                                                    true)))
++                                                                    &src->encryption->secrets[0]->seclookupdef)))
+               return -1;
+     }
+ 
+@@ -1864,10 +1862,10 @@ qemuDomainSecretHostdevPrepare(qemuDomainObjPrivatePtr priv,
+             } else {
+                 srcPriv->secinfo = qemuDomainSecretAESSetupFromSecret(priv,
+                                                                       hostdev->info->alias,
++                                                                      NULL,
+                                                                       usageType,
+                                                                       src->auth->username,
+-                                                                      &src->auth->seclookupdef,
+-                                                                      false);
++                                                                      &src->auth->seclookupdef);
+             }
+ 
+             if (!srcPriv->secinfo)
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSecretInfo-Register-autoptr-cleanup-function.patch b/SOURCES/libvirt-qemuDomainSecretInfo-Register-autoptr-cleanup-function.patch
new file mode 100644
index 0000000..48eacaa
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretInfo-Register-autoptr-cleanup-function.patch
@@ -0,0 +1,36 @@
+From 865a4770a5145a0df11a42bb0efc7e72e862a236 Mon Sep 17 00:00:00 2001
+Message-Id: <865a4770a5145a0df11a42bb0efc7e72e862a236@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:44 +0100
+Subject: [PATCH] qemuDomainSecretInfo: Register autoptr cleanup function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit b544481a91e6f3ee0e7534e0fc3d2cfb3bb60dba)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <f8b983d058091e9cd0631589334d72a1ecc1ec7d.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
+index 89a967efd7..bd9ac85ae2 100644
+--- a/src/qemu/qemu_domain.h
++++ b/src/qemu/qemu_domain.h
+@@ -1035,6 +1035,8 @@ bool qemuDomainSupportsEncryptedSecret(qemuDomainObjPrivatePtr priv);
+ void qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr secinfo)
+     ATTRIBUTE_NONNULL(1);
+ 
++G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainSecretInfo, qemuDomainSecretInfoFree);
++
+ void qemuDomainSecretInfoDestroy(qemuDomainSecretInfoPtr secinfo);
+ 
+ void qemuDomainSecretDiskDestroy(virDomainDiskDefPtr disk)
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Change-aliases-for-disk-secrets.patch b/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Change-aliases-for-disk-secrets.patch
new file mode 100644
index 0000000..66eaa43
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Change-aliases-for-disk-secrets.patch
@@ -0,0 +1,640 @@
+From 753a2f4071eadeed34e92c9b3b98423ae33fbfad Mon Sep 17 00:00:00 2001
+Message-Id: <753a2f4071eadeed34e92c9b3b98423ae33fbfad@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:54 +0100
+Subject: [PATCH] qemuDomainSecretStorageSourcePrepare: Change aliases for disk
+ secrets
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Originally there was only the secret for authentication so we didn't use
+any suffix to tell it apart. With the introduction of encryption we
+added a 'luks' suffix for the encryption secrets. Since encryption is
+really generic and authentication is not the only secret modify the
+aliases for the secrets to better describe what they are used for.
+
+This is possible as we store the disk secrets in the status XML thus
+only new machines will use the new secrets.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 70d2758a9cee795b26563fe33b38a2396efa2324)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <ca3a038969c81a17495add50a445901d5e42de5a.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c                        |  4 +--
+ ...-backing-chains-noindex.x86_64-2.12.0.args |  4 +--
+ ...-backing-chains-noindex.x86_64-latest.args |  6 ++--
+ ...sk-hostdev-scsi-virtio-iscsi-auth-AES.args |  6 ++--
+ .../disk-network-iscsi.x86_64-2.12.0.args     | 12 +++----
+ .../disk-network-iscsi.x86_64-latest.args     |  8 ++---
+ .../disk-network-rbd.x86_64-2.12.0.args       |  4 +--
+ .../disk-network-rbd.x86_64-latest.args       |  4 +--
+ ...isk-network-source-auth.x86_64-2.12.0.args | 10 +++---
+ ...isk-network-source-auth.x86_64-latest.args |  8 ++---
+ .../disk-nvme.x86_64-latest.args              |  4 +--
+ .../encrypted-disk-usage.args                 |  4 +--
+ tests/qemuxml2argvdata/encrypted-disk.args    |  4 +--
+ .../luks-disks-source-qcow2.args              | 24 +++++++-------
+ ...luks-disks-source-qcow2.x86_64-latest.args | 32 +++++++++----------
+ tests/qemuxml2argvdata/luks-disks-source.args | 26 ++++++++-------
+ tests/qemuxml2argvdata/luks-disks.args        | 10 +++---
+ tests/qemuxml2argvdata/user-aliases.args      |  4 +--
+ 18 files changed, 90 insertions(+), 84 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 3599e0c9aa..65df463acc 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1786,7 +1786,7 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+                                                             &src->auth->seclookupdef);
+         } else {
+             srcPriv->secinfo = qemuDomainSecretAESSetupFromSecret(priv, aliasprotocol,
+-                                                                  NULL,
++                                                                  "auth",
+                                                                   usageType,
+                                                                   src->auth->username,
+                                                                   &src->auth->seclookupdef);
+@@ -1798,7 +1798,7 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+ 
+     if (hasEnc) {
+         if (!(srcPriv->encinfo = qemuDomainSecretAESSetupFromSecret(priv, aliasformat,
+-                                                                    "luks",
++                                                                    "encryption",
+                                                                     VIR_SECRET_USAGE_TYPE_VOLUME,
+                                                                     NULL,
+                                                                     &src->encryption->secrets[0]->seclookupdef)))
+diff --git a/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-2.12.0.args b/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-2.12.0.args
+index a8675debd5..47691339d6 100644
+--- a/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-2.12.0.args
++++ b/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-2.12.0.args
+@@ -39,12 +39,12 @@ id=virtio-disk1 \
+ if=none,id=drive-virtio-disk2 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk2,\
+ id=virtio-disk2 \
+--object secret,id=virtio-disk3-secret0,\
++-object secret,id=virtio-disk3-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive 'file=rbd:pool/image:id=myname:auth_supported=cephx\;none:\
+ mon_host=mon1.example.org\:6321\;mon2.example.org\:6322\;mon3.example.org\:\
+-6322,file.password-secret=virtio-disk3-secret0,format=qcow2,if=none,\
++6322,file.password-secret=virtio-disk3-auth-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk3' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk3,\
+ id=virtio-disk3 \
+diff --git a/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-latest.args b/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-latest.args
+index 4108943574..23ceb0aa48 100644
+--- a/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-backing-chains-noindex.x86_64-latest.args
+@@ -80,15 +80,15 @@ id=virtio-disk2 \
+ "node-name":"libvirt-15-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-15-format","read-only":true,"driver":"qcow2",\
+ "file":"libvirt-15-storage","backing":null}' \
+--object secret,id=libvirt-14-storage-secret0,\
++-object secret,id=libvirt-14-storage-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"rbd","pool":"pool","image":"image",\
+ "server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org",\
+ "port":"6322"},{"host":"mon3.example.org","port":"6322"}],"user":"myname",\
+ "auth-client-required":["cephx","none"],\
+-"key-secret":"libvirt-14-storage-secret0","node-name":"libvirt-14-storage",\
+-"auto-read-only":true,"discard":"unmap"}' \
++"key-secret":"libvirt-14-storage-auth-secret0",\
++"node-name":"libvirt-14-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-14-format","read-only":false,"driver":"qcow2",\
+ "file":"libvirt-14-storage","backing":"libvirt-15-format"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=libvirt-14-format,\
+diff --git a/tests/qemuxml2argvdata/disk-hostdev-scsi-virtio-iscsi-auth-AES.args b/tests/qemuxml2argvdata/disk-hostdev-scsi-virtio-iscsi-auth-AES.args
+index aece52dad2..47b014aacc 100644
+--- a/tests/qemuxml2argvdata/disk-hostdev-scsi-virtio-iscsi-auth-AES.args
++++ b/tests/qemuxml2argvdata/disk-hostdev-scsi-virtio-iscsi-auth-AES.args
+@@ -28,13 +28,13 @@ server,nowait \
+ -no-acpi \
+ -device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 \
+ -usb \
+--object secret,id=virtio-disk0-secret0,\
++-object secret,id=virtio-disk0-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file.driver=iscsi,file.portal=example.org:6000,\
+ file.target=iqn.1992-01.com.example:storage,file.lun=1,file.transport=tcp,\
+-file.user=myname,file.password-secret=virtio-disk0-secret0,format=raw,if=none,\
+-id=drive-virtio-disk0 \
++file.user=myname,file.password-secret=virtio-disk0-auth-secret0,format=raw,\
++if=none,id=drive-virtio-disk0 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+ id=virtio-disk0,bootindex=1 \
+ -object secret,id=hostdev0-secret0,\
+diff --git a/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-2.12.0.args b/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-2.12.0.args
+index 55347521da..930d8d5db2 100644
+--- a/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-2.12.0.args
++++ b/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-2.12.0.args
+@@ -38,22 +38,22 @@ file.target=iqn.1992-01.com.example,file.lun=1,file.transport=tcp,format=raw,\
+ if=none,id=drive-virtio-disk1 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk1,\
+ id=virtio-disk1 \
+--object secret,id=virtio-disk2-secret0,\
++-object secret,id=virtio-disk2-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file.driver=iscsi,file.portal=example.org:6000,\
+ file.target=iqn.1992-01.com.example:storage,file.lun=1,file.transport=tcp,\
+-file.user=myname,file.password-secret=virtio-disk2-secret0,format=raw,if=none,\
+-id=drive-virtio-disk2 \
++file.user=myname,file.password-secret=virtio-disk2-auth-secret0,format=raw,\
++if=none,id=drive-virtio-disk2 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk2,\
+ id=virtio-disk2 \
+--object secret,id=virtio-disk3-secret0,\
++-object secret,id=virtio-disk3-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file.driver=iscsi,file.portal=example.org:6000,\
+ file.target=iqn.1992-01.com.example:storage,file.lun=2,file.transport=tcp,\
+-file.user=myname,file.password-secret=virtio-disk3-secret0,format=raw,if=none,\
+-id=drive-virtio-disk3 \
++file.user=myname,file.password-secret=virtio-disk3-auth-secret0,format=raw,\
++if=none,id=drive-virtio-disk3 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk3,\
+ id=virtio-disk3 \
+ -drive file.driver=iscsi,file.portal=example.org:3260,\
+diff --git a/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-latest.args
+index 8831db6622..1cb2f369f6 100644
+--- a/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-iscsi.x86_64-latest.args
+@@ -42,23 +42,23 @@ id=virtio-disk0,bootindex=1 \
+ "file":"libvirt-4-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=libvirt-4-format,\
+ id=virtio-disk1 \
+--object secret,id=libvirt-3-storage-secret0,\
++-object secret,id=libvirt-3-storage-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"iscsi","portal":"example.org:6000",\
+ "target":"iqn.1992-01.com.example:storage","lun":1,"transport":"tcp",\
+-"user":"myname","password-secret":"libvirt-3-storage-secret0",\
++"user":"myname","password-secret":"libvirt-3-storage-auth-secret0",\
+ "node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-3-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=libvirt-3-format,\
+ id=virtio-disk2 \
+--object secret,id=libvirt-2-storage-secret0,\
++-object secret,id=libvirt-2-storage-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"iscsi","portal":"example.org:6000",\
+ "target":"iqn.1992-01.com.example:storage","lun":2,"transport":"tcp",\
+-"user":"myname","password-secret":"libvirt-2-storage-secret0",\
++"user":"myname","password-secret":"libvirt-2-storage-auth-secret0",\
+ "node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-2-storage"}' \
+diff --git a/tests/qemuxml2argvdata/disk-network-rbd.x86_64-2.12.0.args b/tests/qemuxml2argvdata/disk-network-rbd.x86_64-2.12.0.args
+index 18cb534552..21d1c2deba 100644
+--- a/tests/qemuxml2argvdata/disk-network-rbd.x86_64-2.12.0.args
++++ b/tests/qemuxml2argvdata/disk-network-rbd.x86_64-2.12.0.args
+@@ -45,12 +45,12 @@ id=virtio-disk2 \
+ format=raw,if=none,id=drive-virtio-disk3 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk3,\
+ id=virtio-disk3 \
+--object secret,id=virtio-disk4-secret0,\
++-object secret,id=virtio-disk4-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive 'file=rbd:pool/image:id=myname:auth_supported=cephx\;none:\
+ mon_host=mon1.example.org\:6321\;mon2.example.org\:6322\;mon3.example.org\:\
+-6322,file.password-secret=virtio-disk4-secret0,format=raw,if=none,\
++6322,file.password-secret=virtio-disk4-auth-secret0,format=raw,if=none,\
+ id=drive-virtio-disk4' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk4,\
+ id=virtio-disk4 \
+diff --git a/tests/qemuxml2argvdata/disk-network-rbd.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-rbd.x86_64-latest.args
+index 2d05e63cd2..4c26dad497 100644
+--- a/tests/qemuxml2argvdata/disk-network-rbd.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-rbd.x86_64-latest.args
+@@ -56,14 +56,14 @@ id=virtio-disk2 \
+ "file":"libvirt-3-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=libvirt-3-format,\
+ id=virtio-disk3 \
+--object secret,id=libvirt-2-storage-secret0,\
++-object secret,id=libvirt-2-storage-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"rbd","pool":"pool","image":"image",\
+ "server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org",\
+ "port":"6322"},{"host":"mon3.example.org","port":"6322"}],"user":"myname",\
+ "auth-client-required":["cephx","none"],\
+-"key-secret":"libvirt-2-storage-secret0","node-name":"libvirt-2-storage",\
++"key-secret":"libvirt-2-storage-auth-secret0","node-name":"libvirt-2-storage",\
+ "auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-2-storage"}' \
+diff --git a/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-2.12.0.args b/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-2.12.0.args
+index f34c6b678d..279d5c73ec 100644
+--- a/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-2.12.0.args
++++ b/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-2.12.0.args
+@@ -27,21 +27,21 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -no-acpi \
+ -boot strict=on \
+ -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+--object secret,id=virtio-disk0-secret0,\
++-object secret,id=virtio-disk0-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file.driver=iscsi,file.portal=example.org:6000,\
+ file.target=iqn.1992-01.com.example:storage,file.lun=1,file.transport=tcp,\
+-file.user=myname,file.password-secret=virtio-disk0-secret0,format=raw,if=none,\
+-id=drive-virtio-disk0 \
++file.user=myname,file.password-secret=virtio-disk0-auth-secret0,format=raw,\
++if=none,id=drive-virtio-disk0 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x2,drive=drive-virtio-disk0,\
+ id=virtio-disk0,bootindex=1 \
+--object secret,id=virtio-disk1-secret0,\
++-object secret,id=virtio-disk1-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive 'file=rbd:pool/image:id=myname:auth_supported=cephx\;none:\
+ mon_host=mon1.example.org\:6321\;mon2.example.org\:6322\;mon3.example.org\:\
+-6322,file.password-secret=virtio-disk1-secret0,format=raw,if=none,\
++6322,file.password-secret=virtio-disk1-auth-secret0,format=raw,if=none,\
+ id=drive-virtio-disk1' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk1,\
+ id=virtio-disk1 \
+diff --git a/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-latest.args
+index 057cd97273..182c8ab883 100644
+--- a/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-source-auth.x86_64-latest.args
+@@ -27,25 +27,25 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -no-acpi \
+ -boot strict=on \
+ -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+--object secret,id=libvirt-2-storage-secret0,\
++-object secret,id=libvirt-2-storage-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"iscsi","portal":"example.org:6000",\
+ "target":"iqn.1992-01.com.example:storage","lun":1,"transport":"tcp",\
+-"user":"myname","password-secret":"libvirt-2-storage-secret0",\
++"user":"myname","password-secret":"libvirt-2-storage-auth-secret0",\
+ "node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-2-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x2,drive=libvirt-2-format,\
+ id=virtio-disk0,bootindex=1 \
+--object secret,id=libvirt-1-storage-secret0,\
++-object secret,id=libvirt-1-storage-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"rbd","pool":"pool","image":"image",\
+ "server":[{"host":"mon1.example.org","port":"6321"},{"host":"mon2.example.org",\
+ "port":"6322"},{"host":"mon3.example.org","port":"6322"}],"user":"myname",\
+ "auth-client-required":["cephx","none"],\
+-"key-secret":"libvirt-1-storage-secret0","node-name":"libvirt-1-storage",\
++"key-secret":"libvirt-1-storage-auth-secret0","node-name":"libvirt-1-storage",\
+ "auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\
+ "file":"libvirt-1-storage"}' \
+diff --git a/tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args b/tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args
+index 3393a9129b..2d52c58dff 100644
+--- a/tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args
+@@ -46,7 +46,7 @@ id=virtio-disk1 \
+ "file":"libvirt-2-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=libvirt-2-format,\
+ id=virtio-disk2 \
+--object secret,id=libvirt-1-format-luks-secret0,\
++-object secret,id=libvirt-1-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"nvme","device":"0001:02:00.0","namespace":2,\
+@@ -54,7 +54,7 @@ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ "auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-1-format","read-only":false,\
+ "cache":{"direct":true,"no-flush":false},"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-1-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-1-format-encryption-secret0"},\
+ "file":"libvirt-1-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x7,drive=libvirt-1-format,\
+ id=virtio-disk3,write-cache=on \
+diff --git a/tests/qemuxml2argvdata/encrypted-disk-usage.args b/tests/qemuxml2argvdata/encrypted-disk-usage.args
+index 4522d2cb84..8641701293 100644
+--- a/tests/qemuxml2argvdata/encrypted-disk-usage.args
++++ b/tests/qemuxml2argvdata/encrypted-disk-usage.args
+@@ -27,11 +27,11 @@ path=/tmp/lib/domain--1-encryptdisk/monitor.sock,server,nowait \
+ -no-shutdown \
+ -no-acpi \
+ -usb \
+--object secret,id=virtio-disk0-luks-secret0,\
++-object secret,id=virtio-disk0-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk0-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk0-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk0 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+ id=virtio-disk0,bootindex=1 \
+diff --git a/tests/qemuxml2argvdata/encrypted-disk.args b/tests/qemuxml2argvdata/encrypted-disk.args
+index 4522d2cb84..8641701293 100644
+--- a/tests/qemuxml2argvdata/encrypted-disk.args
++++ b/tests/qemuxml2argvdata/encrypted-disk.args
+@@ -27,11 +27,11 @@ path=/tmp/lib/domain--1-encryptdisk/monitor.sock,server,nowait \
+ -no-shutdown \
+ -no-acpi \
+ -usb \
+--object secret,id=virtio-disk0-luks-secret0,\
++-object secret,id=virtio-disk0-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk0-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk0-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk0 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+ id=virtio-disk0,bootindex=1 \
+diff --git a/tests/qemuxml2argvdata/luks-disks-source-qcow2.args b/tests/qemuxml2argvdata/luks-disks-source-qcow2.args
+index ab1c864cf6..e7a29b2e03 100644
+--- a/tests/qemuxml2argvdata/luks-disks-source-qcow2.args
++++ b/tests/qemuxml2argvdata/luks-disks-source-qcow2.args
+@@ -27,53 +27,53 @@ path=/tmp/lib/domain--1-encryptdisk/monitor.sock,server,nowait \
+ -no-shutdown \
+ -no-acpi \
+ -usb \
+--object secret,id=virtio-disk0-luks-secret0,\
++-object secret,id=virtio-disk0-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk0-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk0-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk0 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+ id=virtio-disk0,bootindex=1 \
+--object secret,id=virtio-disk1-luks-secret0,\
++-object secret,id=virtio-disk1-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk2,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk1-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk1-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk1 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\
+ id=virtio-disk1 \
+--object secret,id=virtio-disk2-luks-secret0,\
++-object secret,id=virtio-disk2-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=iscsi://myname:AQCVn5hO6HzFAhAAq0NCv8jtJcIcE+HOBlMQ1A@example.org:\
+ 6000/iqn.1992-01.com.example%3Astorage/1,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk2-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk2-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk2 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk2,\
+ id=virtio-disk2 \
+--object secret,id=virtio-disk3-luks-secret0,\
++-object secret,id=virtio-disk3-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=iscsi://iscsi.example.com:3260/demo-target/3,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk3-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk3-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk3 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-virtio-disk3,\
+ id=virtio-disk3 \
+--object secret,id=virtio-disk4-luks-secret0,\
++-object secret,id=virtio-disk4-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive 'file=rbd:pool/image:auth_supported=none:mon_host=mon1.example.org\:\
+ 6321\;mon2.example.org\:6322\;mon3.example.org\:6322,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk4-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk4-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk4' \
+ -device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk4,\
+ id=virtio-disk4 \
+--object secret,id=virtio-disk5-luks-secret0,\
++-object secret,id=virtio-disk5-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk5,encrypt.format=luks,\
+-encrypt.key-secret=virtio-disk5-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=virtio-disk5-encryption-secret0,format=qcow2,if=none,\
+ id=drive-virtio-disk5 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x9,drive=drive-virtio-disk5,\
+ id=virtio-disk5 \
+diff --git a/tests/qemuxml2argvdata/luks-disks-source-qcow2.x86_64-latest.args b/tests/qemuxml2argvdata/luks-disks-source-qcow2.x86_64-latest.args
+index 021bcb6961..44e4c5698d 100644
+--- a/tests/qemuxml2argvdata/luks-disks-source-qcow2.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/luks-disks-source-qcow2.x86_64-latest.args
+@@ -28,53 +28,53 @@ file=/tmp/lib/domain--1-encryptdisk/master-key.aes \
+ -no-acpi \
+ -boot strict=on \
+ -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+--object secret,id=libvirt-7-format-luks-secret0,\
++-object secret,id=libvirt-7-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"file","filename":"/storage/guest_disks/encryptdisk",\
+ "node-name":"libvirt-7-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-7-format","read-only":false,"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-7-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-7-format-encryption-secret0"},\
+ "file":"libvirt-7-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=libvirt-7-format,\
+ id=virtio-disk0,bootindex=1 \
+--object secret,id=libvirt-6-format-luks-secret0,\
++-object secret,id=libvirt-6-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"file","filename":"/storage/guest_disks/encryptdisk2",\
+ "node-name":"libvirt-6-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-6-format","read-only":false,"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-6-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-6-format-encryption-secret0"},\
+ "file":"libvirt-6-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=libvirt-6-format,\
+ id=virtio-disk1 \
+--object secret,id=libvirt-5-storage-secret0,\
++-object secret,id=libvirt-5-storage-auth-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+--object secret,id=libvirt-5-format-luks-secret0,\
++-object secret,id=libvirt-5-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"iscsi","portal":"example.org:6000",\
+ "target":"iqn.1992-01.com.example:storage","lun":1,"transport":"tcp",\
+-"user":"myname","password-secret":"libvirt-5-storage-secret0",\
++"user":"myname","password-secret":"libvirt-5-storage-auth-secret0",\
+ "node-name":"libvirt-5-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-5-format","read-only":false,"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-5-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-5-format-encryption-secret0"},\
+ "file":"libvirt-5-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x2,drive=libvirt-5-format,\
+ id=virtio-disk2 \
+--object secret,id=libvirt-4-format-luks-secret0,\
++-object secret,id=libvirt-4-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"iscsi","portal":"iscsi.example.com:3260",\
+ "target":"demo-target","lun":3,"transport":"tcp",\
+ "node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-4-format","read-only":false,"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-4-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-4-format-encryption-secret0"},\
+ "file":"libvirt-4-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=libvirt-4-format,\
+ id=virtio-disk3 \
+--object secret,id=libvirt-3-format-luks-secret0,\
++-object secret,id=libvirt-3-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"rbd","pool":"pool","image":"image",\
+@@ -82,25 +82,25 @@ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ "port":"6322"},{"host":"mon3.example.org","port":"6322"}],\
+ "node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-3-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-3-format-encryption-secret0"},\
+ "file":"libvirt-3-storage"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x7,drive=libvirt-3-format,\
+ id=virtio-disk4 \
+--object secret,id=libvirt-2-format-luks-secret0,\
++-object secret,id=libvirt-2-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"file","filename":"/storage/guest_disks/base.qcow2",\
+ "node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-2-format","read-only":true,"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-2-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-2-format-encryption-secret0"},\
+ "file":"libvirt-2-storage","backing":null}' \
+--object secret,id=libvirt-1-format-luks-secret0,\
++-object secret,id=libvirt-1-format-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"file","filename":"/storage/guest_disks/encryptdisk5",\
+ "node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
+ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2",\
+-"encrypt":{"format":"luks","key-secret":"libvirt-1-format-luks-secret0"},\
++"encrypt":{"format":"luks","key-secret":"libvirt-1-format-encryption-secret0"},\
+ "file":"libvirt-1-storage","backing":"libvirt-2-format"}' \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x8,drive=libvirt-1-format,\
+ id=virtio-disk5 \
+diff --git a/tests/qemuxml2argvdata/luks-disks-source.args b/tests/qemuxml2argvdata/luks-disks-source.args
+index 4566f84ff1..e2bd559212 100644
+--- a/tests/qemuxml2argvdata/luks-disks-source.args
++++ b/tests/qemuxml2argvdata/luks-disks-source.args
+@@ -27,41 +27,45 @@ path=/tmp/lib/domain--1-encryptdisk/monitor.sock,server,nowait \
+ -no-shutdown \
+ -no-acpi \
+ -usb \
+--object secret,id=virtio-disk0-luks-secret0,\
++-object secret,id=virtio-disk0-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk,\
+-key-secret=virtio-disk0-luks-secret0,format=luks,if=none,id=drive-virtio-disk0 \
++key-secret=virtio-disk0-encryption-secret0,format=luks,if=none,\
++id=drive-virtio-disk0 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+ id=virtio-disk0,bootindex=1 \
+--object secret,id=virtio-disk1-luks-secret0,\
++-object secret,id=virtio-disk1-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk2,\
+-key-secret=virtio-disk1-luks-secret0,format=luks,if=none,id=drive-virtio-disk1 \
++key-secret=virtio-disk1-encryption-secret0,format=luks,if=none,\
++id=drive-virtio-disk1 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\
+ id=virtio-disk1 \
+--object secret,id=virtio-disk2-luks-secret0,\
++-object secret,id=virtio-disk2-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=iscsi://myname:AQCVn5hO6HzFAhAAq0NCv8jtJcIcE+HOBlMQ1A@example.org:\
+-6000/iqn.1992-01.com.example%3Astorage/1,key-secret=virtio-disk2-luks-secret0,\
+-format=luks,if=none,id=drive-virtio-disk2 \
++6000/iqn.1992-01.com.example%3Astorage/1,\
++key-secret=virtio-disk2-encryption-secret0,format=luks,if=none,\
++id=drive-virtio-disk2 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk2,\
+ id=virtio-disk2 \
+--object secret,id=virtio-disk3-luks-secret0,\
++-object secret,id=virtio-disk3-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=iscsi://iscsi.example.com:3260/demo-target/3,\
+-key-secret=virtio-disk3-luks-secret0,format=luks,if=none,id=drive-virtio-disk3 \
++key-secret=virtio-disk3-encryption-secret0,format=luks,if=none,\
++id=drive-virtio-disk3 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-virtio-disk3,\
+ id=virtio-disk3 \
+--object secret,id=virtio-disk4-luks-secret0,\
++-object secret,id=virtio-disk4-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive 'file=rbd:pool/image:auth_supported=none:mon_host=mon1.example.org\:\
+ 6321\;mon2.example.org\:6322\;mon3.example.org\:6322,\
+-key-secret=virtio-disk4-luks-secret0,format=luks,if=none,\
++key-secret=virtio-disk4-encryption-secret0,format=luks,if=none,\
+ id=drive-virtio-disk4' \
+ -device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk4,\
+ id=virtio-disk4 \
+diff --git a/tests/qemuxml2argvdata/luks-disks.args b/tests/qemuxml2argvdata/luks-disks.args
+index db1ae45b60..47626966f2 100644
+--- a/tests/qemuxml2argvdata/luks-disks.args
++++ b/tests/qemuxml2argvdata/luks-disks.args
+@@ -27,18 +27,20 @@ path=/tmp/lib/domain--1-encryptdisk/monitor.sock,server,nowait \
+ -no-shutdown \
+ -no-acpi \
+ -usb \
+--object secret,id=virtio-disk0-luks-secret0,\
++-object secret,id=virtio-disk0-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk,\
+-key-secret=virtio-disk0-luks-secret0,format=luks,if=none,id=drive-virtio-disk0 \
++key-secret=virtio-disk0-encryption-secret0,format=luks,if=none,\
++id=drive-virtio-disk0 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+ id=virtio-disk0,bootindex=1 \
+--object secret,id=virtio-disk1-luks-secret0,\
++-object secret,id=virtio-disk1-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/storage/guest_disks/encryptdisk2,\
+-key-secret=virtio-disk1-luks-secret0,format=luks,if=none,id=drive-virtio-disk1 \
++key-secret=virtio-disk1-encryption-secret0,format=luks,if=none,\
++id=drive-virtio-disk1 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\
+ id=virtio-disk1 \
+ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
+diff --git a/tests/qemuxml2argvdata/user-aliases.args b/tests/qemuxml2argvdata/user-aliases.args
+index 54463386cd..88e540bc3c 100644
+--- a/tests/qemuxml2argvdata/user-aliases.args
++++ b/tests/qemuxml2argvdata/user-aliases.args
+@@ -48,11 +48,11 @@ id=drive-ua-myDisk1,cache=none \
+ id=drive-ua-myDisk2 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-ua-myDisk2,id=ua-myDisk2,\
+ bootindex=1 \
+--object secret,id=ua-myEncryptedDisk1-luks-secret0,\
++-object secret,id=ua-myEncryptedDisk1-encryption-secret0,\
+ data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -drive file=/var/lib/libvirt/images/OtherDemo.img,encrypt.format=luks,\
+-encrypt.key-secret=ua-myEncryptedDisk1-luks-secret0,format=qcow2,if=none,\
++encrypt.key-secret=ua-myEncryptedDisk1-encryption-secret0,format=qcow2,if=none,\
+ id=drive-ua-myEncryptedDisk1 \
+ -device virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-ua-myEncryptedDisk1,\
+ id=ua-myEncryptedDisk1 \
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Fix-naming-of-alias-variables.patch b/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Fix-naming-of-alias-variables.patch
new file mode 100644
index 0000000..497e01d
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Fix-naming-of-alias-variables.patch
@@ -0,0 +1,60 @@
+From d1569e303d1132059ee4144371b9060ca59c445a Mon Sep 17 00:00:00 2001
+Message-Id: <d1569e303d1132059ee4144371b9060ca59c445a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:50 +0100
+Subject: [PATCH] qemuDomainSecretStorageSourcePrepare: Fix naming of alias
+ variables
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The naming of the variables was tied to what they are used for not what
+the alias represents. Since we'll need to use some of the aliases for
+another type of secrets fix the name so that it makes sense.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit b05322fc0376670edd54f9689ac8cda852581edc)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <ecb2064811e2bab26024bdd8dd90dafc4c23d3eb.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index af23079d5d..6221e7090f 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1759,8 +1759,8 @@ qemuDomainDiskHasEncryptionSecret(virStorageSourcePtr src)
+ static int
+ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+                                      virStorageSourcePtr src,
+-                                     const char *authalias,
+-                                     const char *encalias)
++                                     const char *aliasprotocol,
++                                     const char *aliasformat)
+ {
+     qemuDomainStorageSourcePrivatePtr srcPriv;
+     bool iscsiHasPS = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_ISCSI_PASSWORD_SECRET);
+@@ -1787,7 +1787,7 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+                                                             src->auth->username,
+                                                             &src->auth->seclookupdef);
+         } else {
+-            srcPriv->secinfo = qemuDomainSecretAESSetupFromSecret(priv, authalias,
++            srcPriv->secinfo = qemuDomainSecretAESSetupFromSecret(priv, aliasprotocol,
+                                                                   usageType,
+                                                                   src->auth->username,
+                                                                   &src->auth->seclookupdef,
+@@ -1799,7 +1799,7 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+     }
+ 
+     if (hasEnc) {
+-        if (!(srcPriv->encinfo = qemuDomainSecretAESSetupFromSecret(priv, encalias,
++        if (!(srcPriv->encinfo = qemuDomainSecretAESSetupFromSecret(priv, aliasformat,
+                                                                     VIR_SECRET_USAGE_TYPE_VOLUME,
+                                                                     NULL,
+                                                                     &src->encryption->secrets[0]->seclookupdef,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Setup-secret-for-http-cookies.patch b/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Setup-secret-for-http-cookies.patch
new file mode 100644
index 0000000..f537f21
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSecretStorageSourcePrepare-Setup-secret-for-http-cookies.patch
@@ -0,0 +1,90 @@
+From 899a3adeded6a120a9d8f1298af482247f4696fa Mon Sep 17 00:00:00 2001
+Message-Id: <899a3adeded6a120a9d8f1298af482247f4696fa@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:03 +0100
+Subject: [PATCH] qemuDomainSecretStorageSourcePrepare: Setup secret for http
+ cookies
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QEMU's curl driver requires the cookies concatenated and allows themi to
+be passed in via a secret. Prepare the value for the secret and encrypt
+it.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 877cd358873982d4d6a36b7e65a8605c663e5765)
+
+Conflicts:
+  src/qemu/qemu_domain.c:
+  Refactor to virBufferTrim not backported.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <e61490666a540093eac6c219c07a12c6b7d4c72a.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 33 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 32 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 9391bc37e0..cc47e7a2f0 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -1740,6 +1740,30 @@ qemuDomainDiskHasEncryptionSecret(virStorageSourcePtr src)
+ }
+ 
+ 
++static qemuDomainSecretInfoPtr
++qemuDomainSecretStorageSourcePrepareCookies(qemuDomainObjPrivatePtr priv,
++                                            virStorageSourcePtr src,
++                                            const char *aliasprotocol)
++{
++    g_autofree char *secretalias = qemuAliasForSecret(aliasprotocol, "httpcookie");
++    g_autofree char *cookies = NULL;
++    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
++    size_t i;
++
++    for (i = 0; i < src->ncookies; i++) {
++        virStorageNetCookieDefPtr cookie = src->cookies[i];
++
++        virBufferAsprintf(&buf, "%s=%s; ", cookie->name, cookie->value);
++    }
++
++    virBufferTrim(&buf, "; ", -1);
++    cookies = virBufferContentAndReset(&buf);
++
++    return qemuDomainSecretAESSetup(priv, secretalias, NULL,
++                                    (uint8_t *) cookies, strlen(cookies));
++}
++
++
+ /**
+  * qemuDomainSecretStorageSourcePrepare:
+  * @priv: domain private object
+@@ -1765,7 +1789,7 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+     bool hasAuth = qemuDomainStorageSourceHasAuth(src);
+     bool hasEnc = qemuDomainDiskHasEncryptionSecret(src);
+ 
+-    if (!hasAuth && !hasEnc)
++    if (!hasAuth && !hasEnc && src->ncookies == 0)
+         return 0;
+ 
+     if (!(src->privateData = qemuDomainStorageSourcePrivateNew()))
+@@ -1805,6 +1829,13 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
+               return -1;
+     }
+ 
++    if (src->ncookies &&
++        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV) &&
++        !(srcPriv->httpcookie = qemuDomainSecretStorageSourcePrepareCookies(priv,
++                                                                            src,
++                                                                            aliasprotocol)))
++        return -1;
++
+     return 0;
+ }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuDomainSnapshotDiskPrepareOne-Don-t-load-the-relative-path-with-blockdev.patch b/SOURCES/libvirt-qemuDomainSnapshotDiskPrepareOne-Don-t-load-the-relative-path-with-blockdev.patch
new file mode 100644
index 0000000..c9a9567
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSnapshotDiskPrepareOne-Don-t-load-the-relative-path-with-blockdev.patch
@@ -0,0 +1,42 @@
+From 84b0e095a5dd885a532a4108e95adea0b5dca184 Mon Sep 17 00:00:00 2001
+Message-Id: <84b0e095a5dd885a532a4108e95adea0b5dca184@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:42 +0200
+Subject: [PATCH] qemuDomainSnapshotDiskPrepareOne: Don't load the relative
+ path with blockdev
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since we are refreshing the relative paths when doing the blockjobs we
+no longer need to load them upfront when doing the snapshot.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 2ace7a87a8aced68c2504fd4dd4e2df4302c3eeb)
+https://bugzilla.redhat.com/show_bug.cgi?id=1818655
+Message-Id: <7763b0a5b018f04230220b81038e60dc12706799.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_driver.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 27a50f60ef..4701a1905e 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15441,8 +15441,9 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver,
+         dd->initialized = true;
+ 
+         /* relative backing store paths need to be updated so that relative
+-         * block commit still works */
+-        if (reuse) {
++         * block commit still works. With blockdev we must update it when doing
++         * commit anyways so it's skipped here */
++        if (reuse && !blockdev) {
+             if (supportsBacking) {
+                 g_autofree char *backingStoreStr = NULL;
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuDomainSnapshotDiskPrepareOne-Fix-logic-of-relative-backing-store-update.patch b/SOURCES/libvirt-qemuDomainSnapshotDiskPrepareOne-Fix-logic-of-relative-backing-store-update.patch
new file mode 100644
index 0000000..29d41fb
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainSnapshotDiskPrepareOne-Fix-logic-of-relative-backing-store-update.patch
@@ -0,0 +1,78 @@
+From a3a9d320ac8cde96c976378b92dc4fcf553d9287 Mon Sep 17 00:00:00 2001
+Message-Id: <a3a9d320ac8cde96c976378b92dc4fcf553d9287@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 3 Apr 2020 14:32:55 +0200
+Subject: [PATCH] qemuDomainSnapshotDiskPrepareOne: Fix logic of relative
+ backing store update
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 2ace7a87a8aced68c250 introduced a logic bug by an improperly
+modified condition where we'd skip to the else branch when reusing of
+external images was requested and blockdev is available.
+
+The original intentions were to skip the backing store update with
+blockdev.
+
+Fix it by only asserting the boolean which was used to track whether we
+support update of the backing store only when blockdev is not present
+along with the appropriate rename.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1820016
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit ae64a75a8713cf14b25b40078766c2da93e001ff)
+Message-Id: <c4ce185df3fb6d88aa7282d523b0a5c7ccff2aad.1585916255.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 4701a1905e..26215f8d6a 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15403,7 +15403,7 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver,
+ {
+     virDomainDiskDefPtr persistdisk;
+     bool supportsCreate;
+-    bool supportsBacking;
++    bool updateRelativeBacking = false;
+ 
+     dd->disk = disk;
+ 
+@@ -15432,19 +15432,22 @@ qemuDomainSnapshotDiskPrepareOne(virQEMUDriverPtr driver,
+     }
+ 
+     supportsCreate = virStorageFileSupportsCreate(dd->src);
+-    supportsBacking = virStorageFileSupportsBackingChainTraversal(dd->src);
+ 
+-    if (supportsCreate || supportsBacking) {
++    /* relative backing store paths need to be updated so that relative
++     * block commit still works. With blockdev we must update it when doing
++     * commit anyways so it's skipped here */
++    if (!blockdev &&
++        virStorageFileSupportsBackingChainTraversal(dd->src))
++        updateRelativeBacking = true;
++
++    if (supportsCreate || updateRelativeBacking) {
+         if (qemuDomainStorageFileInit(driver, vm, dd->src, NULL) < 0)
+             return -1;
+ 
+         dd->initialized = true;
+ 
+-        /* relative backing store paths need to be updated so that relative
+-         * block commit still works. With blockdev we must update it when doing
+-         * commit anyways so it's skipped here */
+-        if (reuse && !blockdev) {
+-            if (supportsBacking) {
++        if (reuse) {
++            if (updateRelativeBacking) {
+                 g_autofree char *backingStoreStr = NULL;
+ 
+                 if (virStorageFileGetBackingStoreStr(dd->src, &backingStoreStr) < 0)
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuDomainValidateStorageSource-Reject-unsupported-slices.patch b/SOURCES/libvirt-qemuDomainValidateStorageSource-Reject-unsupported-slices.patch
new file mode 100644
index 0000000..1401c13
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainValidateStorageSource-Reject-unsupported-slices.patch
@@ -0,0 +1,52 @@
+From 038231283c69bf7c9c9fadd2157f53f8b3f719d3 Mon Sep 17 00:00:00 2001
+Message-Id: <038231283c69bf7c9c9fadd2157f53f8b3f719d3@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:17 +0100
+Subject: [PATCH] qemuDomainValidateStorageSource: Reject unsupported slices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We support explicit storage slices only when using blockdev. Storage
+slices expressed via the backing store string are left to qemu to
+open correctly.
+
+Reject storage slices configured via the XML for non-blockdev usage.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit a6eeda986e458e6746268069b1f610c27e89d6e2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <10cfef14fcb49c7daef4f869d622ebdf3aa6a4d5.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index cf069e2b79..7b414b79c7 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -6936,6 +6936,18 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src,
+         return -1;
+     }
+ 
++    if (src->sliceStorage) {
++        /* In pre-blockdev era we can't configure the slice so we can allow them
++         * only for detected backing store entries as they are populated
++         * from a place that qemu would be able to read */
++        if (!src->detected &&
++            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("storage slice is not supported by this QEMU binary"));
++            return -1;
++        }
++    }
++
+     return 0;
+ }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuDomainValidateStorageSource-Validate-new-network-storage-parameters.patch b/SOURCES/libvirt-qemuDomainValidateStorageSource-Validate-new-network-storage-parameters.patch
new file mode 100644
index 0000000..e3e7b54
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainValidateStorageSource-Validate-new-network-storage-parameters.patch
@@ -0,0 +1,113 @@
+From 5e76dbcf3922074cbf708c3ffe8adc6e108bac76 Mon Sep 17 00:00:00 2001
+Message-Id: <5e76dbcf3922074cbf708c3ffe8adc6e108bac76@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:59 +0100
+Subject: [PATCH] qemuDomainValidateStorageSource: Validate new network storage
+ parameters
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Ensure that the new fields are allowed only when -blockdev is used or
+when they are in the detected part of the backing chain where qemu will
+handle them internally.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit c1409e308f8e10f28ff4977309b2573a1a2d8763)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <3b47d0ff8f492506588d6ddeda49d2e4e43cc5aa.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 75 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 75 insertions(+)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 65df463acc..2920e699f6 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -6953,6 +6953,81 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src,
+         }
+     }
+ 
++    if (src->sslverify != VIR_TRISTATE_BOOL_ABSENT) {
++        if (actualType != VIR_STORAGE_TYPE_NETWORK ||
++            (src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_FTPS)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("ssl verification is supported only with HTTPS/FTPS protocol"));
++            return -1;
++        }
++
++        if (!src->detected &&
++            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("ssl verification setting is not supported by this QEMU binary"));
++            return -1;
++        }
++    }
++
++    if (src->ncookies > 0) {
++        if (actualType != VIR_STORAGE_TYPE_NETWORK ||
++            (src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("http cookies are supported only with HTTP(S) protocol"));
++            return -1;
++        }
++
++        if (!src->detected &&
++            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("http cookies are not supported by this QEMU binary"));
++            return -1;
++        }
++
++        if (virStorageSourceNetCookiesValidate(src) < 0)
++            return -1;
++    }
++
++    if (src->readahead > 0) {
++        if (actualType != VIR_STORAGE_TYPE_NETWORK ||
++            (src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_FTP &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_FTPS)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("readaehad is supported only with HTTP(S)/FTP(s) protocols"));
++            return -1;
++        }
++
++        if (!src->detected &&
++            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("readahead setting is not supported with this QEMU binary"));
++            return -1;
++        }
++    }
++
++    if (src->timeout > 0) {
++        if (actualType != VIR_STORAGE_TYPE_NETWORK ||
++            (src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_FTP &&
++             src->protocol != VIR_STORAGE_NET_PROTOCOL_FTPS)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("timeout is supported only with HTTP(S)/FTP(s) protocols"));
++            return -1;
++        }
++
++        if (!src->detected &&
++            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
++            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                           _("timeout setting is not supported with this QEMU binary"));
++            return -1;
++        }
++    }
++
+     return 0;
+ }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuExtDevicesStart-pass-logManager.patch b/SOURCES/libvirt-qemuExtDevicesStart-pass-logManager.patch
new file mode 100644
index 0000000..1f2000e
--- /dev/null
+++ b/SOURCES/libvirt-qemuExtDevicesStart-pass-logManager.patch
@@ -0,0 +1,67 @@
+From 27ae8a1488afd910dccd1f76d1fa31a3c8560d04 Mon Sep 17 00:00:00 2001
+Message-Id: <27ae8a1488afd910dccd1f76d1fa31a3c8560d04@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:36 +0100
+Subject: [PATCH] qemuExtDevicesStart: pass logManager
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Pass logManager to qemuExtDevicesStart for future usage.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit b164eac5e1d4ebe17e673f0427b70f862a670f94)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <44ec9897e79f7482dc22611526a154915bb02cdb.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_extdevice.c | 1 +
+ src/qemu/qemu_extdevice.h | 1 +
+ src/qemu/qemu_process.c   | 4 +++-
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
+index 9c0c0fd573..7f3bb104d9 100644
+--- a/src/qemu/qemu_extdevice.c
++++ b/src/qemu/qemu_extdevice.c
+@@ -153,6 +153,7 @@ qemuExtDevicesCleanupHost(virQEMUDriverPtr driver,
+ int
+ qemuExtDevicesStart(virQEMUDriverPtr driver,
+                     virDomainObjPtr vm,
++                    virLogManagerPtr logManager G_GNUC_UNUSED,
+                     bool incomingMigration)
+ {
+     virDomainDefPtr def = vm->def;
+diff --git a/src/qemu/qemu_extdevice.h b/src/qemu/qemu_extdevice.h
+index 5cf777ab4b..df29968e16 100644
+--- a/src/qemu/qemu_extdevice.h
++++ b/src/qemu/qemu_extdevice.h
+@@ -46,6 +46,7 @@ void qemuExtDevicesCleanupHost(virQEMUDriverPtr driver,
+ 
+ int qemuExtDevicesStart(virQEMUDriverPtr driver,
+                         virDomainObjPtr vm,
++                        virLogManagerPtr logManager,
+                         bool incomingMigration)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+     G_GNUC_WARN_UNUSED_RESULT;
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index a7bbab9e56..0476f18517 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -6705,7 +6705,9 @@ qemuProcessLaunch(virConnectPtr conn,
+     if (qemuProcessGenID(vm, flags) < 0)
+         goto cleanup;
+ 
+-    if (qemuExtDevicesStart(driver, vm, incoming != NULL) < 0)
++    if (qemuExtDevicesStart(driver, vm,
++                            qemuDomainLogContextGetManager(logCtxt),
++                            incoming != NULL) < 0)
+         goto cleanup;
+ 
+     VIR_DEBUG("Building emulator command line");
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuMigrationCookieAddNBD-Exit-early-if-there-are-no-disks.patch b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Exit-early-if-there-are-no-disks.patch
new file mode 100644
index 0000000..f9d3ab4
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Exit-early-if-there-are-no-disks.patch
@@ -0,0 +1,56 @@
+From 44d255b6cc7315537e66f1d97e4893e321b694b8 Mon Sep 17 00:00:00 2001
+Message-Id: <44d255b6cc7315537e66f1d97e4893e321b694b8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:02 +0100
+Subject: [PATCH] qemuMigrationCookieAddNBD: Exit early if there are no disks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Refactor the logic to skip the body of the function if there's nothing
+to do.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit bdff9d4513694da8d9b2bb60a1f808fb1c286388)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <b12c9b8c4ca78e848e43ab4ae7706a5694cfb49c.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_cookie.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
+index 299bf17c9e..73ae815818 100644
+--- a/src/qemu/qemu_migration_cookie.c
++++ b/src/qemu/qemu_migration_cookie.c
+@@ -464,8 +464,13 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+     if (VIR_ALLOC(mig->nbd) < 0)
+         return -1;
+ 
+-    if (vm->def->ndisks &&
+-        VIR_ALLOC_N(mig->nbd->disks, vm->def->ndisks) < 0)
++    mig->nbd->port = priv->nbdPort;
++    mig->flags |= QEMU_MIGRATION_COOKIE_NBD;
++
++    if (vm->def->ndisks == 0)
++        return 0;
++
++    if (VIR_ALLOC_N(mig->nbd->disks, vm->def->ndisks) < 0)
+         return -1;
+     mig->nbd->ndisks = 0;
+ 
+@@ -496,9 +501,6 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+         mig->nbd->ndisks++;
+     }
+ 
+-    mig->nbd->port = priv->nbdPort;
+-    mig->flags |= QEMU_MIGRATION_COOKIE_NBD;
+-
+     ret = 0;
+  cleanup:
+     virHashFree(stats);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMigrationCookieAddNBD-Fix-filling-of-capacity-when-blockdev-is-used.patch b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Fix-filling-of-capacity-when-blockdev-is-used.patch
new file mode 100644
index 0000000..08304a4
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Fix-filling-of-capacity-when-blockdev-is-used.patch
@@ -0,0 +1,74 @@
+From 0c415216f2005b3c33379db3b37fb9c03e30a658 Mon Sep 17 00:00:00 2001
+Message-Id: <0c415216f2005b3c33379db3b37fb9c03e30a658@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:08 +0100
+Subject: [PATCH] qemuMigrationCookieAddNBD: Fix filling of 'capacity' when
+ blockdev is used
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With -blockdev we must look up via the nodename rather than the 'drive'
+alias which is not present any more.
+
+This fixes the pre-creation of storage volumes on migration with
+non-shared storage.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit b9e87908dbcff23cc3fdf3d8629849560d2e7268)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <60eb81e2479cac5fc9ae3cc40abb106e0a127e6e.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_cookie.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
+index 734d95f4f1..a5a9edffc3 100644
+--- a/src/qemu/qemu_migration_cookie.c
++++ b/src/qemu/qemu_migration_cookie.c
+@@ -455,6 +455,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     g_autoptr(virHashTable) stats = virHashNew(virHashValueFree);
++    bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+     size_t i;
+     int rc;
+ 
+@@ -474,7 +475,10 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+ 
+     if (qemuDomainObjEnterMonitorAsync(driver, vm, priv->job.asyncJob) < 0)
+         return -1;
+-    rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false);
++    if (blockdev)
++        rc = qemuMonitorBlockStatsUpdateCapacityBlockdev(priv->mon, stats);
++    else
++        rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false);
+     if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+         return -1;
+ 
+@@ -482,9 +486,14 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+         virDomainDiskDefPtr disk = vm->def->disks[i];
+         qemuBlockStats *entry;
+ 
+-        if (!disk->info.alias ||
+-            !(entry = virHashLookup(stats, disk->info.alias)))
+-            continue;
++        if (blockdev) {
++            if (!(entry = virHashLookup(stats, disk->src->nodeformat)))
++                continue;
++        } else {
++            if (!disk->info.alias ||
++                !(entry = virHashLookup(stats, disk->info.alias)))
++                continue;
++        }
+ 
+         mig->nbd->disks[mig->nbd->ndisks].target = g_strdup(disk->dst);
+         mig->nbd->disks[mig->nbd->ndisks].capacity = entry->capacity;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMigrationCookieAddNBD-Move-monitor-call-out-of-the-loop.patch b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Move-monitor-call-out-of-the-loop.patch
new file mode 100644
index 0000000..c78172d
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Move-monitor-call-out-of-the-loop.patch
@@ -0,0 +1,65 @@
+From fe9aca2a6860fbb84faed53b10fabc95b1c73a7a Mon Sep 17 00:00:00 2001
+Message-Id: <fe9aca2a6860fbb84faed53b10fabc95b1c73a7a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:05 +0100
+Subject: [PATCH] qemuMigrationCookieAddNBD: Move monitor call out of the loop
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The data is gathered only once so we can move the whole block which
+fetches the data out of the loop and get rid of the logic which
+prevents multiple calls.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 464345e153b805467a22fca4615350e992e6d470)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <4c88d7cb39985ba204cd126d6adb740f58d19d6f.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_cookie.c | 23 +++++++++--------------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
+index 1c3de13983..33ab6cb7a5 100644
+--- a/src/qemu/qemu_migration_cookie.c
++++ b/src/qemu/qemu_migration_cookie.c
+@@ -472,24 +472,19 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+     mig->nbd->disks = g_new0(struct qemuMigrationCookieNBDDisk, vm->def->ndisks);
+     mig->nbd->ndisks = 0;
+ 
++    if (!(stats = virHashCreate(10, virHashValueFree)))
++        goto cleanup;
++
++    if (qemuDomainObjEnterMonitorAsync(driver, vm, priv->job.asyncJob) < 0)
++        goto cleanup;
++    rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false);
++    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
++        goto cleanup;
++
+     for (i = 0; i < vm->def->ndisks; i++) {
+         virDomainDiskDefPtr disk = vm->def->disks[i];
+         qemuBlockStats *entry;
+ 
+-        if (!stats) {
+-            if (!(stats = virHashCreate(10, virHashValueFree)))
+-                goto cleanup;
+-
+-            if (qemuDomainObjEnterMonitorAsync(driver, vm,
+-                                               priv->job.asyncJob) < 0)
+-                goto cleanup;
+-            rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false);
+-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+-                goto cleanup;
+-            if (rc < 0)
+-                goto cleanup;
+-        }
+-
+         if (!disk->info.alias ||
+             !(entry = virHashLookup(stats, disk->info.alias)))
+             continue;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMigrationCookieAddNBD-Remove-ret-variable-and-cleanup-label.patch b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Remove-ret-variable-and-cleanup-label.patch
new file mode 100644
index 0000000..e123f21
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Remove-ret-variable-and-cleanup-label.patch
@@ -0,0 +1,61 @@
+From ea4867bfe2c2990f62c3158b875f56dbf540f372 Mon Sep 17 00:00:00 2001
+Message-Id: <ea4867bfe2c2990f62c3158b875f56dbf540f372@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:07 +0100
+Subject: [PATCH] qemuMigrationCookieAddNBD: Remove 'ret' variable and
+ 'cleanup' label
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit d409411213152d204b85daf05468c4f7f17c1616)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <1feef9fdcf0e2f1178e8136192d91a6558cc6149.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_cookie.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
+index 968a9b589c..734d95f4f1 100644
+--- a/src/qemu/qemu_migration_cookie.c
++++ b/src/qemu/qemu_migration_cookie.c
+@@ -456,7 +456,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     g_autoptr(virHashTable) stats = virHashNew(virHashValueFree);
+     size_t i;
+-    int ret = -1, rc;
++    int rc;
+ 
+     /* It is not a bug if there already is a NBD data */
+     qemuMigrationCookieNBDFree(mig->nbd);
+@@ -473,10 +473,10 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+     mig->nbd->ndisks = 0;
+ 
+     if (qemuDomainObjEnterMonitorAsync(driver, vm, priv->job.asyncJob) < 0)
+-        goto cleanup;
++        return -1;
+     rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false);
+     if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+-        goto cleanup;
++        return -1;
+ 
+     for (i = 0; i < vm->def->ndisks; i++) {
+         virDomainDiskDefPtr disk = vm->def->disks[i];
+@@ -491,9 +491,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+         mig->nbd->ndisks++;
+     }
+ 
+-    ret = 0;
+- cleanup:
+-    return ret;
++    return 0;
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMigrationCookieAddNBD-Use-glib-memory-allocators.patch b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Use-glib-memory-allocators.patch
new file mode 100644
index 0000000..c212e54
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Use-glib-memory-allocators.patch
@@ -0,0 +1,47 @@
+From b3f938e7c0907ea9222827550fd3dfa0c1f1e1fd Mon Sep 17 00:00:00 2001
+Message-Id: <b3f938e7c0907ea9222827550fd3dfa0c1f1e1fd@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:04 +0100
+Subject: [PATCH] qemuMigrationCookieAddNBD: Use glib memory allocators
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 8efeeb59a6e76fa9515deb7d3d26ae570e0fb7a7)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <5872c474b94250bb0994748d9b769883ecbea6f8.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_cookie.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
+index 73ae815818..1c3de13983 100644
+--- a/src/qemu/qemu_migration_cookie.c
++++ b/src/qemu/qemu_migration_cookie.c
+@@ -461,8 +461,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+     /* It is not a bug if there already is a NBD data */
+     qemuMigrationCookieNBDFree(mig->nbd);
+ 
+-    if (VIR_ALLOC(mig->nbd) < 0)
+-        return -1;
++    mig->nbd = g_new0(qemuMigrationCookieNBD, 1);
+ 
+     mig->nbd->port = priv->nbdPort;
+     mig->flags |= QEMU_MIGRATION_COOKIE_NBD;
+@@ -470,8 +469,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+     if (vm->def->ndisks == 0)
+         return 0;
+ 
+-    if (VIR_ALLOC_N(mig->nbd->disks, vm->def->ndisks) < 0)
+-        return -1;
++    mig->nbd->disks = g_new0(struct qemuMigrationCookieNBDDisk, vm->def->ndisks);
+     mig->nbd->ndisks = 0;
+ 
+     for (i = 0; i < vm->def->ndisks; i++) {
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMigrationCookieAddNBD-Use-virHashNew-and-automatic-freeing-of-virHashTablePtr.patch b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Use-virHashNew-and-automatic-freeing-of-virHashTablePtr.patch
new file mode 100644
index 0000000..c6850bd
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationCookieAddNBD-Use-virHashNew-and-automatic-freeing-of-virHashTablePtr.patch
@@ -0,0 +1,57 @@
+From 3e6ecac77da1e9f302f81a68dded6bd226430682 Mon Sep 17 00:00:00 2001
+Message-Id: <3e6ecac77da1e9f302f81a68dded6bd226430682@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:06 +0100
+Subject: [PATCH] qemuMigrationCookieAddNBD: Use virHashNew and automatic
+ freeing of virHashTablePtr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Swithc to the helper which doesn't require checking of the return value.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 45eefb2c78cfe2b14d5bc5fb150ffbed18991fde)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <06db6f97ebb2266ea197ce13cbc9051e4c839fdf.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_cookie.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
+index 33ab6cb7a5..968a9b589c 100644
+--- a/src/qemu/qemu_migration_cookie.c
++++ b/src/qemu/qemu_migration_cookie.c
+@@ -454,7 +454,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+                           virDomainObjPtr vm)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+-    virHashTablePtr stats = NULL;
++    g_autoptr(virHashTable) stats = virHashNew(virHashValueFree);
+     size_t i;
+     int ret = -1, rc;
+ 
+@@ -472,9 +472,6 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+     mig->nbd->disks = g_new0(struct qemuMigrationCookieNBDDisk, vm->def->ndisks);
+     mig->nbd->ndisks = 0;
+ 
+-    if (!(stats = virHashCreate(10, virHashValueFree)))
+-        goto cleanup;
+-
+     if (qemuDomainObjEnterMonitorAsync(driver, vm, priv->job.asyncJob) < 0)
+         goto cleanup;
+     rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false);
+@@ -496,7 +493,6 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
+ 
+     ret = 0;
+  cleanup:
+-    virHashFree(stats);
+     return ret;
+ }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMigrationCookieNBD-Extract-embedded-struct.patch b/SOURCES/libvirt-qemuMigrationCookieNBD-Extract-embedded-struct.patch
new file mode 100644
index 0000000..22753ff
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationCookieNBD-Extract-embedded-struct.patch
@@ -0,0 +1,52 @@
+From 92ec9a02d57b18eac3abc33e0807cd70c6bb46c5 Mon Sep 17 00:00:00 2001
+Message-Id: <92ec9a02d57b18eac3abc33e0807cd70c6bb46c5@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:03 +0100
+Subject: [PATCH] qemuMigrationCookieNBD: Extract embedded struct
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Extract the struct so that it's type has a name.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 3093822d1d8e3bbd01ea59f35a9fea1228f9268f)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <e05be367f0869dbbf726cea7e91925fc48bb683f.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_cookie.h | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h
+index 20e1ed60ca..1e88684589 100644
+--- a/src/qemu/qemu_migration_cookie.h
++++ b/src/qemu/qemu_migration_cookie.h
+@@ -84,16 +84,18 @@ struct _qemuMigrationCookieNetwork {
+     qemuMigrationCookieNetDataPtr net;
+ };
+ 
++struct qemuMigrationCookieNBDDisk {
++    char *target;                   /* Disk target */
++    unsigned long long capacity;    /* And its capacity */
++};
++
+ typedef struct _qemuMigrationCookieNBD qemuMigrationCookieNBD;
+ typedef qemuMigrationCookieNBD *qemuMigrationCookieNBDPtr;
+ struct _qemuMigrationCookieNBD {
+     int port; /* on which port does NBD server listen for incoming data */
+ 
+     size_t ndisks;  /* Number of items in @disk array */
+-    struct {
+-        char *target;                   /* Disk target */
+-        unsigned long long capacity;    /* And its capacity */
+-    } *disks;
++    struct qemuMigrationCookieNBDDisk *disks;
+ };
+ 
+ typedef struct _qemuMigrationCookieCaps qemuMigrationCookieCaps;
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMigrationParamsResetTLS-Adapt-to-modern-memory-management.patch b/SOURCES/libvirt-qemuMigrationParamsResetTLS-Adapt-to-modern-memory-management.patch
new file mode 100644
index 0000000..cbecf93
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationParamsResetTLS-Adapt-to-modern-memory-management.patch
@@ -0,0 +1,59 @@
+From f3179ed39f95ec25c9d4c6ec8ef67d54abd6c5ad Mon Sep 17 00:00:00 2001
+Message-Id: <f3179ed39f95ec25c9d4c6ec8ef67d54abd6c5ad@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:42 +0100
+Subject: [PATCH] qemuMigrationParamsResetTLS: Adapt to modern memory
+ management
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use g_autofree instead of VIR_FREE and delete the comment mentioning
+possible failure to allocate memory.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 3b6110655013e9ae0ee933406c1ff0c7af2d4734)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <86a9b24e53e4de2830c6ff33639837b14f20d282.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_params.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
+index f61796713f..60b41e287a 100644
+--- a/src/qemu/qemu_migration_params.c
++++ b/src/qemu/qemu_migration_params.c
+@@ -1074,8 +1074,8 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver,
+                             qemuMigrationParamsPtr origParams,
+                             unsigned long apiFlags)
+ {
+-    char *tlsAlias = NULL;
+-    char *secAlias = NULL;
++    g_autofree char *tlsAlias = NULL;
++    g_autofree char *secAlias = NULL;
+ 
+     /* There's nothing to do if QEMU does not support TLS migration or we were
+      * not asked to enable it. */
+@@ -1083,17 +1083,11 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver,
+         !(apiFlags & VIR_MIGRATE_TLS))
+         return;
+ 
+-    /* NB: If either or both fail to allocate memory we can still proceed
+-     *     since the next time we migrate another deletion attempt will be
+-     *     made after successfully generating the aliases. */
+     tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE);
+     secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false);
+ 
+     qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias);
+     g_clear_pointer(&QEMU_DOMAIN_PRIVATE(vm)->migSecinfo, qemuDomainSecretInfoFree);
+-
+-    VIR_FREE(tlsAlias);
+-    VIR_FREE(secAlias);
+ }
+ 
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuMigrationParamsResetTLS-Fix-comment.patch b/SOURCES/libvirt-qemuMigrationParamsResetTLS-Fix-comment.patch
new file mode 100644
index 0000000..0360a14
--- /dev/null
+++ b/SOURCES/libvirt-qemuMigrationParamsResetTLS-Fix-comment.patch
@@ -0,0 +1,39 @@
+From 8e6004601d38241aafb9a3f04cc572bb4eb5e4c5 Mon Sep 17 00:00:00 2001
+Message-Id: <8e6004601d38241aafb9a3f04cc572bb4eb5e4c5@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:11:43 +0100
+Subject: [PATCH] qemuMigrationParamsResetTLS: Fix comment
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The comment mentioned that the function resets migration params, but
+that is not true as of commit eb54cb473a8d140e0dd4a7bd42e8bcd72b056368
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 7a34e04d82ba61613c5fa1f8c265cbf2c0276b39)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <3d8e22ae485964827bf28bd1d1529e7757b2350c.1584391726.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_migration_params.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
+index 60b41e287a..0a3b0f8741 100644
+--- a/src/qemu/qemu_migration_params.c
++++ b/src/qemu/qemu_migration_params.c
+@@ -1065,7 +1065,7 @@ qemuMigrationParamsDisableTLS(virDomainObjPtr vm,
+  * @apiFlags: API flags used to start the migration
+  *
+  * Deconstruct all the setup possibly done for TLS - delete the TLS and
+- * security objects, free the secinfo, and reset the migration params to "".
++ * security objects and free the secinfo
+  */
+ static void
+ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuMonitorBlockdevAdd-Take-double-pointer-argument.patch b/SOURCES/libvirt-qemuMonitorBlockdevAdd-Take-double-pointer-argument.patch
new file mode 100644
index 0000000..bcec2a6
--- /dev/null
+++ b/SOURCES/libvirt-qemuMonitorBlockdevAdd-Take-double-pointer-argument.patch
@@ -0,0 +1,146 @@
+From f5fe33504d90bf47d3f766470a04b16eca56bfd8 Mon Sep 17 00:00:00 2001
+Message-Id: <f5fe33504d90bf47d3f766470a04b16eca56bfd8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:04 +0100
+Subject: [PATCH] qemuMonitorBlockdevAdd: Take double pointer argument
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Modify qemuMonitorBlockdevAdd so that it takes a double pointer for the
+@props argument so that it's cleared inside the call. This allows
+writing cleaner callers.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit db57e9daf5ab25bd7a1f377c4dde160b0896ad64)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798366
+Message-Id: <1b4429b82826f69f18b506b8fbd648ff0ac70c38.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c        | 14 ++------------
+ src/qemu/qemu_monitor.c      | 16 ++++++----------
+ src/qemu/qemu_monitor.h      |  2 +-
+ src/qemu/qemu_monitor_json.c |  5 +++--
+ src/qemu/qemu_monitor_json.h |  2 +-
+ 5 files changed, 13 insertions(+), 26 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 0ee10dd770..710ddfd2cf 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -1537,13 +1537,8 @@ static int
+ qemuBlockStorageSourceAttachApplyStorage(qemuMonitorPtr mon,
+                                          qemuBlockStorageSourceAttachDataPtr data)
+ {
+-    int rv;
+-
+     if (data->storageProps) {
+-        rv = qemuMonitorBlockdevAdd(mon, data->storageProps);
+-        data->storageProps = NULL;
+-
+-        if (rv < 0)
++        if (qemuMonitorBlockdevAdd(mon, &data->storageProps) < 0)
+             return -1;
+ 
+         data->storageAttached = true;
+@@ -1570,13 +1565,8 @@ static int
+ qemuBlockStorageSourceAttachApplyFormat(qemuMonitorPtr mon,
+                                         qemuBlockStorageSourceAttachDataPtr data)
+ {
+-    int rv;
+-
+     if (data->formatProps) {
+-        rv = qemuMonitorBlockdevAdd(mon, data->formatProps);
+-        data->formatProps = NULL;
+-
+-        if (rv < 0)
++        if (qemuMonitorBlockdevAdd(mon, &data->formatProps) < 0)
+             return -1;
+ 
+         data->formatAttached = true;
+diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
+index 0e67851690..e3ee48613a 100644
+--- a/src/qemu/qemu_monitor.c
++++ b/src/qemu/qemu_monitor.c
+@@ -4391,23 +4391,19 @@ qemuMonitorBlockdevCreate(qemuMonitorPtr mon,
+  * @mon: monitor object
+  * @props: JSON object describing the blockdev to add
+  *
+- * Adds a new block device (BDS) to qemu. Note that @props is always consumed
+- * by this function and should not be accessed after calling this function.
++ * Adds a new block device (BDS) to qemu. Note that *@props is consumed
++ * and set to NULL on success.
+  */
+ int
+ qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
+-                       virJSONValuePtr props)
++                       virJSONValuePtr *props)
+ {
+-    VIR_DEBUG("props=%p (node-name=%s)", props,
+-              NULLSTR(virJSONValueObjectGetString(props, "node-name")));
++    VIR_DEBUG("props=%p (node-name=%s)", *props,
++              NULLSTR(virJSONValueObjectGetString(*props, "node-name")));
+ 
+-    QEMU_CHECK_MONITOR_GOTO(mon, error);
++    QEMU_CHECK_MONITOR(mon);
+ 
+     return qemuMonitorJSONBlockdevAdd(mon, props);
+-
+- error:
+-    virJSONValueFree(props);
+-    return -1;
+ }
+ 
+ 
+diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
+index cca2cdcb27..6a6b8efaee 100644
+--- a/src/qemu/qemu_monitor.h
++++ b/src/qemu/qemu_monitor.h
+@@ -1323,7 +1323,7 @@ int qemuMonitorBlockdevCreate(qemuMonitorPtr mon,
+                               virJSONValuePtr props);
+ 
+ int qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
+-                           virJSONValuePtr props);
++                           virJSONValuePtr *props);
+ 
+ int qemuMonitorBlockdevDel(qemuMonitorPtr mon,
+                            const char *nodename);
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index 05a44882f0..3827574ef6 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -8811,12 +8811,13 @@ qemuMonitorJSONBlockdevCreate(qemuMonitorPtr mon,
+ 
+ int
+ qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
+-                           virJSONValuePtr props)
++                           virJSONValuePtr *props)
+ {
+     g_autoptr(virJSONValue) cmd = NULL;
+     g_autoptr(virJSONValue) reply = NULL;
++    virJSONValuePtr pr = g_steal_pointer(props);
+ 
+-    if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-add", props)))
++    if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-add", pr)))
+         return -1;
+ 
+     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
+index 61f5b0061d..fd2e09025e 100644
+--- a/src/qemu/qemu_monitor_json.h
++++ b/src/qemu/qemu_monitor_json.h
+@@ -597,7 +597,7 @@ int qemuMonitorJSONBlockdevCreate(qemuMonitorPtr mon,
+     ATTRIBUTE_NONNULL(1);
+ 
+ int qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
+-                               virJSONValuePtr props)
++                               virJSONValuePtr *props)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+ 
+ int qemuMonitorJSONBlockdevDel(qemuMonitorPtr mon,
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMonitorJSONBlockdevAdd-Refactor-cleanup.patch b/SOURCES/libvirt-qemuMonitorJSONBlockdevAdd-Refactor-cleanup.patch
new file mode 100644
index 0000000..ef8503f
--- /dev/null
+++ b/SOURCES/libvirt-qemuMonitorJSONBlockdevAdd-Refactor-cleanup.patch
@@ -0,0 +1,61 @@
+From bcbd86ca0e51a5f4fe41b128403d0a86c29150fa Mon Sep 17 00:00:00 2001
+Message-Id: <bcbd86ca0e51a5f4fe41b128403d0a86c29150fa@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:02 +0100
+Subject: [PATCH] qemuMonitorJSONBlockdevAdd: Refactor cleanup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use automatic variable freeing and get rid of the cleanup section.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 643294110c12a41faf2cf24c19948aaee0fcf36f)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798366
+Message-Id: <ad40c6fde708c751fe9be90fd55e9b146cd26cd6.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_monitor_json.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index 8cd98dbf26..ad490dd324 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -8813,25 +8813,19 @@ int
+ qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
+                            virJSONValuePtr props)
+ {
+-    virJSONValuePtr cmd;
+-    virJSONValuePtr reply = NULL;
+-    int ret = -1;
++    g_autoptr(virJSONValue) cmd = NULL;
++    g_autoptr(virJSONValue) reply = NULL;
+ 
+     if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-add", props)))
+         return -1;
+ 
+     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+-        goto cleanup;
++        return -1;
+ 
+     if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+-        goto cleanup;
++        return -1;
+ 
+-    ret = 0;
+-
+- cleanup:
+-    virJSONValueFree(cmd);
+-    virJSONValueFree(reply);
+-    return ret;
++    return 0;
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuMonitorJSONBlockdevDel-Refactor-cleanup.patch b/SOURCES/libvirt-qemuMonitorJSONBlockdevDel-Refactor-cleanup.patch
new file mode 100644
index 0000000..7378fcc
--- /dev/null
+++ b/SOURCES/libvirt-qemuMonitorJSONBlockdevDel-Refactor-cleanup.patch
@@ -0,0 +1,63 @@
+From 21199b5d14d4d21d2a1bdf9f17767d3c4b0bc00d Mon Sep 17 00:00:00 2001
+Message-Id: <21199b5d14d4d21d2a1bdf9f17767d3c4b0bc00d@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:03 +0100
+Subject: [PATCH] qemuMonitorJSONBlockdevDel: Refactor cleanup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use automatic variable freeing and get rid of the cleanup section.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit a592d589aa5015f5beb0f1d4302ceffe9fe7f7e8)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798366
+Message-Id: <e997465c781bb23dad07483313a29f4df2df9a1c.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_monitor_json.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index ad490dd324..05a44882f0 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -8833,9 +8833,8 @@ int
+ qemuMonitorJSONBlockdevDel(qemuMonitorPtr mon,
+                            const char *nodename)
+ {
+-    virJSONValuePtr cmd;
+-    virJSONValuePtr reply = NULL;
+-    int ret = -1;
++    g_autoptr(virJSONValue) cmd = NULL;
++    g_autoptr(virJSONValue) reply = NULL;
+ 
+     if (!(cmd = qemuMonitorJSONMakeCommand("blockdev-del",
+                                            "s:node-name", nodename,
+@@ -8843,17 +8842,12 @@ qemuMonitorJSONBlockdevDel(qemuMonitorPtr mon,
+         return -1;
+ 
+     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+-        goto cleanup;
++        return -1;
+ 
+     if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+-        goto cleanup;
++        return -1;
+ 
+-    ret = 0;
+-
+- cleanup:
+-    virJSONValueFree(cmd);
+-    virJSONValueFree(reply);
+-    return ret;
++    return 0;
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu_capabilities-Rework-domain-caps-cache.patch b/SOURCES/libvirt-qemu_capabilities-Rework-domain-caps-cache.patch
new file mode 100644
index 0000000..38774cc
--- /dev/null
+++ b/SOURCES/libvirt-qemu_capabilities-Rework-domain-caps-cache.patch
@@ -0,0 +1,328 @@
+From dbc6ca0acac24c12b30b74b706c848489f008d71 Mon Sep 17 00:00:00 2001
+Message-Id: <dbc6ca0acac24c12b30b74b706c848489f008d71@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 24 Jan 2020 15:05:51 +0100
+Subject: [PATCH] qemu_capabilities: Rework domain caps cache
+
+Since v5.6.0-48-g270583ed98 we try to cache domain capabilities,
+i.e. store filled virDomainCaps in a hash table in virQEMUCaps
+for future use. However, there's a race condition in the way it's
+implemented. We use virQEMUCapsGetDomainCapsCache() to obtain the
+pointer to the hash table, then we search the hash table for
+cached data and if none is found the domcaps is constructed and
+put into the table. Problem is that this is all done without any
+locking, so if there are two threads trying to do the same, one
+will succeed and the other will fail inserting the data into the
+table.
+
+Also, the API looks a bit fishy - obtaining pointer to the hash
+table is dangerous.
+
+The solution is to use a mutex that guards the whole operation
+with the hash table. Then, the API can be changes to return
+virDomainCapsPtr directly.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791790
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit c76009313f8068c848cad6cb517daf42e6716bb9)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1794691
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <48a4b2f9ab1e8157e4b7baf1b506e90861a39308.1579874719.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_capabilities.c | 122 +++++++++++++++++++++++++++++++++--
+ src/qemu/qemu_capabilities.h |  12 +++-
+ src/qemu/qemu_conf.c         |  65 +++----------------
+ 3 files changed, 136 insertions(+), 63 deletions(-)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 84c62a4e28..edefb70309 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -594,6 +594,26 @@ struct _virQEMUCapsAccel {
+     qemuMonitorCPUDefsPtr cpuModels;
+ };
+ 
++
++typedef struct _virQEMUDomainCapsCache virQEMUDomainCapsCache;
++typedef virQEMUDomainCapsCache *virQEMUDomainCapsCachePtr;
++struct _virQEMUDomainCapsCache {
++    virObjectLockable parent;
++
++    virHashTablePtr cache;
++};
++
++G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDomainCapsCache, virObjectUnref);
++
++static virClassPtr virQEMUDomainCapsCacheClass;
++static void virQEMUDomainCapsCacheDispose(void *obj)
++{
++    virQEMUDomainCapsCachePtr cache = obj;
++
++    virHashFree(cache->cache);
++}
++
++
+ /*
+  * Update the XML parser/formatter when adding more
+  * information to this struct so that it gets cached
+@@ -625,7 +645,7 @@ struct _virQEMUCaps {
+ 
+     virArch arch;
+ 
+-    virHashTablePtr domCapsCache;
++    virQEMUDomainCapsCachePtr domCapsCache;
+ 
+     size_t ngicCapabilities;
+     virGICCapability *gicCapabilities;
+@@ -651,6 +671,9 @@ static int virQEMUCapsOnceInit(void)
+     if (!VIR_CLASS_NEW(virQEMUCaps, virClassForObject()))
+         return -1;
+ 
++    if (!(VIR_CLASS_NEW(virQEMUDomainCapsCache, virClassForObjectLockable())))
++        return -1;
++
+     return 0;
+ }
+ 
+@@ -1620,6 +1643,22 @@ int virQEMUCapsGetDefaultVersion(virCapsPtr caps,
+ }
+ 
+ 
++static virQEMUDomainCapsCachePtr
++virQEMUDomainCapsCacheNew(void)
++{
++    g_autoptr(virQEMUDomainCapsCache) cache = NULL;
++
++    if (virQEMUCapsInitialize() < 0)
++        return NULL;
++
++    if (!(cache = virObjectLockableNew(virQEMUDomainCapsCacheClass)))
++        return NULL;
++
++    if (!(cache->cache = virHashCreate(5, virObjectFreeHashData)))
++        return NULL;
++
++    return g_steal_pointer(&cache);
++}
+ 
+ 
+ virQEMUCapsPtr
+@@ -1637,7 +1676,7 @@ virQEMUCapsNew(void)
+     if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST)))
+         goto error;
+ 
+-    if (!(qemuCaps->domCapsCache = virHashCreate(5, virObjectFreeHashData)))
++    if (!(qemuCaps->domCapsCache = virQEMUDomainCapsCacheNew()))
+         goto error;
+ 
+     return qemuCaps;
+@@ -1827,7 +1866,7 @@ void virQEMUCapsDispose(void *obj)
+ {
+     virQEMUCapsPtr qemuCaps = obj;
+ 
+-    virHashFree(qemuCaps->domCapsCache);
++    virObjectUnref(qemuCaps->domCapsCache);
+     virBitmapFree(qemuCaps->flags);
+ 
+     VIR_FREE(qemuCaps->package);
+@@ -1987,9 +2026,82 @@ const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps)
+ }
+ 
+ 
+-virHashTablePtr virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps)
++struct virQEMUCapsSearchDomcapsData {
++    const char *path;
++    const char *machine;
++    virArch arch;
++    virDomainVirtType virttype;
++};
++
++
++static int
++virQEMUCapsSearchDomcaps(const void *payload,
++                         const void *name G_GNUC_UNUSED,
++                         const void *opaque)
+ {
+-    return qemuCaps->domCapsCache;
++    virDomainCapsPtr domCaps = (virDomainCapsPtr) payload;
++    struct virQEMUCapsSearchDomcapsData *data = (struct virQEMUCapsSearchDomcapsData *) opaque;
++
++    if (STREQ_NULLABLE(data->path, domCaps->path) &&
++        STREQ_NULLABLE(data->machine, domCaps->machine) &&
++        data->arch == domCaps->arch &&
++        data->virttype == domCaps->virttype)
++        return 1;
++
++    return 0;
++}
++
++
++virDomainCapsPtr
++virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps,
++                              const char *machine,
++                              virArch arch,
++                              virDomainVirtType virttype,
++                              virArch hostarch,
++                              bool privileged,
++                              virFirmwarePtr *firmwares,
++                              size_t nfirmwares)
++{
++    virQEMUDomainCapsCachePtr cache = qemuCaps->domCapsCache;
++    virDomainCapsPtr domCaps = NULL;
++    const char *path = virQEMUCapsGetBinary(qemuCaps);
++    struct virQEMUCapsSearchDomcapsData data = {
++        .path = path,
++        .machine = machine,
++        .arch = arch,
++        .virttype = virttype,
++    };
++
++    virObjectLock(cache);
++
++    domCaps = virHashSearch(cache->cache, virQEMUCapsSearchDomcaps, &data, NULL);
++
++    if (!domCaps) {
++        g_autoptr(virDomainCaps) tempDomCaps = NULL;
++        g_autofree char *key = NULL;
++
++        /* hash miss, build new domcaps */
++        if (!(tempDomCaps = virDomainCapsNew(path, machine,
++                                             arch, virttype)))
++            goto cleanup;
++
++        if (virQEMUCapsFillDomainCaps(qemuCaps, hostarch, tempDomCaps,
++                                      privileged, firmwares, nfirmwares) < 0)
++            goto cleanup;
++
++        key = g_strdup_printf("%d:%d:%s:%s", arch, virttype,
++                              NULLSTR(machine), path);
++
++        if (virHashAddEntry(cache->cache, key, tempDomCaps) < 0)
++            goto cleanup;
++
++        domCaps = g_steal_pointer(&tempDomCaps);
++    }
++
++    virObjectRef(domCaps);
++ cleanup:
++    virObjectUnlock(cache);
++    return domCaps;
+ }
+ 
+ 
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index 193c19fc81..d76c1dbfa9 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -571,7 +571,17 @@ const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps);
+ virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps);
+ unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps);
+ const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps);
+-virHashTablePtr virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps);
++
++virDomainCapsPtr
++virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps,
++                              const char *machine,
++                              virArch arch,
++                              virDomainVirtType virttype,
++                              virArch hostarch,
++                              bool privileged,
++                              virFirmwarePtr *firmwares,
++                              size_t nfirmwares);
++
+ unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps);
+ int virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
+                                  virDomainVirtType type,
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index e33ef4895e..029996427e 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1338,31 +1338,6 @@ virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
+ }
+ 
+ 
+-struct virQEMUDriverSearchDomcapsData {
+-    const char *path;
+-    const char *machine;
+-    virArch arch;
+-    virDomainVirtType virttype;
+-};
+-
+-
+-static int
+-virQEMUDriverSearchDomcaps(const void *payload,
+-                           const void *name G_GNUC_UNUSED,
+-                           const void *opaque)
+-{
+-    virDomainCapsPtr domCaps = (virDomainCapsPtr) payload;
+-    struct virQEMUDriverSearchDomcapsData *data = (struct virQEMUDriverSearchDomcapsData *) opaque;
+-
+-    if (STREQ_NULLABLE(data->path, domCaps->path) &&
+-        STREQ_NULLABLE(data->machine, domCaps->machine) &&
+-        data->arch == domCaps->arch &&
+-        data->virttype == domCaps->virttype)
+-        return 1;
+-
+-    return 0;
+-}
+-
+ /**
+  * virQEMUDriverGetDomainCapabilities:
+  *
+@@ -1381,40 +1356,16 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriverPtr driver,
+                                    virArch arch,
+                                    virDomainVirtType virttype)
+ {
+-    g_autoptr(virDomainCaps) domCaps = NULL;
+     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+-    virHashTablePtr domCapsCache = virQEMUCapsGetDomainCapsCache(qemuCaps);
+-    struct virQEMUDriverSearchDomcapsData data = {
+-        .path = virQEMUCapsGetBinary(qemuCaps),
+-        .machine = machine,
+-        .arch = arch,
+-        .virttype = virttype,
+-    };
+ 
+-    domCaps = virHashSearch(domCapsCache,
+-                            virQEMUDriverSearchDomcaps, &data, NULL);
+-    if (!domCaps) {
+-        g_autofree char *key = NULL;
+-
+-        /* hash miss, build new domcaps */
+-        if (!(domCaps = virDomainCapsNew(data.path, data.machine,
+-                                         data.arch, data.virttype)))
+-            return NULL;
+-
+-        if (virQEMUCapsFillDomainCaps(qemuCaps, driver->hostarch, domCaps,
+-                                      driver->privileged,
+-                                      cfg->firmwares, cfg->nfirmwares) < 0)
+-            return NULL;
+-
+-        key = g_strdup_printf("%d:%d:%s:%s", data.arch, data.virttype,
+-                              NULLSTR(data.machine), NULLSTR(data.path));
+-
+-        if (virHashAddEntry(domCapsCache, key, domCaps) < 0)
+-            return NULL;
+-    }
+-
+-    virObjectRef(domCaps);
+-    return g_steal_pointer(&domCaps);
++    return virQEMUCapsGetDomainCapsCache(qemuCaps,
++                                         machine,
++                                         arch,
++                                         virttype,
++                                         driver->hostarch,
++                                         driver->privileged,
++                                         cfg->firmwares,
++                                         cfg->nfirmwares);
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu_conf-Avoid-dereferencing-NULL-in-virQEMUDriverGetHost-NUMACaps-CPU.patch b/SOURCES/libvirt-qemu_conf-Avoid-dereferencing-NULL-in-virQEMUDriverGetHost-NUMACaps-CPU.patch
new file mode 100644
index 0000000..2723729
--- /dev/null
+++ b/SOURCES/libvirt-qemu_conf-Avoid-dereferencing-NULL-in-virQEMUDriverGetHost-NUMACaps-CPU.patch
@@ -0,0 +1,85 @@
+From f06f903d5cb3c14853a7213b6a70c078380b7a62 Mon Sep 17 00:00:00 2001
+Message-Id: <f06f903d5cb3c14853a7213b6a70c078380b7a62@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 24 Jan 2020 15:05:50 +0100
+Subject: [PATCH] qemu_conf: Avoid dereferencing NULL in
+ virQEMUDriverGetHost{NUMACaps, CPU}
+
+When fixing [1] I've ran attached reproducer and had it spawn
+1024 threads and query capabilities XML in each one of them. This
+lead libvirtd to hit the RLIMIT_NOFILE limit which was kind of
+expected. What wasn't expected was a subsequent segfault. It
+happened because virCPUProbeHost failed and returned NULL. We've
+taken the NULL and passed it to virCapabilitiesHostNUMARef()
+which dereferenced it. Code inspection showed the same flas in
+virQEMUDriverGetHostNUMACaps(), so I'm fixing both places.
+
+1: https://bugzilla.redhat.com/show_bug.cgi?id=1791790
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit cc361a34c53210d682dbc5f2d506b4a23b71e399)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1794691
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <5de22b27463cd2803b3910d7ef45a0e4bc08ad47.1579874719.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_conf.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 3d2f0e7bbb..e33ef4895e 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1201,32 +1201,42 @@ virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver,
+ virCapsHostNUMAPtr
+ virQEMUDriverGetHostNUMACaps(virQEMUDriverPtr driver)
+ {
++    virCapsHostNUMAPtr hostnuma;
++
+     qemuDriverLock(driver);
+ 
+     if (!driver->hostnuma)
+         driver->hostnuma = virCapabilitiesHostNUMANewHost();
+ 
++    hostnuma = driver->hostnuma;
++
+     qemuDriverUnlock(driver);
+ 
+-    virCapabilitiesHostNUMARef(driver->hostnuma);
++    if (hostnuma)
++        virCapabilitiesHostNUMARef(hostnuma);
+ 
+-    return driver->hostnuma;
++    return hostnuma;
+ }
+ 
+ 
+ virCPUDefPtr
+ virQEMUDriverGetHostCPU(virQEMUDriverPtr driver)
+ {
++    virCPUDefPtr hostcpu;
++
+     qemuDriverLock(driver);
+ 
+     if (!driver->hostcpu)
+         driver->hostcpu = virCPUProbeHost(virArchFromHost());
+ 
++    hostcpu = driver->hostcpu;
++
+     qemuDriverUnlock(driver);
+ 
+-    virCPUDefRef(driver->hostcpu);
++    if (hostcpu)
++        virCPUDefRef(hostcpu);
+ 
+-    return driver->hostcpu;
++    return hostcpu;
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemu_domain-Modify-access-to-a-NVMe-disk-iff-needed.patch b/SOURCES/libvirt-qemu_domain-Modify-access-to-a-NVMe-disk-iff-needed.patch
new file mode 100644
index 0000000..5defcdf
--- /dev/null
+++ b/SOURCES/libvirt-qemu_domain-Modify-access-to-a-NVMe-disk-iff-needed.patch
@@ -0,0 +1,52 @@
+From 659d623740e3f15135b4c7b1e44d18ee08e67a11 Mon Sep 17 00:00:00 2001
+Message-Id: <659d623740e3f15135b4c7b1e44d18ee08e67a11@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 14 Feb 2020 16:17:08 +0100
+Subject: [PATCH] qemu_domain: Modify access to a NVMe disk iff needed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If a domain has a NVMe disk it already has the access configured.
+Trying to configure it again on a commit or some other operation
+is wrong and condemned to failure.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit b18328256b565806c04c153ce49fc3641412b35b)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1519005#c24
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <ee3871eb043b3ae82daca2e365b696c8963665f7.1581693409.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_domain.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 1bed117eb0..8e0e919f9a 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -11828,13 +11828,12 @@ qemuDomainStorageSourceAccessModify(virQEMUDriverPtr driver,
+ 
+     revoke_lockspace = true;
+ 
+-    if (qemuDomainStorageSourceAccessModifyNVMe(driver, vm, src, false) < 0)
+-        goto revoke;
+-
+-    revoke_nvme = true;
+-
+-    /* When modifying access of existing @src namespace does not need update */
+     if (!(flags & QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_MODIFY_ACCESS)) {
++        if (qemuDomainStorageSourceAccessModifyNVMe(driver, vm, src, false) < 0)
++            goto revoke;
++
++        revoke_nvme = true;
++
+         if (qemuDomainNamespaceSetupDisk(vm, src) < 0)
+             goto revoke;
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemublocktest-Add-JSON-JSON-test-cases-for-block-device-backends.patch b/SOURCES/libvirt-qemublocktest-Add-JSON-JSON-test-cases-for-block-device-backends.patch
new file mode 100644
index 0000000..feb2a18
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Add-JSON-JSON-test-cases-for-block-device-backends.patch
@@ -0,0 +1,149 @@
+From b385c22388eb9810f654936decc970bc882d6c8b Mon Sep 17 00:00:00 2001
+Message-Id: <b385c22388eb9810f654936decc970bc882d6c8b@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:12 +0100
+Subject: [PATCH] qemublocktest: Add JSON->JSON test cases for block device
+ backends
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add testing of the interpretation of the JSON pseudo-protocol backing
+store into JSON structs for blockdev. This will be used to test JSON
+pseudo-URIs used by libguestfs while actually also validating the output
+against the QMP schema. Since libguestfs uses obsolete/undocumented
+values the outputs will differ and a benefit is that modern output is
+used now.
+
+The example test case covers the fields and values used by libguestfs
+when using the https driver.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit d089234110282069e9a6dfe879ca257d114bb5bd)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <f63c18cbdf69b27bd91fe44250737cf89b3cb090.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         | 65 +++++++++++++++++++
+ .../jsontojson/curl-libguestfs-in.json        |  1 +
+ .../jsontojson/curl-libguestfs-out.json       |  9 +++
+ 3 files changed, 75 insertions(+)
+ create mode 100644 tests/qemublocktestdata/jsontojson/curl-libguestfs-in.json
+ create mode 100644 tests/qemublocktestdata/jsontojson/curl-libguestfs-out.json
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index d2ba85c5e5..d8bd811b4d 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -128,6 +128,57 @@ testBackingXMLjsonXML(const void *args)
+     return 0;
+ }
+ 
++static const char *testJSONtoJSONPath = abs_srcdir "/qemublocktestdata/jsontojson/";
++
++struct testJSONtoJSONData {
++    const char *name;
++    virHashTablePtr schema;
++    virJSONValuePtr schemaroot;
++};
++
++static int
++testJSONtoJSON(const void *args)
++{
++    const struct testJSONtoJSONData *data = args;
++    g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
++    g_autoptr(virJSONValue) jsonsrcout = NULL;
++    g_autoptr(virStorageSource) src = NULL;
++    g_autofree char *actual = NULL;
++    g_autofree char *in = NULL;
++    g_autofree char *infile = g_strdup_printf("%s%s-in.json", testJSONtoJSONPath,
++                                              data->name);
++    g_autofree char *outfile = g_strdup_printf("%s%s-out.json", testJSONtoJSONPath,
++                                              data->name);
++
++    if (virTestLoadFile(infile, &in) < 0)
++        return -1;
++
++    if (virStorageSourceNewFromBackingAbsolute(in, &src) < 0) {
++        fprintf(stderr, "failed to parse disk json\n");
++        return -1;
++    }
++
++    if (!(jsonsrcout = qemuBlockStorageSourceGetBackendProps(src, false, false, true))) {
++        fprintf(stderr, "failed to format disk source json\n");
++        return -1;
++    }
++
++    if (!(actual = virJSONValueToString(jsonsrcout, true)))
++        return -1;
++
++    if (testQEMUSchemaValidate(jsonsrcout, data->schemaroot,
++                               data->schema, &debug) < 0) {
++        g_autofree char *debugmsg = virBufferContentAndReset(&debug);
++
++        VIR_TEST_VERBOSE("json does not conform to QAPI schema");
++        VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
++                       actual, NULLSTR(debugmsg));
++        return -1;
++    }
++
++    return virTestCompareToFile(actual, outfile);
++}
++
+ 
+ struct testQemuDiskXMLToJSONData {
+     virQEMUDriverPtr driver;
+@@ -875,6 +926,7 @@ mymain(void)
+     virQEMUDriver driver;
+     struct testBackingXMLjsonXMLdata xmljsonxmldata;
+     struct testQemuDiskXMLToJSONData diskxmljsondata;
++    struct testJSONtoJSONData jsontojsondata;
+     struct testQemuImageCreateData imagecreatedata;
+     struct testQemuBackupIncrementalBitmapCalculateData backupbitmapcalcdata;
+     struct testQemuCheckpointDeleteMergeData checkpointdeletedata;
+@@ -1068,6 +1120,19 @@ mymain(void)
+     TEST_DISK_TO_JSON("block-raw-noopts");
+     TEST_DISK_TO_JSON("block-raw-reservations");
+ 
++#define TEST_JSON_TO_JSON(nme) \
++    do { \
++        jsontojsondata.name = nme; \
++        if (virTestRun("JSON to JSON " nme, testJSONtoJSON, \
++                       &jsontojsondata) < 0) \
++            ret = -1; \
++    } while (0)
++
++    jsontojsondata.schema = qmp_schema_x86_64;
++    jsontojsondata.schemaroot = qmp_schemaroot_x86_64_blockdev_add;
++
++    TEST_JSON_TO_JSON("curl-libguestfs");
++
+ #define TEST_IMAGE_CREATE(testname, testbacking) \
+     do { \
+         imagecreatedata.name = testname; \
+diff --git a/tests/qemublocktestdata/jsontojson/curl-libguestfs-in.json b/tests/qemublocktestdata/jsontojson/curl-libguestfs-in.json
+new file mode 100644
+index 0000000000..0b92dabc6d
+--- /dev/null
++++ b/tests/qemublocktestdata/jsontojson/curl-libguestfs-in.json
+@@ -0,0 +1 @@
++json:{"file.driver":"https","file.url":"https://test.host/whatever.img","file.timeout":2000,"file.readahead":65536,"file.sslverify":"off","file.cookie":"some_cookie=\"some_value_or_whatever\""}
+diff --git a/tests/qemublocktestdata/jsontojson/curl-libguestfs-out.json b/tests/qemublocktestdata/jsontojson/curl-libguestfs-out.json
+new file mode 100644
+index 0000000000..e130c7bd3c
+--- /dev/null
++++ b/tests/qemublocktestdata/jsontojson/curl-libguestfs-out.json
+@@ -0,0 +1,9 @@
++{
++  "driver": "https",
++  "url": "https://test.host:443/whatever.img",
++  "sslverify": false,
++  "timeout": 2000,
++  "readahead": 65536,
++  "auto-read-only": true,
++  "discard": "unmap"
++}
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Add-more-tests-for-block-commit-bitmap-handling-with-snapshots.patch b/SOURCES/libvirt-qemublocktest-Add-more-tests-for-block-commit-bitmap-handling-with-snapshots.patch
new file mode 100644
index 0000000..8d09264
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Add-more-tests-for-block-commit-bitmap-handling-with-snapshots.patch
@@ -0,0 +1,945 @@
+From 2eb309fcc6bc22e5eff4fe048683176056a43a94 Mon Sep 17 00:00:00 2001
+Message-Id: <2eb309fcc6bc22e5eff4fe048683176056a43a94@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:26 +0100
+Subject: [PATCH] qemublocktest: Add more tests for block-commit bitmap
+ handling with snapshots
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Test handling of more complex cases of merging bitmaps accross
+snapshots.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 8f096cd8808b186d451ec100c646dc8ddd974735)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <45bfd1540594f663240f64a58a369c31cd83e607.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |  15 ++
+ .../bitmapblockcommit/snapshots-1-2           |  49 +++++++
+ .../bitmapblockcommit/snapshots-1-3           |  76 ++++++++++
+ .../bitmapblockcommit/snapshots-1-4           | 126 +++++++++++++++++
+ .../bitmapblockcommit/snapshots-1-5           | 130 ++++++++++++++++++
+ .../bitmapblockcommit/snapshots-2-3           |  49 +++++++
+ .../bitmapblockcommit/snapshots-2-4           |  99 +++++++++++++
+ .../bitmapblockcommit/snapshots-2-5           | 103 ++++++++++++++
+ .../bitmapblockcommit/snapshots-3-4           |  72 ++++++++++
+ .../bitmapblockcommit/snapshots-3-5           |  76 ++++++++++
+ .../bitmapblockcommit/snapshots-4-5           |  33 +++++
+ 11 files changed, 828 insertions(+)
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 63ac80b584..ad68b37c80 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1392,6 +1392,21 @@ mymain(void)
+     TEST_BITMAP_BLOCKCOMMIT("basic-1-3", 1, 3, "basic");
+     TEST_BITMAP_BLOCKCOMMIT("basic-2-3", 2, 3, "basic");
+ 
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-1-2", 1, 2, "snapshots");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-1-3", 1, 3, "snapshots");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-1-4", 1, 4, "snapshots");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-1-5", 1, 5, "snapshots");
++
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-2-3", 2, 3, "snapshots");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-2-4", 2, 4, "snapshots");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-2-5", 2, 5, "snapshots");
++
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-3-4", 3, 4, "snapshots");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-3-5", 3, 5, "snapshots");
++
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-4-5", 4, 5, "snapshots");
++
++
+  cleanup:
+     qemuTestDriverFree(&driver);
+     VIR_FREE(capslatest_x86_64);
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2
+new file mode 100644
+index 0000000000..0015b9ceb3
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-2
+@@ -0,0 +1,49 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "d"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3
+new file mode 100644
+index 0000000000..5691b408aa
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-3
+@@ -0,0 +1,76 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "c"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        },
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4
+new file mode 100644
+index 0000000000..454001531a
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-4
+@@ -0,0 +1,126 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        },
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        },
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5
+new file mode 100644
+index 0000000000..2fd43d7917
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-1-5
+@@ -0,0 +1,130 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "a"
++        },
++        {
++          "node": "libvirt-4-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        },
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        },
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3
+new file mode 100644
+index 0000000000..d719a90bd7
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-3
+@@ -0,0 +1,49 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "c"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4
+new file mode 100644
+index 0000000000..9e37962344
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-4
+@@ -0,0 +1,99 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        },
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5
+new file mode 100644
+index 0000000000..d6b20a5d05
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-2-5
+@@ -0,0 +1,103 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "a"
++        },
++        {
++          "node": "libvirt-4-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        },
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4
+new file mode 100644
+index 0000000000..b96e8910d7
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-4
+@@ -0,0 +1,72 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5
+new file mode 100644
+index 0000000000..9570c34c40
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-3-5
+@@ -0,0 +1,76 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "a"
++        },
++        {
++          "node": "libvirt-4-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5
+new file mode 100644
+index 0000000000..7e1020d96e
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-4-5
+@@ -0,0 +1,33 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-4-format",
++          "name": "a"
++        }
++      ]
++    }
++  }
++]
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Add-tests-for-handling-of-bitmaps-during-block-commit.patch b/SOURCES/libvirt-qemublocktest-Add-tests-for-handling-of-bitmaps-during-block-commit.patch
new file mode 100644
index 0000000..ce9eb4c
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Add-tests-for-handling-of-bitmaps-during-block-commit.patch
@@ -0,0 +1,418 @@
+From ff6e22d991a2681488c3c52b00dcf5289bf97bd3 Mon Sep 17 00:00:00 2001
+Message-Id: <ff6e22d991a2681488c3c52b00dcf5289bf97bd3@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:25 +0100
+Subject: [PATCH] qemublocktest: Add tests for handling of bitmaps during
+ block-commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add code for testing the two necessary steps of handling bitmaps during
+block commit and exercise the code on the test data which we have for
+bitmap handling.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 77b9d574b41e79bbeb87ee0443dd60c4fde8a79a)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <551872a6e70f8136c2bd8e9f7be194b8f7091046.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |  95 ++++++++++++++
+ .../bitmapblockcommit/basic-1-2               | 119 ++++++++++++++++++
+ .../bitmapblockcommit/basic-1-3               | 119 ++++++++++++++++++
+ .../bitmapblockcommit/basic-2-3               |   2 +
+ 4 files changed, 335 insertions(+)
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-1-2
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-1-3
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/basic-2-3
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 6ccc2328b3..63ac80b584 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -665,6 +665,21 @@ testQemuBackupIncrementalBitmapCalculateGetFakeChain(void)
+ }
+ 
+ 
++static virStorageSourcePtr
++testQemuBitmapGetFakeChainEntry(virStorageSourcePtr src,
++                                size_t idx)
++{
++    virStorageSourcePtr n;
++
++    for (n = src; n; n = n->backingStore) {
++        if (n->id == idx)
++            return n;
++    }
++
++    return NULL;
++}
++
++
+ typedef virDomainMomentDefPtr testMomentList;
+ 
+ static void
+@@ -919,6 +934,68 @@ testQemuBlockBitmapBlockcopy(const void *opaque)
+     return virTestCompareToFile(actual, expectpath);
+ }
+ 
++static const char *blockcommitPrefix = "qemublocktestdata/bitmapblockcommit/";
++
++struct testQemuBlockBitmapBlockcommitData {
++    const char *name;
++    virStorageSourcePtr top;
++    virStorageSourcePtr base;
++    virStorageSourcePtr chain;
++    const char *nodedatafile;
++};
++
++
++static int
++testQemuBlockBitmapBlockcommit(const void *opaque)
++{
++    const struct testQemuBlockBitmapBlockcommitData *data = opaque;
++
++    g_autofree char *actual = NULL;
++    g_autofree char *expectpath = NULL;
++    g_autoptr(virJSONValue) actionsDisable = NULL;
++    g_autoptr(virJSONValue) actionsMerge = NULL;
++    g_autoptr(virJSONValue) nodedatajson = NULL;
++    g_autoptr(virHashTable) nodedata = NULL;
++    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
++    VIR_AUTOSTRINGLIST bitmapsDisable = NULL;
++
++    expectpath = g_strdup_printf("%s/%s%s", abs_srcdir,
++                                 blockcommitPrefix, data->name);
++
++    if (!(nodedatajson = virTestLoadFileJSON(bitmapDetectPrefix, data->nodedatafile,
++                                             ".json", NULL)))
++        return -1;
++
++    if (!(nodedata = qemuMonitorJSONBlockGetNamedNodeDataJSON(nodedatajson))) {
++        VIR_TEST_VERBOSE("failed to load nodedata JSON\n");
++        return -1;
++    }
++
++    if (qemuBlockBitmapsHandleCommitStart(data->top, data->base, nodedata,
++                                          &actionsDisable, &bitmapsDisable) < 0)
++        return -1;
++
++    virBufferAddLit(&buf, "pre job bitmap disable:\n");
++
++    if (actionsDisable &&
++        virJSONValueToBuffer(actionsDisable, &buf, true) < 0)
++        return -1;
++
++    virBufferAddLit(&buf, "merge bitmpas:\n");
++
++    if (qemuBlockBitmapsHandleCommitFinish(data->top, data->base, nodedata,
++                                           &actionsMerge, bitmapsDisable) < 0)
++        return -1;
++
++    if (actionsMerge &&
++        virJSONValueToBuffer(actionsMerge, &buf, true) < 0)
++        return -1;
++
++    actual = virBufferContentAndReset(&buf);
++
++    return virTestCompareToFile(actual, expectpath);
++}
++
+ 
+ static int
+ mymain(void)
+@@ -933,6 +1010,7 @@ mymain(void)
+     struct testQemuCheckpointDeleteMergeData checkpointdeletedata;
+     struct testQemuBlockBitmapValidateData blockbitmapvalidatedata;
+     struct testQemuBlockBitmapBlockcopyData blockbitmapblockcopydata;
++    struct testQemuBlockBitmapBlockcommitData blockbitmapblockcommitdata;
+     char *capslatest_x86_64 = NULL;
+     virQEMUCapsPtr caps_x86_64 = NULL;
+     g_autoptr(virHashTable) qmp_schema_x86_64 = NULL;
+@@ -1297,6 +1375,23 @@ mymain(void)
+     TEST_BITMAP_BLOCKCOPY("snapshots-shallow", true, "snapshots");
+     TEST_BITMAP_BLOCKCOPY("snapshots-deep", false, "snapshots");
+ 
++
++#define TEST_BITMAP_BLOCKCOMMIT(testname, topimg, baseimg, ndf) \
++    do {\
++        blockbitmapblockcommitdata.name = testname; \
++        blockbitmapblockcommitdata.top = testQemuBitmapGetFakeChainEntry(bitmapSourceChain, topimg); \
++        blockbitmapblockcommitdata.base = testQemuBitmapGetFakeChainEntry(bitmapSourceChain, baseimg); \
++        blockbitmapblockcommitdata.nodedatafile = ndf; \
++        if (virTestRun("bitmap block commit " testname, \
++                       testQemuBlockBitmapBlockcommit, \
++                       &blockbitmapblockcommitdata) < 0) \
++        ret = -1; \
++    } while (0)
++
++    TEST_BITMAP_BLOCKCOMMIT("basic-1-2", 1, 2, "basic");
++    TEST_BITMAP_BLOCKCOMMIT("basic-1-3", 1, 3, "basic");
++    TEST_BITMAP_BLOCKCOMMIT("basic-2-3", 2, 3, "basic");
++
+  cleanup:
+     qemuTestDriverFree(&driver);
+     VIR_FREE(capslatest_x86_64);
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-1-2 b/tests/qemublocktestdata/bitmapblockcommit/basic-1-2
+new file mode 100644
+index 0000000000..8eeb4c3a11
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/basic-1-2
+@@ -0,0 +1,119 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "a",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-1-3 b/tests/qemublocktestdata/bitmapblockcommit/basic-1-3
+new file mode 100644
+index 0000000000..71b48e31a5
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/basic-1-3
+@@ -0,0 +1,119 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "a",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/basic-2-3 b/tests/qemublocktestdata/bitmapblockcommit/basic-2-3
+new file mode 100644
+index 0000000000..bfc58f994e
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/basic-2-3
+@@ -0,0 +1,2 @@
++pre job bitmap disable:
++merge bitmpas:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Add-tests-for-re-enabling-of-bitmaps-after-commit.patch b/SOURCES/libvirt-qemublocktest-Add-tests-for-re-enabling-of-bitmaps-after-commit.patch
new file mode 100644
index 0000000..5f312be
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Add-tests-for-re-enabling-of-bitmaps-after-commit.patch
@@ -0,0 +1,460 @@
+From 0dc8024eae1f56e02228171feb824becf21ee697 Mon Sep 17 00:00:00 2001
+Message-Id: <0dc8024eae1f56e02228171feb824becf21ee697@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 17 Mar 2020 17:12:46 +0100
+Subject: [PATCH] qemublocktest: Add tests for re-enabling of bitmaps after
+ commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some branches were not covered and thus we didn't catch that the bitmaps
+are not re-enabled if nothing is merged into them. Two bitmaps are
+necessary to reliably test the case due to hash table ordering.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Tested-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit cab3622119a73a54e62e5f2d7b4257da00bd4ac8)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <fc3f48f6a5233fce3148fc21a63c4e0255b2e466.1584461519.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ .../bitmap/snapshots-synthetic-broken.json    | 18 ++++++++
+ .../bitmap/snapshots-synthetic-broken.out     |  2 +
+ .../snapshots-synthetic-broken-1-2            | 30 ++++++++++++
+ .../snapshots-synthetic-broken-1-3            | 46 +++++++++++++++++++
+ .../snapshots-synthetic-broken-1-4            | 46 +++++++++++++++++++
+ .../snapshots-synthetic-broken-1-5            | 46 +++++++++++++++++++
+ .../snapshots-synthetic-broken-2-3            | 46 +++++++++++++++++++
+ .../snapshots-synthetic-broken-2-4            | 46 +++++++++++++++++++
+ .../snapshots-synthetic-broken-2-5            | 46 +++++++++++++++++++
+ 9 files changed, 326 insertions(+)
+
+diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json
+index bf4963494f..8cf14d4baa 100644
+--- a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json
++++ b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json
+@@ -398,6 +398,24 @@
+                 "granularity": 65536,
+                 "count": 0
+             },
++            {
++                "name": "oa",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            },
++            {
++                "name": "ob",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            },
+             {
+                 "name": "d",
+                 "recording": true,
+diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out
+index 022630bd76..ad24a580f1 100644
+--- a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out
++++ b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out
+@@ -3,6 +3,8 @@ libvirt-1-format:
+   current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+ libvirt-2-format:
+         c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++       oa: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++       ob: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+         d: record:1 busy:0 persist:1 inconsist:1 gran:65536 dirty:0
+ libvirt-3-format:
+         a: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2
+index d413fbe723..463120d442 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2
+@@ -1,4 +1,20 @@
+ pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "oa"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "ob"
++    }
++  }
++]
+ merge bitmpas:
+ [
+   {
+@@ -23,5 +39,19 @@ merge bitmpas:
+         }
+       ]
+     }
++  },
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "oa"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "ob"
++    }
+   }
+ ]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3
+index 6eb14f927a..fec6f95dd1 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3
+@@ -62,5 +62,51 @@ merge bitmpas:
+         }
+       ]
+     }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "oa",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "oa",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "oa"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "ob",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "ob",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "ob"
++        }
++      ]
++    }
+   }
+ ]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4
+index f4d9b72576..697230f67b 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4
+@@ -69,5 +69,51 @@ merge bitmpas:
+         }
+       ]
+     }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "oa",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "oa",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "oa"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "ob",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "ob",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "ob"
++        }
++      ]
++    }
+   }
+ ]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5
+index a8e575c2d9..6bf1f0da64 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5
+@@ -69,5 +69,51 @@ merge bitmpas:
+         }
+       ]
+     }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "oa",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "oa",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "oa"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "ob",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "ob",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "ob"
++        }
++      ]
++    }
+   }
+ ]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3
+index d468e2b9d8..f202bb94b1 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3
+@@ -39,5 +39,51 @@ merge bitmpas:
+         }
+       ]
+     }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "oa",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "oa",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "oa"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "ob",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "ob",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "ob"
++        }
++      ]
++    }
+   }
+ ]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4
+index 2a9986bac6..864cc9041b 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4
+@@ -46,5 +46,51 @@ merge bitmpas:
+         }
+       ]
+     }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "oa",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "oa",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "oa"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "ob",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "ob",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "ob"
++        }
++      ]
++    }
+   }
+ ]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5
+index 47d9f6e17a..4c5d8dbe80 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5
+@@ -46,5 +46,51 @@ merge bitmpas:
+         }
+       ]
+     }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "oa",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "oa",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "oa"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "ob",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "ob",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "ob"
++        }
++      ]
++    }
+   }
+ ]
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Add-tests-of-broken-bitmap-chain-handling-during-block-commit.patch b/SOURCES/libvirt-qemublocktest-Add-tests-of-broken-bitmap-chain-handling-during-block-commit.patch
new file mode 100644
index 0000000..9e491d9
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Add-tests-of-broken-bitmap-chain-handling-during-block-commit.patch
@@ -0,0 +1,585 @@
+From 60a2b7411580b4df7a1f9b6f2706fc666d12b170 Mon Sep 17 00:00:00 2001
+Message-Id: <60a2b7411580b4df7a1f9b6f2706fc666d12b170@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:27 +0100
+Subject: [PATCH] qemublocktest: Add tests of broken bitmap chain handling
+ during block-commit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use the 'snapshots-synthetic-broken' test data for block-commit.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 4e9bb10cf3f3d2c2b13a6e889209e2fac88e1ea7)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <45e2c5f391fdbf458ffabba516f93d0eb279cd97.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         | 13 ++++
+ .../snapshots-synthetic-broken-1-2            | 27 +++++++
+ .../snapshots-synthetic-broken-1-3            | 66 +++++++++++++++++
+ .../snapshots-synthetic-broken-1-4            | 73 +++++++++++++++++++
+ .../snapshots-synthetic-broken-1-5            | 73 +++++++++++++++++++
+ .../snapshots-synthetic-broken-2-3            | 43 +++++++++++
+ .../snapshots-synthetic-broken-2-4            | 50 +++++++++++++
+ .../snapshots-synthetic-broken-2-5            | 50 +++++++++++++
+ .../snapshots-synthetic-broken-3-4            | 27 +++++++
+ .../snapshots-synthetic-broken-3-5            | 27 +++++++
+ .../snapshots-synthetic-broken-4-5            | 20 +++++
+ 11 files changed, 469 insertions(+)
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5
+ create mode 100644 tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index ad68b37c80..c8428921fe 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1406,6 +1406,19 @@ mymain(void)
+ 
+     TEST_BITMAP_BLOCKCOMMIT("snapshots-4-5", 4, 5, "snapshots");
+ 
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-2", 1, 2, "snapshots-synthetic-broken");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-3", 1, 3, "snapshots-synthetic-broken");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-4", 1, 4, "snapshots-synthetic-broken");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-1-5", 1, 5, "snapshots-synthetic-broken");
++
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-2-3", 2, 3, "snapshots-synthetic-broken");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-2-4", 2, 4, "snapshots-synthetic-broken");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-2-5", 2, 5, "snapshots-synthetic-broken");
++
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-3-4", 3, 4, "snapshots-synthetic-broken");
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-3-5", 3, 5, "snapshots-synthetic-broken");
++
++    TEST_BITMAP_BLOCKCOMMIT("snapshots-synthetic-broken-4-5", 4, 5, "snapshots-synthetic-broken");
+ 
+  cleanup:
+     qemuTestDriverFree(&driver);
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2
+new file mode 100644
+index 0000000000..d413fbe723
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-2
+@@ -0,0 +1,27 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3
+new file mode 100644
+index 0000000000..6eb14f927a
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-3
+@@ -0,0 +1,66 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4
+new file mode 100644
+index 0000000000..f4d9b72576
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-4
+@@ -0,0 +1,73 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5
+new file mode 100644
+index 0000000000..a8e575c2d9
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-1-5
+@@ -0,0 +1,73 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3
+new file mode 100644
+index 0000000000..d468e2b9d8
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-3
+@@ -0,0 +1,43 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4
+new file mode 100644
+index 0000000000..2a9986bac6
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-4
+@@ -0,0 +1,50 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5
+new file mode 100644
+index 0000000000..47d9f6e17a
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-2-5
+@@ -0,0 +1,50 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4
+new file mode 100644
+index 0000000000..367a930a74
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-4
+@@ -0,0 +1,27 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-4-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5
+new file mode 100644
+index 0000000000..0062ec140c
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-3-5
+@@ -0,0 +1,27 @@
++pre job bitmap disable:
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-5-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5 b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5
+new file mode 100644
+index 0000000000..b1f10a8a24
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcommit/snapshots-synthetic-broken-4-5
+@@ -0,0 +1,20 @@
++pre job bitmap disable:
++[
++  {
++    "type": "block-dirty-bitmap-disable",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
++merge bitmpas:
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Backport-cleanups-for-testQemuDiskXMLToProps-from-dd94f36ffbe.patch b/SOURCES/libvirt-qemublocktest-Backport-cleanups-for-testQemuDiskXMLToProps-from-dd94f36ffbe.patch
new file mode 100644
index 0000000..46867d8
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Backport-cleanups-for-testQemuDiskXMLToProps-from-dd94f36ffbe.patch
@@ -0,0 +1,60 @@
+From ec4851ad003ae1e28bd43f3d76af9bc05537a97f Mon Sep 17 00:00:00 2001
+Message-Id: <ec4851ad003ae1e28bd43f3d76af9bc05537a97f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:25:54 +0100
+Subject: [PATCH] qemublocktest: Backport cleanups for testQemuDiskXMLToProps
+ from dd94f36ffbe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RHEL-only subset changes from dd94f36ffbe
+
+dd94f36ffbe is too invasive to backport but makes changes to
+testQemuDiskXMLToProps which make it hard to backport other patches.
+
+Filter out the relevant changes for a clean backport.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Message-Id: <af87b1b8a1e1343a339fcc308e74bc4d08a96103.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index c8428921fe..cd7ea6bb2b 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -256,6 +256,7 @@ static int
+ testQemuDiskXMLToProps(const void *opaque)
+ {
+     struct testQemuDiskXMLToJSONData *data = (void *) opaque;
++    g_autoptr(virDomainDef) vmdef = NULL;
+     virDomainDiskDefPtr disk = NULL;
+     virStorageSourcePtr n;
+     virJSONValuePtr formatProps = NULL;
+@@ -275,6 +276,10 @@ testQemuDiskXMLToProps(const void *opaque)
+                                        VIR_DOMAIN_DEF_PARSE_STATUS)))
+         goto cleanup;
+ 
++    if (!(vmdef = virDomainDefNew()) ||
++        virDomainDiskInsert(vmdef, disk) < 0)
++        goto cleanup;
++
+     if (qemuCheckDiskConfig(disk, data->qemuCaps) < 0 ||
+         qemuDomainDeviceDefValidateDisk(disk, data->qemuCaps) < 0) {
+         VIR_TEST_VERBOSE("invalid configuration for disk");
+@@ -313,7 +318,6 @@ testQemuDiskXMLToProps(const void *opaque)
+  cleanup:
+     virJSONValueFree(formatProps);
+     virJSONValueFree(storageProps);
+-    virDomainDiskDefFree(disk);
+     VIR_FREE(xmlpath);
+     VIR_FREE(xmlstr);
+     return ret;
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemublocktest-Extract-schema-root-for-blockdev-add-validation.patch b/SOURCES/libvirt-qemublocktest-Extract-schema-root-for-blockdev-add-validation.patch
new file mode 100644
index 0000000..04d9fc9
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Extract-schema-root-for-blockdev-add-validation.patch
@@ -0,0 +1,71 @@
+From fbeabd58626de924d59891338dade4f56044a3cc Mon Sep 17 00:00:00 2001
+Message-Id: <fbeabd58626de924d59891338dade4f56044a3cc@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:10 +0100
+Subject: [PATCH] qemublocktest: Extract schema root for blockdev-add
+ validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move lookup of the schema root earlier so that multiple functions
+can use it for validation.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 218ce53069b730daa508a4a67d8640b415d69b4e)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <9f33cec13b55e431b1144042ddcbeb7afefcf969.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index f805265c93..94f20eeb47 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -864,6 +864,7 @@ mymain(void)
+     char *capslatest_x86_64 = NULL;
+     virQEMUCapsPtr caps_x86_64 = NULL;
+     g_autoptr(virHashTable) qmp_schema_x86_64 = NULL;
++    virJSONValuePtr qmp_schemaroot_x86_64_blockdev_add = NULL;
+     g_autoptr(virStorageSource) bitmapSourceChain = NULL;
+ 
+     if (qemuTestDriverInit(&driver) < 0)
+@@ -891,6 +892,15 @@ mymain(void)
+         goto cleanup;
+     }
+ 
++    if (virQEMUQAPISchemaPathGet("blockdev-add/arg-type",
++                                 qmp_schema_x86_64,
++                                 &qmp_schemaroot_x86_64_blockdev_add) < 0 ||
++        !qmp_schemaroot_x86_64_blockdev_add) {
++        VIR_TEST_VERBOSE("failed to find schema entry for blockdev-add");
++        ret = -1;
++        goto cleanup;
++    }
++
+     virTestCounterReset("qemu storage source xml->json->xml ");
+ 
+ #define TEST_JSON_FORMAT(tpe, xmlstr) \
+@@ -990,15 +1000,7 @@ mymain(void)
+ #define TEST_DISK_TO_JSON(nme) TEST_DISK_TO_JSON_FULL(nme, false)
+ 
+     diskxmljsondata.schema = qmp_schema_x86_64;
+-
+-    if (virQEMUQAPISchemaPathGet("blockdev-add/arg-type",
+-                                 diskxmljsondata.schema,
+-                                 &diskxmljsondata.schemaroot) < 0 ||
+-        !diskxmljsondata.schemaroot) {
+-        VIR_TEST_VERBOSE("failed to find schema entry for blockdev-add");
+-        ret = -1;
+-        goto cleanup;
+-    }
++    diskxmljsondata.schemaroot = qmp_schemaroot_x86_64_blockdev_add;
+ 
+     TEST_DISK_TO_JSON_FULL("nodename-long-format", true);
+     TEST_DISK_TO_JSON_FULL("nodename-long-protocol", true);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Fix-and-optimize-fake-image-chain.patch b/SOURCES/libvirt-qemublocktest-Fix-and-optimize-fake-image-chain.patch
new file mode 100644
index 0000000..270afad
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Fix-and-optimize-fake-image-chain.patch
@@ -0,0 +1,47 @@
+From a0a2e4eaa6ab0b6435286f9af6e7026f0000b9e5 Mon Sep 17 00:00:00 2001
+Message-Id: <a0a2e4eaa6ab0b6435286f9af6e7026f0000b9e5@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:23 +0100
+Subject: [PATCH] qemublocktest: Fix and optimize fake image chain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Set the 'id' field of the backing chain properly so that we can look
+up images, and initialize 6 images instead of 10 as we don't use more
+currently.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit f8389505aae66e705046f5cbd9fe4ac10f1dee2e)
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <c45885fd70242874545a5c8129bcb52022014112.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index f48875e16d..6ccc2328b3 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -636,6 +636,7 @@ testQemuBackupIncrementalBitmapCalculateGetFakeImage(size_t idx)
+    if (!(ret = virStorageSourceNew()))
+        abort();
+ 
++   ret->id = idx;
+    ret->type = VIR_STORAGE_TYPE_FILE;
+    ret->format = VIR_STORAGE_FILE_QCOW2;
+    ret->path = g_strdup_printf("/image%zu", idx);
+@@ -655,7 +656,7 @@ testQemuBackupIncrementalBitmapCalculateGetFakeChain(void)
+ 
+     n = ret = testQemuBackupIncrementalBitmapCalculateGetFakeImage(1);
+ 
+-    for (i = 2; i < 10; i++) {
++    for (i = 2; i < 6; i++) {
+         n->backingStore = testQemuBackupIncrementalBitmapCalculateGetFakeImage(i);
+         n = n->backingStore;
+     }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Load-QMP-schema-earlier.patch b/SOURCES/libvirt-qemublocktest-Load-QMP-schema-earlier.patch
new file mode 100644
index 0000000..23c260e
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Load-QMP-schema-earlier.patch
@@ -0,0 +1,85 @@
+From e0454c4801452c031856681c68bf5d154440bbb0 Mon Sep 17 00:00:00 2001
+Message-Id: <e0454c4801452c031856681c68bf5d154440bbb0@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:09 +0100
+Subject: [PATCH] qemublocktest: Load QMP schema earlier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Multiple tests require the schema. Extract the loading into a separate
+variable to avoid issues with ownership of the pointer.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 1262cdede447a2566b6e8cb99434b767a4ef67da)
+
+ Conflicts:
+	tests/qemublocktest.c
+        QMP schema loading for non-x86_64 qemus was not backported.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <d8a7b2d9987175b106363d781df23d313a02d870.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 3057db6930..f805265c93 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -863,6 +863,7 @@ mymain(void)
+     struct testQemuBlockBitmapBlockcopyData blockbitmapblockcopydata;
+     char *capslatest_x86_64 = NULL;
+     virQEMUCapsPtr caps_x86_64 = NULL;
++    g_autoptr(virHashTable) qmp_schema_x86_64 = NULL;
+     g_autoptr(virStorageSource) bitmapSourceChain = NULL;
+ 
+     if (qemuTestDriverInit(&driver) < 0)
+@@ -885,6 +886,11 @@ mymain(void)
+     diskxmljsondata.qemuCaps = caps_x86_64;
+     imagecreatedata.qemuCaps = caps_x86_64;
+ 
++    if (!(qmp_schema_x86_64 = testQEMUSchemaLoad())) {
++        ret = -1;
++        goto cleanup;
++    }
++
+     virTestCounterReset("qemu storage source xml->json->xml ");
+ 
+ #define TEST_JSON_FORMAT(tpe, xmlstr) \
+@@ -983,10 +989,7 @@ mymain(void)
+ 
+ #define TEST_DISK_TO_JSON(nme) TEST_DISK_TO_JSON_FULL(nme, false)
+ 
+-    if (!(diskxmljsondata.schema = testQEMUSchemaLoad())) {
+-        ret = -1;
+-        goto cleanup;
+-    }
++    diskxmljsondata.schema = qmp_schema_x86_64;
+ 
+     if (virQEMUQAPISchemaPathGet("blockdev-add/arg-type",
+                                  diskxmljsondata.schema,
+@@ -1045,7 +1048,9 @@ mymain(void)
+                        &imagecreatedata) < 0) \
+             ret = -1; \
+     } while (0)
+-    imagecreatedata.schema = diskxmljsondata.schema;
++
++    imagecreatedata.schema = qmp_schema_x86_64;
++
+     if (virQEMUQAPISchemaPathGet("blockdev-create/arg-type/options",
+                                  imagecreatedata.schema,
+                                  &imagecreatedata.schemaroot) < 0 ||
+@@ -1198,7 +1203,6 @@ mymain(void)
+     TEST_BITMAP_BLOCKCOPY("snapshots-deep", false, "snapshots");
+ 
+  cleanup:
+-    virHashFree(diskxmljsondata.schema);
+     qemuTestDriverFree(&driver);
+     VIR_FREE(capslatest_x86_64);
+     virObjectUnref(caps_x86_64);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-Test-backing-store-strings.patch b/SOURCES/libvirt-qemublocktest-Test-backing-store-strings.patch
new file mode 100644
index 0000000..97827fd
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-Test-backing-store-strings.patch
@@ -0,0 +1,1587 @@
+From 0d41c52b4ccd749e2c2c33bfe20c2f01d319a962 Mon Sep 17 00:00:00 2001
+Message-Id: <0d41c52b4ccd749e2c2c33bfe20c2f01d319a962@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:02 +0100
+Subject: [PATCH] qemublocktest: Test backing store strings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With -blockdev libvirt provides the string which is recorded  as
+'backing store' property of an image to qemu. Add testing for
+qemuBlockGetBackingStoreString which generates these strings as there's
+logic which determines which format to use.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 5f3b4a37275a4079949bb3428149ab310c6c4e2e)
+
+ Conflicts: tests/qemublocktest.c: virBufferTrim changes not backported
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <398610db4cddda5d1ec6dc3b67b2d4c68afbf32c.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |  20 ++-
+ .../xml2json/block-raw-noopts-srconly.json    |  13 +-
+ .../block-raw-reservations-srconly.json       |  13 +-
+ .../xml2json/dir-fat-cache-srconly.json       |  15 +-
+ .../xml2json/dir-fat-floppy-srconly.json      |  15 +-
+ .../xml2json/dir-fat-readonly-srconly.json    |  15 +-
+ ...ile-backing_basic-aio_threads-srconly.json |  68 +++++----
+ ...acking_basic-cache-directsync-srconly.json |  68 +++++----
+ ...file-backing_basic-cache-none-srconly.json |  68 +++++----
+ ...le-backing_basic-cache-unsafe-srconly.json |  68 +++++----
+ ...backing_basic-cache-writeback-srconly.json |  68 +++++----
+ ...king_basic-cache-writethrough-srconly.json |  68 +++++----
+ .../file-backing_basic-detect-srconly.json    |  68 +++++----
+ .../file-backing_basic-noopts-srconly.json    |  52 ++++---
+ ...le-backing_basic-unmap-detect-srconly.json |  68 +++++----
+ ...le-backing_basic-unmap-ignore-srconly.json |  68 +++++----
+ .../file-backing_basic-unmap-srconly.json     |  68 +++++----
+ .../xml2json/file-bochs-noopts-srconly.json   |  13 +-
+ .../xml2json/file-cloop-noopts-srconly.json   |  13 +-
+ .../xml2json/file-dmg-noopts-srconly.json     |  13 +-
+ .../xml2json/file-ploop-noopts-srconly.json   |  13 +-
+ ...cow2-backing-chain-encryption-srconly.json |  26 ++--
+ ...le-qcow2-backing-chain-noopts-srconly.json | 130 ++++++++++++------
+ ...w2-backing-chain-unterminated-srconly.json |  26 ++--
+ .../xml2json/file-raw-aio_native-srconly.json |  13 +-
+ .../xml2json/file-raw-luks-srconly.json       |  13 +-
+ .../xml2json/file-raw-noopts-srconly.json     |  13 +-
+ .../xml2json/file-vdi-noopts-srconly.json     |  13 +-
+ .../xml2json/file-vhd-noopts-srconly.json     |  13 +-
+ .../xml2json/file-vpc-noopts-srconly.json     |  13 +-
+ .../xml2json/network-nbd-tls-srconly.json     |  19 ++-
+ ...w2-backing-chain-cache-unsafe-srconly.json |  68 ++++++---
+ ...backing-chain-encryption_auth-srconly.json |  68 ++++++---
+ .../xml2json/nvme-raw-noopts-srconly.json     |  19 ++-
+ 34 files changed, 876 insertions(+), 433 deletions(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index c009db7996..cf56c8a983 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -184,6 +184,7 @@ struct testQemuDiskXMLToJSONImageData {
+     virJSONValuePtr formatprops;
+     virJSONValuePtr storageprops;
+     virJSONValuePtr storagepropssrc;
++    char *backingstore;
+ };
+ 
+ 
+@@ -210,6 +211,7 @@ testQemuDiskXMLToPropsClear(struct testQemuDiskXMLToJSONData *data)
+         virJSONValueFree(data->images[i].formatprops);
+         virJSONValueFree(data->images[i].storageprops);
+         virJSONValueFree(data->images[i].storagepropssrc);
++        g_free(data->images[i].backingstore);
+     }
+     data->nimages = 0;
+     VIR_FREE(data->images);
+@@ -287,6 +289,7 @@ testQemuDiskXMLToProps(const void *opaque)
+     }
+ 
+     for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
++        g_autofree char *backingstore = NULL;
+ 
+         if (testQemuDiskXMLToJSONFakeSecrets(n) < 0)
+             return -1;
+@@ -298,7 +301,8 @@ testQemuDiskXMLToProps(const void *opaque)
+ 
+         if (!(formatProps = qemuBlockStorageSourceGetBlockdevProps(n, n->backingStore)) ||
+             !(storageSrcOnlyProps = qemuBlockStorageSourceGetBackendProps(n, false, true, true)) ||
+-            !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false, true))) {
++            !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false, true)) ||
++            !(backingstore = qemuBlockGetBackingStoreString(n, true))) {
+             if (!data->fail) {
+                 VIR_TEST_VERBOSE("failed to generate qemu blockdev props");
+                 return -1;
+@@ -314,6 +318,7 @@ testQemuDiskXMLToProps(const void *opaque)
+         data->images[data->nimages].formatprops = g_steal_pointer(&formatProps);
+         data->images[data->nimages].storageprops = g_steal_pointer(&storageProps);
+         data->images[data->nimages].storagepropssrc = g_steal_pointer(&storageSrcOnlyProps);
++        data->images[data->nimages].backingstore = g_steal_pointer(&backingstore);
+ 
+         data->nimages++;
+     }
+@@ -425,10 +430,21 @@ testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque)
+     for (i = 0; i < data->nimages; i++) {
+         g_autofree char *jsonstr = NULL;
+ 
++        virBufferAddLit(&buf, "(\n");
++        virBufferAdjustIndent(&buf, 2);
++        virBufferAddLit(&buf, "source only properties:\n");
++
+         if (!(jsonstr = virJSONValueToString(data->images[i].storagepropssrc, true)))
+             return -1;
+ 
+-        virBufferAdd(&buf, jsonstr, -1);
++        virBufferAddStr(&buf, jsonstr);
++
++        virBufferAddLit(&buf, "backing store string:\n");
++        virBufferAddStr(&buf, data->images[i].backingstore);
++
++        virBufferTrim(&buf, "\n", -1);
++        virBufferAdjustIndent(&buf, -2);
++        virBufferAddLit(&buf, "\n)\n");
+     }
+ 
+     actual = virBufferContentAndReset(&buf);
+diff --git a/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json
+index 72f9067353..07f7390433 100644
+--- a/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "host_device",
+-  "filename": "/dev/blah"
+-}
++(
++  source only properties:
++  {
++    "driver": "host_device",
++    "filename": "/dev/blah"
++  }
++  backing store string:
++  /dev/blah
++)
+diff --git a/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json b/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json
+index 72f9067353..07f7390433 100644
+--- a/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json
++++ b/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "host_device",
+-  "filename": "/dev/blah"
+-}
++(
++  source only properties:
++  {
++    "driver": "host_device",
++    "filename": "/dev/blah"
++  }
++  backing store string:
++  /dev/blah
++)
+diff --git a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json
+index 6ec4f78d7b..8bc58fa033 100644
+--- a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json
++++ b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json
+@@ -1,5 +1,10 @@
+-{
+-  "driver": "vvfat",
+-  "dir": "/var/somefiles",
+-  "floppy": false
+-}
++(
++  source only properties:
++  {
++    "driver": "vvfat",
++    "dir": "/var/somefiles",
++    "floppy": false
++  }
++  backing store string:
++  /var/somefiles
++)
+diff --git a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json
+index 6b0388bc18..043b796435 100644
+--- a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json
++++ b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json
+@@ -1,5 +1,10 @@
+-{
+-  "driver": "vvfat",
+-  "dir": "/var/somefiles",
+-  "floppy": true
+-}
++(
++  source only properties:
++  {
++    "driver": "vvfat",
++    "dir": "/var/somefiles",
++    "floppy": true
++  }
++  backing store string:
++  /var/somefiles
++)
+diff --git a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json
+index 6ec4f78d7b..8bc58fa033 100644
+--- a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json
++++ b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json
+@@ -1,5 +1,10 @@
+-{
+-  "driver": "vvfat",
+-  "dir": "/var/somefiles",
+-  "floppy": false
+-}
++(
++  source only properties:
++  {
++    "driver": "vvfat",
++    "dir": "/var/somefiles",
++    "floppy": false
++  }
++  backing store string:
++  /var/somefiles
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json
+index dbdf6e563b..35a8c3af37 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json
+@@ -1,16 +1,36 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/c"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/c"
++  }
++  backing store string:
++  /var/lib/libvirt/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json
+index ea490b0034..65a3773b97 100644
+--- a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json
+@@ -1,24 +1,44 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
+-{
+-  "driver": "gluster",
+-  "volume": "images",
+-  "path": "c",
+-  "server": [
+-    {
+-      "type": "inet",
+-      "host": "test.org",
+-      "port": "24007"
+-    }
+-  ]
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/d"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
++(
++  source only properties:
++  {
++    "driver": "gluster",
++    "volume": "images",
++    "path": "c",
++    "server": [
++      {
++        "type": "inet",
++        "host": "test.org",
++        "port": "24007"
++      }
++    ]
++  }
++  backing store string:
++  gluster://test.org:24007/images/c
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/d"
++  }
++  backing store string:
++  /var/lib/libvirt/images/d
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json
+index 316dbc9df2..29644f8c0f 100644
+--- a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json
+@@ -1,8 +1,18 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/a"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/b"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/a"
++  }
++  backing store string:
++  /var/lib/libvirt/images/a
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/b"
++  }
++  backing store string:
++  /var/lib/libvirt/images/b
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json
+index d998acc194..7691609577 100644
+--- a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json
+@@ -1,40 +1,90 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1507297895"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1484071872"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1483615252"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1483605924"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1483605920"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1483546244"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1483545901"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1483545313"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1483536402"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.qcow2"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1507297895"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1507297895
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1484071872"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1484071872
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1483615252"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1483615252
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1483605924"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1483605924
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1483605920"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1483605920
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1483546244"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1483546244
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1483545901"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1483545901
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1483545313"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1483545313
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1483536402"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1483536402
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.qcow2"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.qcow2
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json
+index e0bce3bcd2..f2fd81184b 100644
+--- a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json
+@@ -1,8 +1,18 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1507297895"
+-}
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/rhel7.3.1484071872"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1507297895"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1507297895
++)
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/rhel7.3.1484071872"
++  }
++  backing store string:
++  /var/lib/libvirt/images/rhel7.3.1484071872
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json b/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json b/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json
+index 6d7088211f..c065e3fab0 100644
+--- a/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/luks.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/luks.img"
++  }
++  backing store string:
++  /path/luks.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json
+index bb3e8af9eb..a2b32b09e0 100644
+--- a/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/var/lib/libvirt/images/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/var/lib/libvirt/images/i.img"
++  }
++  backing store string:
++  /var/lib/libvirt/images/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json
+index c50fa903f5..58dd7e1c34 100644
+--- a/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json
+@@ -1,4 +1,9 @@
+-{
+-  "driver": "file",
+-  "filename": "/path/to/i.img"
+-}
++(
++  source only properties:
++  {
++    "driver": "file",
++    "filename": "/path/to/i.img"
++  }
++  backing store string:
++  /path/to/i.img
++)
+diff --git a/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json b/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json
+index 455f4e5140..606e68713a 100644
+--- a/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json
++++ b/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json
+@@ -1,8 +1,13 @@
+-{
+-  "driver": "nbd",
+-  "server": {
+-    "type": "inet",
+-    "host": "host1.example.com",
+-    "port": "10809"
++(
++  source only properties:
++  {
++    "driver": "nbd",
++    "server": {
++      "type": "inet",
++      "host": "host1.example.com",
++      "port": "10809"
++    }
+   }
+-}
++  backing store string:
++  nbd://host1.example.com:10809
++)
+diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json
+index 69ca9caf88..2d7eeb3bca 100644
+--- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json
++++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json
+@@ -1,22 +1,46 @@
+-{
+-  "driver": "rbd",
+-  "pool": "rbdpool",
+-  "image": "rbdimg",
+-  "server": [
+-    {
+-      "host": "host1.example.com",
+-      "port": "0"
+-    },
+-    {
+-      "host": "host2.example.com",
+-      "port": "0"
+-    }
+-  ]
+-}
+-{
+-  "driver": "iscsi",
+-  "portal": "example.org:3260",
+-  "target": "iscsitarget",
+-  "lun": 1,
+-  "transport": "tcp"
+-}
++(
++  source only properties:
++  {
++    "driver": "rbd",
++    "pool": "rbdpool",
++    "image": "rbdimg",
++    "server": [
++      {
++        "host": "host1.example.com",
++        "port": "0"
++      },
++      {
++        "host": "host2.example.com",
++        "port": "0"
++      }
++    ]
++  }
++  backing store string:
++  json:{
++    "driver": "rbd",
++    "pool": "rbdpool",
++    "image": "rbdimg",
++    "server": [
++      {
++        "host": "host1.example.com",
++        "port": "0"
++      },
++      {
++        "host": "host2.example.com",
++        "port": "0"
++      }
++    ]
++  }
++)
++(
++  source only properties:
++  {
++    "driver": "iscsi",
++    "portal": "example.org:3260",
++    "target": "iscsitarget",
++    "lun": 1,
++    "transport": "tcp"
++  }
++  backing store string:
++  iscsi://example.org:3260/iscsitarget/1
++)
+diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json
+index 6298329812..5679318fbe 100644
+--- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json
++++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json
+@@ -1,22 +1,46 @@
+-{
+-  "driver": "rbd",
+-  "pool": "rbdpool",
+-  "image": "rbdimg",
+-  "server": [
+-    {
+-      "host": "host1.example.com",
+-      "port": "0"
+-    },
+-    {
+-      "host": "host2.example.com",
+-      "port": "0"
+-    }
+-  ]
+-}
+-{
+-  "driver": "iscsi",
+-  "portal": "example.org:3260",
+-  "target": "iqn.2016-09.com.example:iscsitarget",
+-  "lun": 1,
+-  "transport": "tcp"
+-}
++(
++  source only properties:
++  {
++    "driver": "rbd",
++    "pool": "rbdpool",
++    "image": "rbdimg",
++    "server": [
++      {
++        "host": "host1.example.com",
++        "port": "0"
++      },
++      {
++        "host": "host2.example.com",
++        "port": "0"
++      }
++    ]
++  }
++  backing store string:
++  json:{
++    "driver": "rbd",
++    "pool": "rbdpool",
++    "image": "rbdimg",
++    "server": [
++      {
++        "host": "host1.example.com",
++        "port": "0"
++      },
++      {
++        "host": "host2.example.com",
++        "port": "0"
++      }
++    ]
++  }
++)
++(
++  source only properties:
++  {
++    "driver": "iscsi",
++    "portal": "example.org:3260",
++    "target": "iqn.2016-09.com.example:iscsitarget",
++    "lun": 1,
++    "transport": "tcp"
++  }
++  backing store string:
++  iscsi://example.org:3260/iqn.2016-09.com.example%3Aiscsitarget/1
++)
+diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
+index ed55c08cbf..970e1bb8af 100644
+--- a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
++++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
+@@ -1,5 +1,14 @@
+-{
+-  "driver": "nvme",
+-  "device": "0000:01:00.0",
+-  "namespace": 1
+-}
++(
++  source only properties:
++  {
++    "driver": "nvme",
++    "device": "0000:01:00.0",
++    "namespace": 1
++  }
++  backing store string:
++  json:{
++    "driver": "nvme",
++    "device": "0000:01:00.0",
++    "namespace": 1
++  }
++)
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemublocktest-XMLjsonXML-Test-formatting-parsing-of-modern-JSON.patch b/SOURCES/libvirt-qemublocktest-XMLjsonXML-Test-formatting-parsing-of-modern-JSON.patch
new file mode 100644
index 0000000..45c09be
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-XMLjsonXML-Test-formatting-parsing-of-modern-JSON.patch
@@ -0,0 +1,103 @@
+From 6b38c75d24769798a6152ebf69ec71a24a4a2e50 Mon Sep 17 00:00:00 2001
+Message-Id: <6b38c75d24769798a6152ebf69ec71a24a4a2e50@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:11 +0100
+Subject: [PATCH] qemublocktest: XMLjsonXML: Test formatting/parsing of modern
+ JSON
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The test was invoking the JSON formatter with the 'legacy' flag thus
+formatting bunch of obsolete JSON blockdev definitions. We also should
+test the modern ones. Add a boolean and re-run all the tests in both
+cases.
+
+Additionally for any modern invocation we should also validate that the
+output conforms to the QAPI schema.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 7f8d0ca56a8335b29f3973e5490815c7cfbeac13)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <df8b109c41f11362999ffb84b9d1cf477a89c8f4.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 28 +++++++++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 94f20eeb47..d2ba85c5e5 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -41,6 +41,9 @@ VIR_LOG_INIT("tests.storagetest");
+ struct testBackingXMLjsonXMLdata {
+     int type;
+     const char *xml;
++    bool legacy;
++    virHashTablePtr schema;
++    virJSONValuePtr schemaroot;
+ };
+ 
+ static int
+@@ -57,6 +60,7 @@ testBackingXMLjsonXML(const void *args)
+     g_autofree char *actualxml = NULL;
+     g_autoptr(virStorageSource) xmlsrc = NULL;
+     g_autoptr(virStorageSource) jsonsrc = NULL;
++    g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
+ 
+     if (!(xmlsrc = virStorageSourceNew()))
+         return -1;
+@@ -71,12 +75,27 @@ testBackingXMLjsonXML(const void *args)
+         return -1;
+     }
+ 
+-    if (!(backendprops = qemuBlockStorageSourceGetBackendProps(xmlsrc, true, false,
++    if (!(backendprops = qemuBlockStorageSourceGetBackendProps(xmlsrc,
++                                                               data->legacy,
++                                                               false,
+                                                                false))) {
+         fprintf(stderr, "failed to format disk source json\n");
+         return -1;
+     }
+ 
++    if (!data->legacy) {
++        if (testQEMUSchemaValidate(backendprops, data->schemaroot,
++                                   data->schema, &debug) < 0) {
++            g_autofree char *debugmsg = virBufferContentAndReset(&debug);
++            g_autofree char *debugprops = virJSONValueToString(backendprops, true);
++
++            VIR_TEST_VERBOSE("json does not conform to QAPI schema");
++            VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
++                           debugprops, NULLSTR(debugmsg));
++            return -1;
++        }
++    }
++
+     if (virJSONValueObjectCreate(&wrapper, "a:file", &backendprops, NULL) < 0)
+         return -1;
+ 
+@@ -907,6 +926,10 @@ mymain(void)
+     do { \
+         xmljsonxmldata.type = tpe; \
+         xmljsonxmldata.xml = xmlstr; \
++        xmljsonxmldata.legacy = true; \
++        if (virTestRun(virTestCounterNext(), testBackingXMLjsonXML, \
++                       &xmljsonxmldata) < 0) \
++        xmljsonxmldata.legacy = false; \
+         if (virTestRun(virTestCounterNext(), testBackingXMLjsonXML, \
+                        &xmljsonxmldata) < 0) \
+             ret = -1; \
+@@ -915,6 +938,9 @@ mymain(void)
+ #define TEST_JSON_FORMAT_NET(xmlstr) \
+     TEST_JSON_FORMAT(VIR_STORAGE_TYPE_NETWORK, xmlstr)
+ 
++    xmljsonxmldata.schema = qmp_schema_x86_64;
++    xmljsonxmldata.schemaroot = qmp_schemaroot_x86_64_blockdev_add;
++
+     TEST_JSON_FORMAT(VIR_STORAGE_TYPE_FILE, "<source file='/path/to/file'/>\n");
+ 
+     /* type VIR_STORAGE_TYPE_BLOCK is not tested since it parses back to 'file' */
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemublocktest-xml-json-Add-test-for-NVMe.patch b/SOURCES/libvirt-qemublocktest-xml-json-Add-test-for-NVMe.patch
new file mode 100644
index 0000000..f1f7077
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-xml-json-Add-test-for-NVMe.patch
@@ -0,0 +1,94 @@
+From 9fac737d1a60821d00d5c0352ee8c6b01f56d15c Mon Sep 17 00:00:00 2001
+Message-Id: <9fac737d1a60821d00d5c0352ee8c6b01f56d15c@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:25:56 +0100
+Subject: [PATCH] qemublocktest: xml->json: Add test for NVMe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Based on the configuration from the only qemuxml2argv test.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 2337dbfdd1271891e3aa56c3d01389030ca10741)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <3b5eb8505338de198ce8c783bffaecf2ee0127a3.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                              |  2 ++
+ .../xml2json/nvme-raw-noopts-srconly.json          |  5 +++++
+ .../xml2json/nvme-raw-noopts.json                  | 14 ++++++++++++++
+ .../qemublocktestdata/xml2json/nvme-raw-noopts.xml | 13 +++++++++++++
+ 4 files changed, 34 insertions(+)
+ create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
+ create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts.json
+ create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index cd7ea6bb2b..189e95f46a 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1203,6 +1203,8 @@ mymain(void)
+     TEST_DISK_TO_JSON("block-raw-noopts");
+     TEST_DISK_TO_JSON("block-raw-reservations");
+ 
++    TEST_DISK_TO_JSON("nvme-raw-noopts");
++
+ #define TEST_JSON_TO_JSON(nme) \
+     do { \
+         jsontojsondata.name = nme; \
+diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
+new file mode 100644
+index 0000000000..ed55c08cbf
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json
+@@ -0,0 +1,5 @@
++{
++  "driver": "nvme",
++  "device": "0000:01:00.0",
++  "namespace": 1
++}
+diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.json
+new file mode 100644
+index 0000000000..e18e96099c
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.json
+@@ -0,0 +1,14 @@
++{
++  "node-name": "0123456789ABCDEF0123456789ABCDE",
++  "read-only": false,
++  "driver": "raw",
++  "file": "0123456789ABCDEF0123456789ABCDE"
++}
++{
++  "driver": "nvme",
++  "device": "0000:01:00.0",
++  "namespace": 1,
++  "node-name": "0123456789ABCDEF0123456789ABCDE",
++  "auto-read-only": true,
++  "discard": "unmap"
++}
+diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml
+new file mode 100644
+index 0000000000..1e4dbd6e56
+--- /dev/null
++++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml
+@@ -0,0 +1,13 @@
++<disk type='nvme' device='disk'>
++  <driver name='qemu' type='raw'/>
++  <source type='pci' managed='yes' namespace='1'>
++    <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
++    <privateData>
++      <nodenames>
++        <nodename type='storage' name='0123456789ABCDEF0123456789ABCDE'/>
++        <nodename type='format' name='0123456789ABCDEF0123456789ABCDE'/>
++      </nodenames>
++    </privateData>
++  </source>
++  <target dev='vda' bus='virtio'/>
++</disk>
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemublocktest-xml-json-Refactor-cleanup-in-test-case-functions.patch b/SOURCES/libvirt-qemublocktest-xml-json-Refactor-cleanup-in-test-case-functions.patch
new file mode 100644
index 0000000..98a1655
--- /dev/null
+++ b/SOURCES/libvirt-qemublocktest-xml-json-Refactor-cleanup-in-test-case-functions.patch
@@ -0,0 +1,208 @@
+From 4adce466baf293c7b6c8751f3c295faef85b402e Mon Sep 17 00:00:00 2001
+Message-Id: <4adce466baf293c7b6c8751f3c295faef85b402e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:25:58 +0100
+Subject: [PATCH] qemublocktest: xml->json: Refactor cleanup in test case
+ functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use automatic variable clearing and remove the cleanup sections of
+testQemuDiskXMLToProps, testQemuDiskXMLToPropsValidateSchema and
+testQemuDiskXMLToPropsValidateFile.
+
+testQemuDiskXMLToPropsValidateFileSrcOnly already uses new helpers.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 4a9f355535f6af92731cd6e8afaf6cfde2751bf1)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <6f11c48265348f2fa72c51f637bb1339dd9d64ee.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 76 +++++++++++++++----------------------------
+ 1 file changed, 27 insertions(+), 49 deletions(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 189e95f46a..40aa1e2825 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -259,39 +259,38 @@ testQemuDiskXMLToProps(const void *opaque)
+     g_autoptr(virDomainDef) vmdef = NULL;
+     virDomainDiskDefPtr disk = NULL;
+     virStorageSourcePtr n;
+-    virJSONValuePtr formatProps = NULL;
+-    virJSONValuePtr storageProps = NULL;
++    g_autoptr(virJSONValue) formatProps = NULL;
++    g_autoptr(virJSONValue) storageProps = NULL;
+     g_autoptr(virJSONValue) storageSrcOnlyProps = NULL;
+-    char *xmlpath = NULL;
+-    char *xmlstr = NULL;
+-    int ret = -1;
++    g_autofree char *xmlpath = NULL;
++    g_autofree char *xmlstr = NULL;
+ 
+     xmlpath = g_strdup_printf("%s%s.xml", testQemuDiskXMLToJSONPath, data->name);
+ 
+     if (virTestLoadFile(xmlpath, &xmlstr) < 0)
+-        goto cleanup;
++        return -1;
+ 
+     /* qemu stores node names in the status XML portion */
+     if (!(disk = virDomainDiskDefParse(xmlstr, data->driver->xmlopt,
+                                        VIR_DOMAIN_DEF_PARSE_STATUS)))
+-        goto cleanup;
++        return -1;
+ 
+     if (!(vmdef = virDomainDefNew()) ||
+         virDomainDiskInsert(vmdef, disk) < 0)
+-        goto cleanup;
++        return -1;
+ 
+     if (qemuCheckDiskConfig(disk, data->qemuCaps) < 0 ||
+         qemuDomainDeviceDefValidateDisk(disk, data->qemuCaps) < 0) {
+         VIR_TEST_VERBOSE("invalid configuration for disk");
+-        goto cleanup;
++        return -1;
+     }
+ 
+     for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
+         if (testQemuDiskXMLToJSONFakeSecrets(n) < 0)
+-            goto cleanup;
++            return -1;
+ 
+         if (qemuDomainValidateStorageSource(n, data->qemuCaps) < 0)
+-            goto cleanup;
++            return -1;
+ 
+         qemuDomainPrepareDiskSourceData(disk, n);
+ 
+@@ -300,27 +299,20 @@ testQemuDiskXMLToProps(const void *opaque)
+             !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false, true))) {
+             if (!data->fail) {
+                 VIR_TEST_VERBOSE("failed to generate qemu blockdev props");
+-                goto cleanup;
++                return -1;
+             }
+         } else if (data->fail) {
+             VIR_TEST_VERBOSE("qemu blockdev props should have failed");
+-            goto cleanup;
++            return -1;
+         }
+ 
+         if (VIR_APPEND_ELEMENT(data->props, data->nprops, formatProps) < 0 ||
+             VIR_APPEND_ELEMENT(data->props, data->nprops, storageProps) < 0 ||
+             VIR_APPEND_ELEMENT(data->propssrc, data->npropssrc, storageSrcOnlyProps) < 0)
+-            goto cleanup;
++            return -1;
+     }
+ 
+-    ret = 0;
+-
+- cleanup:
+-    virJSONValueFree(formatProps);
+-    virJSONValueFree(storageProps);
+-    VIR_FREE(xmlpath);
+-    VIR_FREE(xmlstr);
+-    return ret;
++    return 0;
+ }
+ 
+ 
+@@ -328,9 +320,6 @@ static int
+ testQemuDiskXMLToPropsValidateSchema(const void *opaque)
+ {
+     struct testQemuDiskXMLToJSONData *data = (void *) opaque;
+-    virBuffer debug = VIR_BUFFER_INITIALIZER;
+-    char *propsstr = NULL;
+-    char *debugmsg = NULL;
+     int ret = 0;
+     size_t i;
+ 
+@@ -338,35 +327,31 @@ testQemuDiskXMLToPropsValidateSchema(const void *opaque)
+         return EXIT_AM_SKIP;
+ 
+     for (i = 0; i < data->nprops; i++) {
++        g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
++
+         if (testQEMUSchemaValidate(data->props[i], data->schemaroot,
+                                    data->schema, &debug) < 0) {
+-            debugmsg = virBufferContentAndReset(&debug);
+-            propsstr = virJSONValueToString(data->props[i], true);
++            g_autofree char *debugmsg = virBufferContentAndReset(&debug);
++            g_autofree char *propsstr = virJSONValueToString(data->props[i], true);
+             VIR_TEST_VERBOSE("json does not conform to QAPI schema");
+             VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
+                            propsstr, NULLSTR(debugmsg));
+-            VIR_FREE(debugmsg);
+-            VIR_FREE(propsstr);
+             ret = -1;
+         }
+-
+-        virBufferFreeAndReset(&debug);
+     }
+ 
+     for (i = 0; i < data->npropssrc; i++) {
++        g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
++
+         if (testQEMUSchemaValidate(data->propssrc[i], data->schemaroot,
+                                    data->schema, &debug) < 0) {
+-            debugmsg = virBufferContentAndReset(&debug);
+-            propsstr = virJSONValueToString(data->propssrc[i], true);
++            g_autofree char *debugmsg = virBufferContentAndReset(&debug);
++            g_autofree char *propsstr = virJSONValueToString(data->propssrc[i], true);
+             VIR_TEST_VERBOSE("json does not conform to QAPI schema");
+             VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
+                            propsstr, NULLSTR(debugmsg));
+-            VIR_FREE(debugmsg);
+-            VIR_FREE(propsstr);
+             ret = -1;
+         }
+-
+-        virBufferFreeAndReset(&debug);
+     }
+ 
+     return ret;
+@@ -378,9 +363,8 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque)
+ {
+     struct testQemuDiskXMLToJSONData *data = (void *) opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+-    char *jsonpath = NULL;
+-    char *actual = NULL;
+-    int ret = -1;
++    g_autofree char *jsonpath = NULL;
++    g_autofree char *actual = NULL;
+     size_t i;
+ 
+     if (data->fail)
+@@ -389,23 +373,17 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque)
+     jsonpath = g_strdup_printf("%s%s.json", testQemuDiskXMLToJSONPath, data->name);
+ 
+     for (i = 0; i < data->nprops; i++) {
+-        char *jsonstr;
++        g_autofree char *jsonstr = NULL;
+ 
+         if (!(jsonstr = virJSONValueToString(data->props[i], true)))
+-            goto cleanup;
++            return -1;
+ 
+         virBufferAdd(&buf, jsonstr, -1);
+-        VIR_FREE(jsonstr);
+     }
+ 
+     actual = virBufferContentAndReset(&buf);
+ 
+-    ret = virTestCompareToFile(actual, jsonpath);
+-
+- cleanup:
+-    VIR_FREE(jsonpath);
+-    VIR_FREE(actual);
+-    return ret;
++    return virTestCompareToFile(actual, jsonpath);
+ }
+ 
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuxml2argvtest-Add-test-case-for-disks-with-http-s-source.patch b/SOURCES/libvirt-qemuxml2argvtest-Add-test-case-for-disks-with-http-s-source.patch
new file mode 100644
index 0000000..55b7842
--- /dev/null
+++ b/SOURCES/libvirt-qemuxml2argvtest-Add-test-case-for-disks-with-http-s-source.patch
@@ -0,0 +1,166 @@
+From 566b77b94d498426062dfddaf5a8c77250ba0857 Mon Sep 17 00:00:00 2001
+Message-Id: <566b77b94d498426062dfddaf5a8c77250ba0857@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:00 +0100
+Subject: [PATCH] qemuxml2argvtest: Add test case for disks with http(s) source
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Upcoming patches will implement the support for sslverify, cookies,
+readahead, and timeout properties. Add a test file which will collect
+the cases.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 3dd7952f6f996d13a0a685e1300c178fd9be6658)
+
+ Conflicts:
+  tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args:
+  Test output differs on the '-cpu qemu64' line due to previous fixes
+  to the testsuite not being backported
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <4ff67b442d284d3e8cdc9564b9378990b57fa3c0.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ .../disk-network-http.x86_64-latest.args      | 56 +++++++++++++++++++
+ tests/qemuxml2argvdata/disk-network-http.xml  | 50 +++++++++++++++++
+ tests/qemuxml2argvtest.c                      |  1 +
+ 3 files changed, 107 insertions(+)
+ create mode 100644 tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+ create mode 100644 tests/qemuxml2argvdata/disk-network-http.xml
+
+diff --git a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+new file mode 100644
+index 0000000000..d39f357072
+--- /dev/null
++++ b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+@@ -0,0 +1,56 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-QEMUGuest1 \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-x86_64 \
++-name guest=QEMUGuest1,debug-threads=on \
++-S \
++-object secret,id=masterKey0,format=raw,\
++file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
++-machine pc,accel=kvm,usb=off,dump-guest-core=off \
++-m 214 \
++-overcommit mem-lock=off \
++-smp 1,sockets=1,cores=1,threads=1 \
++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,fd=1729,server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-no-acpi \
++-boot strict=on \
++-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
++-blockdev '{"driver":"http","url":"http://example.org:80/test.img",\
++"node-name":"libvirt-4-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-4-format","read-only":false,"driver":"raw",\
++"file":"libvirt-4-storage"}' \
++-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x2,drive=libvirt-4-format,\
++id=virtio-disk0,bootindex=1 \
++-blockdev '{"driver":"https","url":"https://example.org:443/test2.img",\
++"node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"raw",\
++"file":"libvirt-3-storage"}' \
++-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=libvirt-3-format,\
++id=virtio-disk1 \
++-blockdev '{"driver":"http","url":"http://example.org:1234/test3.img",\
++"node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-2-format","read-only":false,"driver":"raw",\
++"file":"libvirt-2-storage"}' \
++-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=libvirt-2-format,\
++id=virtio-disk2 \
++-blockdev '{"driver":"https","url":"https://example.org:1234/test4.img",\
++"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\
++"file":"libvirt-1-storage"}' \
++-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=libvirt-1-format,\
++id=virtio-disk3 \
++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
++resourcecontrol=deny \
++-msg timestamp=on
+diff --git a/tests/qemuxml2argvdata/disk-network-http.xml b/tests/qemuxml2argvdata/disk-network-http.xml
+new file mode 100644
+index 0000000000..83a9865c83
+--- /dev/null
++++ b/tests/qemuxml2argvdata/disk-network-http.xml
+@@ -0,0 +1,50 @@
++<domain type='kvm'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='http' name='test.img'>
++        <host name='example.org'/>
++      </source>
++      <target dev='vda' bus='virtio'/>
++    </disk>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='https' name='test2.img'>
++        <host name='example.org'/>
++      </source>
++      <target dev='vdb' bus='virtio'/>
++    </disk>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='http' name='test3.img'>
++        <host name='example.org' port='1234'/>
++      </source>
++      <target dev='vdc' bus='virtio'/>
++    </disk>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='https' name='test4.img'>
++        <host name='example.org' port='1234'/>
++      </source>
++      <target dev='vdd' bus='virtio'/>
++    </disk>
++    <controller type='usb' index='0'/>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index 265ffce465..7bc01d55d5 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1089,6 +1089,7 @@ mymain(void)
+             QEMU_CAPS_OBJECT_TLS_CREDS_X509, QEMU_CAPS_NBD_TLS);
+     DO_TEST_CAPS_VER("disk-network-tlsx509", "2.12.0");
+     DO_TEST_CAPS_LATEST("disk-network-tlsx509");
++    DO_TEST_CAPS_LATEST("disk-network-http");
+     driver.config->vxhsTLS = 0;
+     VIR_FREE(driver.config->vxhsTLSx509certdir);
+     DO_TEST("disk-no-boot", NONE);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-qemuxml2xmltest-Add-case-for-host-model-vendor_id.patch b/SOURCES/libvirt-qemuxml2xmltest-Add-case-for-host-model-vendor_id.patch
new file mode 100644
index 0000000..55abb7a
--- /dev/null
+++ b/SOURCES/libvirt-qemuxml2xmltest-Add-case-for-host-model-vendor_id.patch
@@ -0,0 +1,79 @@
+From a620d42d440828f1f978a75c01a9515d0c131721 Mon Sep 17 00:00:00 2001
+Message-Id: <a620d42d440828f1f978a75c01a9515d0c131721@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 20 Feb 2020 09:08:04 +0100
+Subject: [PATCH] qemuxml2xmltest: Add case for host-model vendor_id
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch shows a bug in our code: the
+
+    <model vendor_id="Libvirt QEMU"/>
+
+element present in the source XML is lost when the parsed CPU definition
+is formatted back to XML.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804549
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 1939fbef989e6990cb5dd2d2d7ff8ea002c517c2)
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <cef7f3e28619a9fc306f17eddaa6d81df5ce21c2.1582186015.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ .../cpu-host-model-vendor.xml                 | 28 +++++++++++++++++++
+ tests/qemuxml2xmltest.c                       |  1 +
+ 2 files changed, 29 insertions(+)
+ create mode 100644 tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml
+
+diff --git a/tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml b/tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml
+new file mode 100644
+index 0000000000..d2447ccd10
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/cpu-host-model-vendor.xml
+@@ -0,0 +1,28 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219100</memory>
++  <currentMemory unit='KiB'>219100</currentMemory>
++  <vcpu placement='static'>6</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='network'/>
++  </os>
++  <cpu mode='host-model' check='partial'/>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <controller type='usb' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='virtio'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </memballoon>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index a3c7f8fd47..7c105e5207 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -266,6 +266,7 @@ mymain(void)
+     DO_TEST("cpu-host-kvmclock", NONE);
+     DO_TEST("cpu-host-passthrough-features", NONE);
+     DO_TEST("cpu-host-model-features", NONE);
++    DO_TEST("cpu-host-model-vendor", NONE);
+     DO_TEST("clock-catchup", QEMU_CAPS_KVM_PIT_TICK_POLICY);
+     DO_TEST("kvmclock", NONE);
+     DO_TEST("clock-timer-hyperv-rtc", NONE);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-qemuxml2xmltest-Wire-up-disk-network-http-case.patch b/SOURCES/libvirt-qemuxml2xmltest-Wire-up-disk-network-http-case.patch
new file mode 100644
index 0000000..38d79bc
--- /dev/null
+++ b/SOURCES/libvirt-qemuxml2xmltest-Wire-up-disk-network-http-case.patch
@@ -0,0 +1,115 @@
+From eae7db4b5daa44a6bf83e2d57601d108d3b93beb Mon Sep 17 00:00:00 2001
+Message-Id: <eae7db4b5daa44a6bf83e2d57601d108d3b93beb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:39 +0200
+Subject: [PATCH] qemuxml2xmltest: Wire up 'disk-network-http' case
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit c34ec56abad4b2286ef82a0a3ab9deb4d807a9bf)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+
+Conflicts: The XML output file differs in the <cpu> element as changes
+           in default cpu handling were not backported.
+Message-Id: <dd5d567d2c6f0a0e50f9184360265fc0aff78296.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ .../disk-network-http.x86_64-latest.xml       | 68 +++++++++++++++++++
+ tests/qemuxml2xmltest.c                       |  2 +
+ 2 files changed, 70 insertions(+)
+ create mode 100644 tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
+
+diff --git a/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
+new file mode 100644
+index 0000000000..238a5fef58
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
+@@ -0,0 +1,68 @@
++<domain type='kvm'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='http' name='test.img'>
++        <host name='example.org' port='80'/>
++        <timeout seconds='1234'/>
++      </source>
++      <target dev='vda' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
++    </disk>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='https' name='test2.img'>
++        <host name='example.org' port='443'/>
++        <readahead size='1024'/>
++      </source>
++      <target dev='vdb' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </disk>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='http' name='test3.img'>
++        <host name='example.org' port='1234'/>
++        <cookies>
++          <cookie name='test'>testcookievalue</cookie>
++          <cookie name='test2'>blurb</cookie>
++        </cookies>
++      </source>
++      <target dev='vdc' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
++    </disk>
++    <disk type='network' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source protocol='https' name='test4.img'>
++        <host name='example.org' port='1234'/>
++        <ssl verify='no'/>
++        <cookies>
++          <cookie name='test'>testcookievalue</cookie>
++          <cookie name='test2'>blurb</cookie>
++        </cookies>
++      </source>
++      <target dev='vdd' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
++    </disk>
++    <controller type='usb' index='0' model='piix3-uhci'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index f77f59fa3c..15110dd104 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -1089,6 +1089,8 @@ mymain(void)
+     DO_TEST("disk-backing-chains-index", NONE);
+     DO_TEST("disk-backing-chains-noindex", NONE);
+ 
++    DO_TEST_CAPS_LATEST("disk-network-http");
++
+     DO_TEST("chardev-label",
+             QEMU_CAPS_DEVICE_VIRTIO_RNG);
+ 
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-qemuxml2xmltest-set-driver-as-privileged.patch b/SOURCES/libvirt-qemuxml2xmltest-set-driver-as-privileged.patch
new file mode 100644
index 0000000..51a7908
--- /dev/null
+++ b/SOURCES/libvirt-qemuxml2xmltest-set-driver-as-privileged.patch
@@ -0,0 +1,38 @@
+From dc5c05491ab6e66cb2ce411530cb24a2cd76763b Mon Sep 17 00:00:00 2001
+Message-Id: <dc5c05491ab6e66cb2ce411530cb24a2cd76763b@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:38 +0100
+Subject: [PATCH] qemuxml2xmltest: set driver as privileged
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some validation check might reject unprivileged drivers in the future.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 99dc98db3d3e2381f322120bf00c25ba0501b092)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <e97eb61c987fdb72ced457131c6c86260dd449a0.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ tests/qemuxml2xmltest.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index 7c105e5207..d58259587b 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -162,6 +162,7 @@ mymain(void)
+         return EXIT_FAILURE;
+ 
+     cfg = virQEMUDriverGetConfig(&driver);
++    driver.privileged = true;
+ 
+ # define DO_TEST_INTERNAL(_name, suffix, when, ...) \
+     do { \
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-rhel-Enable-usage-of-x-blockdev-reopen.patch b/SOURCES/libvirt-rhel-Enable-usage-of-x-blockdev-reopen.patch
new file mode 100644
index 0000000..94c53cd
--- /dev/null
+++ b/SOURCES/libvirt-rhel-Enable-usage-of-x-blockdev-reopen.patch
@@ -0,0 +1,186 @@
+From 0ca4a633af46f2e06d3ef831919ca75387f42103 Mon Sep 17 00:00:00 2001
+Message-Id: <0ca4a633af46f2e06d3ef831919ca75387f42103@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:34 +0100
+Subject: [PATCH] rhel: Enable usage of x-blockdev-reopen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RHEL-only
+
+Introduce a new capability QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API
+based on the presence of '__com.redhat_rhel-av-8_2_0-api' feature for
+'x-blockdev-reopen' which states that reopen works for what libvirt
+is going to use it and wire up code to call the x- prefixed command.
+
+This implementation will become dormant once qemu starts supporting
+upstream-stable blockdev-reopen.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1799013
+Message-Id: <098dc0e73e1b561af991f2a9ecf13436dde3b33d.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c        |  3 ++-
+ src/qemu/qemu_capabilities.c | 13 +++++++++++++
+ src/qemu/qemu_capabilities.h |  3 +++
+ src/qemu/qemu_monitor.c      |  5 +++--
+ src/qemu/qemu_monitor.h      |  3 ++-
+ src/qemu/qemu_monitor_json.c | 12 +++++++++---
+ src/qemu/qemu_monitor_json.h |  3 ++-
+ 7 files changed, 34 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 21c1ad9618..099ceeb802 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -3225,6 +3225,7 @@ qemuBlockReopenFormat(virDomainObjPtr vm,
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+     virQEMUDriverPtr driver = priv->driver;
+     g_autoptr(virJSONValue) reopenprops = NULL;
++    bool downstream = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API);
+     int rc;
+ 
+     /* If we are lacking the object here, qemu might have opened an image with
+@@ -3241,7 +3242,7 @@ qemuBlockReopenFormat(virDomainObjPtr vm,
+     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+         return -1;
+ 
+-    rc = qemuMonitorBlockdevReopen(priv->mon, &reopenprops);
++    rc = qemuMonitorBlockdevReopen(priv->mon, &reopenprops, downstream);
+ 
+     if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+         return -1;
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index a4046b09d6..0b4ed4253c 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -561,6 +561,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
+               "vhost-user-fs",
+               "blockdev-snapshot.allow-write-only-overlay",
+               "blockdev-reopen",
++
++              /* 355 */
++              "blockdev-reopen.__com.redhat_rhel-av-8_2_0-api"
+     );
+ 
+ 
+@@ -1419,6 +1422,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsNVDIMM[] = {
+ 
+ /* see documentation for virQEMUQAPISchemaPathGet for the query format */
+ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
++    { "x-blockdev-reopen/$__com.redhat_rhel-av-8_2_0-api", QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API },
+     { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
+     { "blockdev-add/arg-type/+gluster/debug", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
+     { "blockdev-add/arg-type/+vxhs", QEMU_CAPS_VXHS},
+@@ -4861,6 +4865,15 @@ virQEMUCapsInitProcessCaps(virQEMUCapsPtr qemuCaps)
+         virQEMUCapsGet(qemuCaps, QEMU_CAPS_SAVEVM_MONITOR_NODES))
+         virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKDEV);
+ 
++    /* RHEL-only:
++     * - if upstream blockdev-reopen is enabled, clear the downstream flag
++     * - if the downstream flag is present but not the upstream, assert the upstream flag too
++     */
++    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
++        virQEMUCapsClear(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API);
++    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API))
++        virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN);
++
+     virQEMUCapsInitProcessCapsInterlock(qemuCaps);
+ }
+ 
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index 8fdbe05638..0f7c586703 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -543,6 +543,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+     QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY, /* blockdev-snapshot has the 'allow-write-only-overlay' feature */
+     QEMU_CAPS_BLOCKDEV_REOPEN, /* 'blockdev-reopen' qmp command is supported */
+ 
++    /* 355 */
++    QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API, /* downstream support for blockdev reopen in rhel-av-8.2.0 */
++
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+ 
+diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
+index c4202d59af..5915035589 100644
+--- a/src/qemu/qemu_monitor.c
++++ b/src/qemu/qemu_monitor.c
+@@ -4409,14 +4409,15 @@ qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
+ 
+ int
+ qemuMonitorBlockdevReopen(qemuMonitorPtr mon,
+-                          virJSONValuePtr *props)
++                          virJSONValuePtr *props,
++                          bool downstream)
+ {
+     VIR_DEBUG("props=%p (node-name=%s)", *props,
+               NULLSTR(virJSONValueObjectGetString(*props, "node-name")));
+ 
+     QEMU_CHECK_MONITOR(mon);
+ 
+-    return qemuMonitorJSONBlockdevReopen(mon, props);
++    return qemuMonitorJSONBlockdevReopen(mon, props, downstream);
+ }
+ 
+ 
+diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
+index 481fc8e12e..ca975d084c 100644
+--- a/src/qemu/qemu_monitor.h
++++ b/src/qemu/qemu_monitor.h
+@@ -1326,7 +1326,8 @@ int qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
+                            virJSONValuePtr *props);
+ 
+ int qemuMonitorBlockdevReopen(qemuMonitorPtr mon,
+-                              virJSONValuePtr *props);
++                              virJSONValuePtr *props,
++                              bool downstream);
+ 
+ int qemuMonitorBlockdevDel(qemuMonitorPtr mon,
+                            const char *nodename);
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index 0122b77259..92d7317a82 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -8832,14 +8832,20 @@ qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
+ 
+ int
+ qemuMonitorJSONBlockdevReopen(qemuMonitorPtr mon,
+-                              virJSONValuePtr *props)
++                              virJSONValuePtr *props,
++                              bool downstream)
+ {
+     g_autoptr(virJSONValue) cmd = NULL;
+     g_autoptr(virJSONValue) reply = NULL;
+     virJSONValuePtr pr = g_steal_pointer(props);
+ 
+-    if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", pr)))
+-        return -1;
++    if (downstream) {
++        if (!(cmd = qemuMonitorJSONMakeCommandInternal("x-blockdev-reopen", pr)))
++            return -1;
++    } else {
++        if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", pr)))
++            return -1;
++    }
+ 
+     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+         return -1;
+diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
+index 801babef97..38c61a5661 100644
+--- a/src/qemu/qemu_monitor_json.h
++++ b/src/qemu/qemu_monitor_json.h
+@@ -601,7 +601,8 @@ int qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+ 
+ int qemuMonitorJSONBlockdevReopen(qemuMonitorPtr mon,
+-                                  virJSONValuePtr *props)
++                                  virJSONValuePtr *props,
++                                  bool downstream)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+ 
+ int qemuMonitorJSONBlockdevDel(qemuMonitorPtr mon,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-schema-wrap-fsDriver-in-a-choice-group.patch b/SOURCES/libvirt-schema-wrap-fsDriver-in-a-choice-group.patch
new file mode 100644
index 0000000..d8bfa52
--- /dev/null
+++ b/SOURCES/libvirt-schema-wrap-fsDriver-in-a-choice-group.patch
@@ -0,0 +1,89 @@
+From f37eb0d50ba30f036e08e8144bd52b3ebc1751e1 Mon Sep 17 00:00:00 2001
+Message-Id: <f37eb0d50ba30f036e08e8144bd52b3ebc1751e1@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:35 +0100
+Subject: [PATCH] schema: wrap fsDriver in a choice group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allow adding new groups without changing indentation.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Tested-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit 3913abd476cfe663db978d9110daa8bdc6d4e5b6)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <a802f84a40623bf55d9c1b1307a117b6e133daad.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ docs/schemas/domaincommon.rng | 50 +++++++++++++++++++----------------
+ 1 file changed, 27 insertions(+), 23 deletions(-)
+
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 38aef19e89..bfd8786ea8 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -2620,29 +2620,33 @@
+            for this kind of info, and 'type' for the
+            storage format. We need the latter too, so
+            had to invent a new attribute name -->
+-      <optional>
+-        <attribute name="type">
+-          <choice>
+-            <value>path</value>
+-            <value>handle</value>
+-            <value>loop</value>
+-            <value>nbd</value>
+-            <value>ploop</value>
+-          </choice>
+-        </attribute>
+-      </optional>
+-      <optional>
+-        <attribute name="format">
+-          <ref name="storageFormat"/>
+-        </attribute>
+-      </optional>
+-      <optional>
+-        <attribute name="wrpolicy">
+-          <value>immediate</value>
+-        </attribute>
+-      </optional>
+-      <ref name='virtioOptions'/>
+-      <empty/>
++      <choice>
++        <group>
++          <optional>
++            <attribute name="type">
++              <choice>
++                <value>path</value>
++                <value>handle</value>
++                <value>loop</value>
++                <value>nbd</value>
++                <value>ploop</value>
++              </choice>
++            </attribute>
++          </optional>
++          <optional>
++            <attribute name="format">
++              <ref name="storageFormat"/>
++            </attribute>
++          </optional>
++          <optional>
++            <attribute name="wrpolicy">
++              <value>immediate</value>
++            </attribute>
++          </optional>
++          <ref name='virtioOptions'/>
++        </group>
++        <empty/>
++      </choice>
+     </element>
+   </define>
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-schemas-rng-Use-interleave-in-the-disk-source-element.patch b/SOURCES/libvirt-schemas-rng-Use-interleave-in-the-disk-source-element.patch
new file mode 100644
index 0000000..ba85b9f
--- /dev/null
+++ b/SOURCES/libvirt-schemas-rng-Use-interleave-in-the-disk-source-element.patch
@@ -0,0 +1,497 @@
+From d7aeea8dfb78168ae305252bf581d46766496e24 Mon Sep 17 00:00:00 2001
+Message-Id: <d7aeea8dfb78168ae305252bf581d46766496e24@dist-git>
+From: Han Han <hhan@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:44 +0200
+Subject: [PATCH] schemas: rng: Use interleave in the disk source element
+
+Signed-off-by: Han Han <hhan@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit 8b41b21aee4fb3b0f5fed1ecc73c5a7fd6879a93)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <79373ae94fb73576d1433b22545327a4afca2d99.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/schemas/domaincommon.rng | 398 ++++++++++++++++++----------------
+ 1 file changed, 211 insertions(+), 187 deletions(-)
+
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index ac6f180382..e17f7ff8c0 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1642,21 +1642,23 @@
+     </optional>
+     <optional>
+       <element name="source">
+-        <optional>
+-          <attribute name="file">
+-            <ref name="absFilePath"/>
+-          </attribute>
+-        </optional>
+-        <ref name="diskSourceCommon"/>
+-        <optional>
+-          <ref name="storageStartupPolicy"/>
+-        </optional>
+-        <optional>
+-          <ref name="encryption"/>
+-        </optional>
+-        <zeroOrMore>
+-          <ref name='devSeclabel'/>
+-        </zeroOrMore>
++        <interleave>
++          <optional>
++            <attribute name="file">
++              <ref name="absFilePath"/>
++            </attribute>
++          </optional>
++          <ref name="diskSourceCommon"/>
++          <optional>
++            <ref name="storageStartupPolicy"/>
++          </optional>
++          <optional>
++            <ref name="encryption"/>
++          </optional>
++          <zeroOrMore>
++            <ref name='devSeclabel'/>
++          </zeroOrMore>
++        </interleave>
+       </element>
+     </optional>
+   </define>
+@@ -1667,24 +1669,26 @@
+     </attribute>
+     <optional>
+       <element name="source">
+-        <optional>
+-          <attribute name="dev">
+-            <ref name="absFilePath"/>
+-          </attribute>
+-        </optional>
+-        <ref name="diskSourceCommon"/>
+-        <optional>
+-          <ref name="storageStartupPolicy"/>
+-        </optional>
+-        <optional>
+-          <ref name="encryption"/>
+-        </optional>
+-        <optional>
+-          <ref name="reservations"/>
+-        </optional>
+-        <zeroOrMore>
+-          <ref name='devSeclabel'/>
+-        </zeroOrMore>
++        <interleave>
++          <optional>
++            <attribute name="dev">
++              <ref name="absFilePath"/>
++            </attribute>
++          </optional>
++          <ref name="diskSourceCommon"/>
++          <optional>
++            <ref name="storageStartupPolicy"/>
++          </optional>
++          <optional>
++            <ref name="encryption"/>
++          </optional>
++          <optional>
++            <ref name="reservations"/>
++          </optional>
++          <zeroOrMore>
++            <ref name='devSeclabel'/>
++          </zeroOrMore>
++        </interleave>
+       </element>
+     </optional>
+   </define>
+@@ -1695,17 +1699,19 @@
+     </attribute>
+     <optional>
+       <element name="source">
+-        <attribute name="dir">
+-          <ref name="absFilePath"/>
+-        </attribute>
+-        <ref name="diskSourceCommon"/>
+-        <optional>
+-          <ref name="storageStartupPolicy"/>
+-        </optional>
+-        <optional>
+-          <ref name="encryption"/>
+-        </optional>
+-        <empty/>
++        <interleave>
++          <attribute name="dir">
++            <ref name="absFilePath"/>
++          </attribute>
++          <ref name="diskSourceCommon"/>
++          <optional>
++            <ref name="storageStartupPolicy"/>
++          </optional>
++          <optional>
++            <ref name="encryption"/>
++          </optional>
++          <empty/>
++        </interleave>
+       </element>
+     </optional>
+   </define>
+@@ -1856,138 +1862,152 @@
+ 
+   <define name="diskSourceNetworkProtocolHTTPS">
+     <element name="source">
+-      <attribute name="protocol">
+-        <choice>
+-          <value>https</value>
+-        </choice>
+-      </attribute>
+-      <attribute name="name"/>
+-      <ref name="diskSourceCommon"/>
+-      <ref name="diskSourceNetworkHost"/>
+-      <optional>
+-        <ref name="encryption"/>
+-      </optional>
+-      <optional>
+-        <ref name="diskSourceNetworkProtocolSSLVerify"/>
+-      </optional>
+-      <optional>
+-        <ref name="diskSourceNetworkProtocolHTTPCookies"/>
+-      </optional>
+-      <ref name="diskSourceNetworkProtocolPropsCommon"/>
++      <interleave>
++        <attribute name="protocol">
++          <choice>
++            <value>https</value>
++          </choice>
++        </attribute>
++        <attribute name="name"/>
++        <ref name="diskSourceCommon"/>
++        <ref name="diskSourceNetworkHost"/>
++        <optional>
++          <ref name="encryption"/>
++        </optional>
++        <optional>
++          <ref name="diskSourceNetworkProtocolSSLVerify"/>
++        </optional>
++        <optional>
++          <ref name="diskSourceNetworkProtocolHTTPCookies"/>
++        </optional>
++        <ref name="diskSourceNetworkProtocolPropsCommon"/>
++        </interleave>
+     </element>
+   </define>
+ 
+   <define name="diskSourceNetworkProtocolHTTP">
+     <element name="source">
+-      <attribute name="protocol">
+-        <choice>
+-          <value>http</value>
+-        </choice>
+-      </attribute>
+-      <attribute name="name"/>
+-      <ref name="diskSourceCommon"/>
+-      <ref name="diskSourceNetworkHost"/>
+-      <optional>
+-        <ref name="encryption"/>
+-      </optional>
+-      <optional>
+-        <ref name="diskSourceNetworkProtocolHTTPCookies"/>
+-      </optional>
+-      <ref name="diskSourceNetworkProtocolPropsCommon"/>
++      <interleave>
++        <attribute name="protocol">
++          <choice>
++            <value>http</value>
++          </choice>
++        </attribute>
++        <attribute name="name"/>
++        <ref name="diskSourceCommon"/>
++        <ref name="diskSourceNetworkHost"/>
++        <optional>
++          <ref name="encryption"/>
++        </optional>
++        <optional>
++          <ref name="diskSourceNetworkProtocolHTTPCookies"/>
++        </optional>
++        <ref name="diskSourceNetworkProtocolPropsCommon"/>
++      </interleave>
+     </element>
+   </define>
+ 
+   <define name="diskSourceNetworkProtocolFTPS">
+     <element name="source">
+-      <attribute name="protocol">
+-        <choice>
+-          <value>ftps</value>
+-        </choice>
+-      </attribute>
+-      <attribute name="name"/>
+-      <ref name="diskSourceCommon"/>
+-      <ref name="diskSourceNetworkHost"/>
+-      <optional>
+-        <ref name="encryption"/>
+-      </optional>
+-      <optional>
+-        <ref name="diskSourceNetworkProtocolSSLVerify"/>
+-      </optional>
+-      <ref name="diskSourceNetworkProtocolPropsCommon"/>
++      <interleave>
++        <attribute name="protocol">
++          <choice>
++            <value>ftps</value>
++          </choice>
++        </attribute>
++        <attribute name="name"/>
++        <ref name="diskSourceCommon"/>
++        <ref name="diskSourceNetworkHost"/>
++        <optional>
++          <ref name="encryption"/>
++        </optional>
++        <optional>
++          <ref name="diskSourceNetworkProtocolSSLVerify"/>
++        </optional>
++        <ref name="diskSourceNetworkProtocolPropsCommon"/>
++      </interleave>
+     </element>
+   </define>
+ 
+   <define name="diskSourceNetworkProtocolSimple">
+     <element name="source">
+-      <attribute name="protocol">
+-        <choice>
+-          <value>sheepdog</value>
+-          <value>ftp</value>
+-          <value>tftp</value>
+-        </choice>
+-      </attribute>
+-      <attribute name="name"/>
+-      <ref name="diskSourceCommon"/>
+-      <ref name="diskSourceNetworkHost"/>
+-      <optional>
+-        <ref name="encryption"/>
+-      </optional>
+-      <ref name="diskSourceNetworkProtocolPropsCommon"/>
++      <interleave>
++        <attribute name="protocol">
++          <choice>
++            <value>sheepdog</value>
++            <value>ftp</value>
++            <value>tftp</value>
++          </choice>
++        </attribute>
++        <attribute name="name"/>
++        <ref name="diskSourceCommon"/>
++        <ref name="diskSourceNetworkHost"/>
++        <optional>
++          <ref name="encryption"/>
++        </optional>
++        <ref name="diskSourceNetworkProtocolPropsCommon"/>
++      </interleave>
+     </element>
+   </define>
+ 
+   <define name="diskSourceNetworkProtocolNBD">
+     <element name="source">
+-      <attribute name="protocol">
+-        <value>nbd</value>
+-      </attribute>
+-      <optional>
+-        <attribute name="name"/>
+-      </optional>
+-      <optional>
+-        <attribute name="tls">
+-          <ref name="virYesNo"/>
++      <interleave>
++        <attribute name="protocol">
++          <value>nbd</value>
+         </attribute>
+-      </optional>
+-      <ref name="diskSourceCommon"/>
+-      <ref name="diskSourceNetworkHost"/>
+-      <optional>
+-        <ref name="encryption"/>
+-      </optional>
++        <optional>
++          <attribute name="name"/>
++        </optional>
++        <optional>
++          <attribute name="tls">
++            <ref name="virYesNo"/>
++          </attribute>
++        </optional>
++        <ref name="diskSourceCommon"/>
++        <ref name="diskSourceNetworkHost"/>
++        <optional>
++          <ref name="encryption"/>
++        </optional>
++      </interleave>
+     </element>
+   </define>
+ 
+   <define name="diskSourceNetworkProtocolGluster">
+     <element name="source">
+-      <attribute name="protocol">
+-        <value>gluster</value>
+-      </attribute>
+-      <attribute name="name"/>
+-      <ref name="diskSourceCommon"/>
+-      <oneOrMore>
+-        <ref name="diskSourceNetworkHost"/>
+-      </oneOrMore>
+-      <optional>
+-        <ref name="encryption"/>
+-      </optional>
++      <interleave>
++        <attribute name="protocol">
++          <value>gluster</value>
++        </attribute>
++        <attribute name="name"/>
++        <ref name="diskSourceCommon"/>
++        <oneOrMore>
++          <ref name="diskSourceNetworkHost"/>
++        </oneOrMore>
++        <optional>
++          <ref name="encryption"/>
++        </optional>
++      </interleave>
+     </element>
+   </define>
+ 
+   <define name="diskSourceNetworkProtocolVxHS">
+     <element name="source">
+-      <attribute name="protocol">
+-        <choice>
+-          <value>vxhs</value>
+-        </choice>
+-      </attribute>
+-      <attribute name="name"/>
+-      <ref name="diskSourceCommon"/>
+-      <optional>
+-        <attribute name="tls">
+-          <ref name="virYesNo"/>
++      <interleave>
++        <attribute name="protocol">
++          <choice>
++            <value>vxhs</value>
++          </choice>
+         </attribute>
+-      </optional>
+-      <ref name="diskSourceNetworkHost"/>
++        <attribute name="name"/>
++        <ref name="diskSourceCommon"/>
++        <optional>
++          <attribute name="tls">
++            <ref name="virYesNo"/>
++          </attribute>
++        </optional>
++        <ref name="diskSourceNetworkHost"/>
++      </interleave>
+     </element>
+   </define>
+ 
+@@ -2014,30 +2034,32 @@
+     </attribute>
+     <optional>
+       <element name="source">
+-        <attribute name="pool">
+-          <ref name="poolName"/>
+-        </attribute>
+-        <attribute name="volume">
+-          <ref name="volName"/>
+-        </attribute>
+-        <optional>
+-          <attribute name="mode">
+-            <choice>
+-              <value>host</value>
+-              <value>direct</value>
+-            </choice>
++        <interleave>
++          <attribute name="pool">
++            <ref name="poolName"/>
+           </attribute>
+-        </optional>
+-        <ref name="diskSourceCommon"/>
+-        <optional>
+-          <ref name="storageStartupPolicy"/>
+-        </optional>
+-        <optional>
+-          <ref name="encryption"/>
+-        </optional>
+-        <zeroOrMore>
+-          <ref name='devSeclabel'/>
+-        </zeroOrMore>
++          <attribute name="volume">
++            <ref name="volName"/>
++          </attribute>
++          <optional>
++            <attribute name="mode">
++              <choice>
++                <value>host</value>
++                <value>direct</value>
++              </choice>
++            </attribute>
++          </optional>
++          <ref name="diskSourceCommon"/>
++          <optional>
++            <ref name="storageStartupPolicy"/>
++          </optional>
++          <optional>
++            <ref name="encryption"/>
++          </optional>
++          <zeroOrMore>
++            <ref name='devSeclabel'/>
++          </zeroOrMore>
++        </interleave>
+       </element>
+     </optional>
+   </define>
+@@ -2048,27 +2070,29 @@
+     </attribute>
+     <optional>
+       <element name="source">
+-        <attribute name="type">
+-          <value>pci</value>
+-        </attribute>
+-        <attribute name="namespace">
+-          <ref name="uint32"/>
+-        </attribute>
+-        <optional>
+-          <attribute name="managed">
+-            <ref name="virYesNo"/>
++        <interleave>
++          <attribute name="type">
++            <value>pci</value>
+           </attribute>
+-        </optional>
+-        <element name="address">
+-          <ref name="pciaddress"/>
+-        </element>
+-        <ref name="diskSourceCommon"/>
+-        <optional>
+-          <ref name="storageStartupPolicy"/>
+-        </optional>
+-        <optional>
+-          <ref name="encryption"/>
+-        </optional>
++          <attribute name="namespace">
++            <ref name="uint32"/>
++          </attribute>
++          <optional>
++            <attribute name="managed">
++              <ref name="virYesNo"/>
++            </attribute>
++          </optional>
++          <element name="address">
++            <ref name="pciaddress"/>
++          </element>
++          <ref name="diskSourceCommon"/>
++          <optional>
++            <ref name="storageStartupPolicy"/>
++          </optional>
++          <optional>
++            <ref name="encryption"/>
++          </optional>
++        </interleave>
+       </element>
+     </optional>
+   </define>
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-security-Don-t-fail-if-locking-a-file-on-NFS-mount-fails.patch b/SOURCES/libvirt-security-Don-t-fail-if-locking-a-file-on-NFS-mount-fails.patch
new file mode 100644
index 0000000..0c4c782
--- /dev/null
+++ b/SOURCES/libvirt-security-Don-t-fail-if-locking-a-file-on-NFS-mount-fails.patch
@@ -0,0 +1,45 @@
+From 4f9e2b4b36fda208d25acf4126abbf4fee37f0b5 Mon Sep 17 00:00:00 2001
+Message-Id: <4f9e2b4b36fda208d25acf4126abbf4fee37f0b5@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Tue, 25 Feb 2020 11:24:52 +0100
+Subject: [PATCH] security: Don't fail if locking a file on NFS mount fails
+
+The way that our file locking works is that we open() the file we
+want to lock and then use fcntl(fd, F_SETLKW, ...) to lock it.
+The problem is, we are doing all of these as root which doesn't
+work if the file lives on root squashed NFS, because if it does
+then the open() fails. The way to resolve this is to make this a
+non fatal error and leave callers deal with this (i.e. disable
+remembering) - implemented in the previous commit.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804672
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit f16663d58f7aab6bf800fcffd34f83f522927897)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <d3cb3d3214cf3e67bd357fa9781ce55f8dc8c751.1582626185.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/security/security_manager.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/security/security_manager.c b/src/security/security_manager.c
+index 9d06316a99..23ed6a127c 100644
+--- a/src/security/security_manager.c
++++ b/src/security/security_manager.c
+@@ -1343,6 +1343,11 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
+                 continue;
+             }
+ 
++            if (virFileIsSharedFS(p)) {
++                /* Probably a root squashed NFS. */
++                continue;
++            }
++
+             virReportSystemError(errno,
+                                  _("unable to open %s"),
+                                  p);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-security-Don-t-remember-seclabel-for-paths-we-haven-t-locked-successfully.patch b/SOURCES/libvirt-security-Don-t-remember-seclabel-for-paths-we-haven-t-locked-successfully.patch
new file mode 100644
index 0000000..69cd76d
--- /dev/null
+++ b/SOURCES/libvirt-security-Don-t-remember-seclabel-for-paths-we-haven-t-locked-successfully.patch
@@ -0,0 +1,117 @@
+From f08dc7e622b398b00d6916ead44a8c9058b5a17e Mon Sep 17 00:00:00 2001
+Message-Id: <f08dc7e622b398b00d6916ead44a8c9058b5a17e@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Tue, 25 Feb 2020 11:24:51 +0100
+Subject: [PATCH] security: Don't remember seclabel for paths we haven't locked
+ successfully
+
+There are some cases where we want to remember the original owner
+of a file but we fail to lock it for XATTR change (e.g. root
+squashed NFS). If that is the case we error out and refuse to
+start a domain. Well, we can do better if we disable remembering
+for paths we haven't locked successfully.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 5fddf61351f44e4186c0313d81907024c574201b)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1804672
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <4c2586a6da3b01adce09573a6123a15b3aea5ae6.1582626185.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/security/security_dac.c     | 14 ++++++++++++++
+ src/security/security_manager.c |  7 -------
+ src/security/security_manager.h |  6 ++++++
+ src/security/security_selinux.c | 14 ++++++++++++++
+ 4 files changed, 34 insertions(+), 7 deletions(-)
+
+diff --git a/src/security/security_dac.c b/src/security/security_dac.c
+index 2561ee440e..0cfe3626d4 100644
+--- a/src/security/security_dac.c
++++ b/src/security/security_dac.c
+@@ -240,6 +240,20 @@ virSecurityDACTransactionRun(pid_t pid G_GNUC_UNUSED,
+ 
+         if (!(state = virSecurityManagerMetadataLock(list->manager, paths, npaths)))
+             goto cleanup;
++
++        for (i = 0; i < list->nItems; i++) {
++            virSecurityDACChownItemPtr item = list->items[i];
++            size_t j;
++
++            for (j = 0; j < state->nfds; j++) {
++                if (STREQ_NULLABLE(item->path, state->paths[j]))
++                    break;
++            }
++
++            /* If path wasn't locked, don't try to remember its label. */
++            if (j == state->nfds)
++                item->remember = false;
++        }
+     }
+ 
+     for (i = 0; i < list->nItems; i++) {
+diff --git a/src/security/security_manager.c b/src/security/security_manager.c
+index 05d20e36af..9d06316a99 100644
+--- a/src/security/security_manager.c
++++ b/src/security/security_manager.c
+@@ -1245,13 +1245,6 @@ virSecurityManagerRestoreTPMLabels(virSecurityManagerPtr mgr,
+ }
+ 
+ 
+-struct _virSecurityManagerMetadataLockState {
+-    size_t nfds; /* Captures size of both @fds and @paths */
+-    int *fds;
+-    const char **paths;
+-};
+-
+-
+ static int
+ cmpstringp(const void *p1, const void *p2)
+ {
+diff --git a/src/security/security_manager.h b/src/security/security_manager.h
+index f835356b7e..b92ea5dc87 100644
+--- a/src/security/security_manager.h
++++ b/src/security/security_manager.h
+@@ -203,6 +203,12 @@ int virSecurityManagerRestoreTPMLabels(virSecurityManagerPtr mgr,
+ 
+ typedef struct _virSecurityManagerMetadataLockState virSecurityManagerMetadataLockState;
+ typedef virSecurityManagerMetadataLockState *virSecurityManagerMetadataLockStatePtr;
++struct _virSecurityManagerMetadataLockState {
++    size_t nfds; /* Captures size of both @fds and @paths */
++    int *fds;
++    const char **paths;
++};
++
+ 
+ virSecurityManagerMetadataLockStatePtr
+ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr,
+diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
+index 21279e7622..d7362327e6 100644
+--- a/src/security/security_selinux.c
++++ b/src/security/security_selinux.c
+@@ -271,6 +271,20 @@ virSecuritySELinuxTransactionRun(pid_t pid G_GNUC_UNUSED,
+ 
+         if (!(state = virSecurityManagerMetadataLock(list->manager, paths, npaths)))
+             goto cleanup;
++
++        for (i = 0; i < list->nItems; i++) {
++            virSecuritySELinuxContextItemPtr item = list->items[i];
++            size_t j;
++
++            for (j = 0; j < state->nfds; j++) {
++                if (STREQ_NULLABLE(item->path, state->paths[j]))
++                    break;
++            }
++
++            /* If path wasn't locked, don't try to remember its label. */
++            if (j == state->nfds)
++                item->remember = false;
++        }
+     }
+ 
+     rv = 0;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-security-Introduce-VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP-flag.patch b/SOURCES/libvirt-security-Introduce-VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP-flag.patch
new file mode 100644
index 0000000..0aad95b
--- /dev/null
+++ b/SOURCES/libvirt-security-Introduce-VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP-flag.patch
@@ -0,0 +1,182 @@
+From 04b7241a14015f67b68d9779be71f9e8f91791c3 Mon Sep 17 00:00:00 2001
+Message-Id: <04b7241a14015f67b68d9779be71f9e8f91791c3@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Mon, 9 Mar 2020 14:58:56 +0100
+Subject: [PATCH] security: Introduce
+ VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP flag
+
+Our decision whether to remember seclabel for a disk image
+depends on a few factors. If the image is readonly or shared or
+not the chain top the remembering is suppressed for the image.
+However, the virSecurityManagerSetImageLabel() is too low level
+to determine whether passed @src is chain top or not. Even though
+the function has the @parent argument it does not necessarily
+reflect the chain top - it only points to the top level image in
+the chain we want to relabel and not to the topmost image of the
+whole chain. And this can't be derived from the passed domain
+definition reliably neither - in some cases (like snapshots or
+block copy) the @src is added to the definition only after the
+operation succeeded. Therefore, introduce a flag which callers
+can use to help us with the decision.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 62f3d8adbc0381223499ff2bef45b23e7dca401d)
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1803551
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <bd4b1cca6feabd0c6d421603abe38397090c5394.1583760062.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/security/security_dac.c     | 15 ++++++++++-----
+ src/security/security_manager.h |  4 ++++
+ src/security/security_selinux.c | 17 +++++++++++------
+ 3 files changed, 25 insertions(+), 11 deletions(-)
+
+diff --git a/src/security/security_dac.c b/src/security/security_dac.c
+index 0cfe3626d4..66906245eb 100644
+--- a/src/security/security_dac.c
++++ b/src/security/security_dac.c
+@@ -885,14 +885,14 @@ static int
+ virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr,
+                                     virDomainDefPtr def,
+                                     virStorageSourcePtr src,
+-                                    virStorageSourcePtr parent)
++                                    virStorageSourcePtr parent,
++                                    bool isChainTop)
+ {
+     virSecurityLabelDefPtr secdef;
+     virSecurityDeviceLabelDefPtr disk_seclabel;
+     virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
+     virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+     bool remember;
+-    bool is_toplevel = parent == src || parent->externalDataStore == src;
+     uid_t user;
+     gid_t group;
+ 
+@@ -950,7 +950,7 @@ virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr,
+      * but the top layer, or read only image, or disk explicitly
+      * marked as shared.
+      */
+-    remember = is_toplevel && !src->readonly && !src->shared;
++    remember = isChainTop && !src->readonly && !src->shared;
+ 
+     return virSecurityDACSetOwnership(mgr, src, NULL, user, group, remember);
+ }
+@@ -966,7 +966,9 @@ virSecurityDACSetImageLabelRelative(virSecurityManagerPtr mgr,
+     virStorageSourcePtr n;
+ 
+     for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
+-        if (virSecurityDACSetImageLabelInternal(mgr, def, n, parent) < 0)
++        const bool isChainTop = flags & VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
++
++        if (virSecurityDACSetImageLabelInternal(mgr, def, n, parent, isChainTop) < 0)
+             return -1;
+ 
+         if (n->externalDataStore &&
+@@ -979,6 +981,8 @@ virSecurityDACSetImageLabelRelative(virSecurityManagerPtr mgr,
+ 
+         if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN))
+             break;
++
++        flags &= ~VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
+     }
+ 
+     return 0;
+@@ -2106,7 +2110,8 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
+         if (virDomainDiskGetType(def->disks[i]) == VIR_STORAGE_TYPE_DIR)
+             continue;
+         if (virSecurityDACSetImageLabel(mgr, def, def->disks[i]->src,
+-                                        VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN) < 0)
++                                        VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN |
++                                        VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP) < 0)
+             return -1;
+     }
+ 
+diff --git a/src/security/security_manager.h b/src/security/security_manager.h
+index b92ea5dc87..7699bcbc6f 100644
+--- a/src/security/security_manager.h
++++ b/src/security/security_manager.h
+@@ -151,6 +151,10 @@ virSecurityManagerPtr* virSecurityManagerGetNested(virSecurityManagerPtr mgr);
+ 
+ typedef enum {
+     VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN = 1 << 0,
++    /* The VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP should be set if the
++     * image passed to virSecurityManagerSetImageLabel() is the top parent of
++     * the whole backing chain. */
++    VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP = 1 << 1,
+ } virSecurityDomainImageLabelFlags;
+ 
+ int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
+diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
+index d7362327e6..985c7eda1a 100644
+--- a/src/security/security_selinux.c
++++ b/src/security/security_selinux.c
+@@ -1824,7 +1824,8 @@ static int
+ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
+                                         virDomainDefPtr def,
+                                         virStorageSourcePtr src,
+-                                        virStorageSourcePtr parent)
++                                        virStorageSourcePtr parent,
++                                        bool isChainTop)
+ {
+     virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+     virSecurityLabelDefPtr secdef;
+@@ -1832,7 +1833,6 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
+     virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
+     char *use_label = NULL;
+     bool remember;
+-    bool is_toplevel = parent == src || parent->externalDataStore == src;
+     g_autofree char *vfioGroupDev = NULL;
+     const char *path = src->path;
+     int ret;
+@@ -1856,7 +1856,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
+      * but the top layer, or read only image, or disk explicitly
+      * marked as shared.
+      */
+-    remember = is_toplevel && !src->readonly && !src->shared;
++    remember = isChainTop && !src->readonly && !src->shared;
+ 
+     disk_seclabel = virStorageSourceGetSecurityLabelDef(src,
+                                                         SECURITY_SELINUX_NAME);
+@@ -1873,7 +1873,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
+             return 0;
+ 
+         use_label = parent_seclabel->label;
+-    } else if (is_toplevel) {
++    } else if (parent == src || parent->externalDataStore == src) {
+         if (src->shared) {
+             use_label = data->file_context;
+         } else if (src->readonly) {
+@@ -1930,7 +1930,9 @@ virSecuritySELinuxSetImageLabelRelative(virSecurityManagerPtr mgr,
+     virStorageSourcePtr n;
+ 
+     for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
+-        if (virSecuritySELinuxSetImageLabelInternal(mgr, def, n, parent) < 0)
++        const bool isChainTop = flags & VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
++
++        if (virSecuritySELinuxSetImageLabelInternal(mgr, def, n, parent, isChainTop) < 0)
+             return -1;
+ 
+         if (n->externalDataStore &&
+@@ -1943,6 +1945,8 @@ virSecuritySELinuxSetImageLabelRelative(virSecurityManagerPtr mgr,
+ 
+         if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN))
+             break;
++
++        flags &= ~VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
+     }
+ 
+     return 0;
+@@ -3142,7 +3146,8 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
+             continue;
+         }
+         if (virSecuritySELinuxSetImageLabel(mgr, def, def->disks[i]->src,
+-                                            VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN) < 0)
++                                            VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN |
++                                            VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP) < 0)
+             return -1;
+     }
+     /* XXX fixme process  def->fss if relabel == true */
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-storage-Implement-backing-store-support-for-fat-prefix.patch b/SOURCES/libvirt-storage-Implement-backing-store-support-for-fat-prefix.patch
new file mode 100644
index 0000000..7bce538
--- /dev/null
+++ b/SOURCES/libvirt-storage-Implement-backing-store-support-for-fat-prefix.patch
@@ -0,0 +1,123 @@
+From 32163ac7b599b20c09458170e626784c0c9b4d9c Mon Sep 17 00:00:00 2001
+Message-Id: <32163ac7b599b20c09458170e626784c0c9b4d9c@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:04 +0100
+Subject: [PATCH] storage: Implement backing store support for "fat:" prefix
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+qemublocktest showed that we don't add the "fat:" prefix for directory
+storage when formatting the backing store string. While it's unlikely to
+be used it's simple enough to actually implement the support rather than
+trying to forbid it.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 5a70f1048fb60b72d5a715d93e963ba07e041e23)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <52a96160554678625eea409b7c816de12eeace1a.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_block.c                                    | 7 ++++++-
+ src/util/virstoragefile.c                                | 9 +++++++++
+ .../xml2json/dir-fat-cache-srconly.json                  | 2 +-
+ .../xml2json/dir-fat-floppy-srconly.json                 | 2 +-
+ .../xml2json/dir-fat-readonly-srconly.json               | 2 +-
+ tests/virstoragetest.c                                   | 1 +
+ 6 files changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 20579ec7b3..5a7364576a 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2032,8 +2032,13 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
+     g_autofree char *backingJSON = NULL;
+ 
+     if (!src->sliceStorage) {
+-        if (virStorageSourceIsLocalStorage(src))
++        if (virStorageSourceIsLocalStorage(src)) {
++            if (src->type == VIR_STORAGE_TYPE_DIR &&
++                src->format == VIR_STORAGE_FILE_FAT)
++                return g_strdup_printf("fat:%s", src->path);
++
+             return g_strdup(src->path);
++        }
+ 
+         /* generate simplified URIs for the easy cases */
+         if (actualType == VIR_STORAGE_TYPE_NETWORK &&
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 2e54620139..5423f0b955 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3922,6 +3922,7 @@ virStorageSourceNewFromBackingAbsolute(const char *path,
+                                        virStorageSourcePtr *src)
+ {
+     const char *json;
++    const char *dirpath;
+     int rc = 0;
+     g_autoptr(virStorageSource) def = NULL;
+ 
+@@ -3935,6 +3936,14 @@ virStorageSourceNewFromBackingAbsolute(const char *path,
+ 
+         def->path = g_strdup(path);
+     } else {
++        if ((dirpath = STRSKIP(path, "fat:"))) {
++            def->type = VIR_STORAGE_TYPE_DIR;
++            def->format = VIR_STORAGE_FILE_FAT;
++            def->path = g_strdup(dirpath);
++            *src = g_steal_pointer(&def);
++            return 0;
++        }
++
+         def->type = VIR_STORAGE_TYPE_NETWORK;
+ 
+         VIR_DEBUG("parsing backing store string: '%s'", path);
+diff --git a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json
+index 8bc58fa033..80f866f08b 100644
+--- a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json
++++ b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json
+@@ -6,5 +6,5 @@
+     "floppy": false
+   }
+   backing store string:
+-  /var/somefiles
++  fat:/var/somefiles
+ )
+diff --git a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json
+index 043b796435..6c86f1da06 100644
+--- a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json
++++ b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json
+@@ -6,5 +6,5 @@
+     "floppy": true
+   }
+   backing store string:
+-  /var/somefiles
++  fat:/var/somefiles
+ )
+diff --git a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json
+index 8bc58fa033..80f866f08b 100644
+--- a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json
++++ b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json
+@@ -6,5 +6,5 @@
+     "floppy": false
+   }
+   backing store string:
+-  /var/somefiles
++  fat:/var/somefiles
+ )
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index ca428f5ca7..a61522965b 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1225,6 +1225,7 @@ mymain(void)
+     TEST_BACKING_PARSE_FULL(bck, xml, 0)
+ 
+     TEST_BACKING_PARSE("path", "<source file='path'/>\n");
++    TEST_BACKING_PARSE("fat:/somedir", "<source dir='/somedir'/>\n");
+     TEST_BACKING_PARSE("://", NULL);
+     TEST_BACKING_PARSE("http://example.com",
+                        "<source protocol='http' name=''>\n"
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-storage-Parse-nvme-disk-source-properties-from-json-pseudo-uri.patch b/SOURCES/libvirt-storage-Parse-nvme-disk-source-properties-from-json-pseudo-uri.patch
new file mode 100644
index 0000000..92fd51d
--- /dev/null
+++ b/SOURCES/libvirt-storage-Parse-nvme-disk-source-properties-from-json-pseudo-uri.patch
@@ -0,0 +1,115 @@
+From 52f32252c985693be402c5a1fba79d21807a53cb Mon Sep 17 00:00:00 2001
+Message-Id: <52f32252c985693be402c5a1fba79d21807a53cb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:08 +0100
+Subject: [PATCH] storage: Parse 'nvme' disk source properties from json:{}
+ pseudo-uri
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Our code allows snapshots of NVMe based disks which means we create
+overlay file with a 'json:{}' pseudo-uri refering to the NVME device.
+Our parser code doesn't handle them though. Add the parser and test it
+via the XML->json->XML round-trip and reference data.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 1b84dd190c16695710a714305517ed24afdd4573)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <8460aa915dbc8b4030aacf31cc39fbb7aee07d87.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 30 ++++++++++++++++++++++++++++++
+ tests/qemublocktest.c     |  5 +++++
+ tests/virstoragetest.c    |  9 +++++++++
+ 3 files changed, 44 insertions(+)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 5423f0b955..3eb32edc2a 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3806,6 +3806,35 @@ virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src,
+ }
+ 
+ 
++static int
++virStorageSourceParseBackingJSONNVMe(virStorageSourcePtr src,
++                                     virJSONValuePtr json,
++                                     const char *jsonstr G_GNUC_UNUSED,
++                                     int opaque G_GNUC_UNUSED)
++{
++    g_autoptr(virStorageSourceNVMeDef) nvme = g_new0(virStorageSourceNVMeDef, 1);
++    const char *device = virJSONValueObjectGetString(json, "device");
++
++    if (!device || virPCIDeviceAddressParse((char *) device, &nvme->pciAddr) < 0) {
++        virReportError(VIR_ERR_INVALID_ARG, "%s",
++                       _("missing or malformed 'device' field of 'nvme' storage"));
++        return -1;
++    }
++
++    if (virJSONValueObjectGetNumberUlong(json, "namespace", &nvme->namespc) < 0 ||
++        nvme->namespc == 0) {
++        virReportError(VIR_ERR_INVALID_ARG, "%s",
++                       _("missing or malformed 'namespace' field of 'nvme' storage"));
++        return -1;
++    }
++
++    src->type = VIR_STORAGE_TYPE_NVME;
++    src->nvme = g_steal_pointer(&nvme);
++
++    return 0;
++}
++
++
+ struct virStorageSourceJSONDriverParser {
+     const char *drvname;
+     bool formatdriver;
+@@ -3837,6 +3866,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
+     {"rbd", false, virStorageSourceParseBackingJSONRBD, 0},
+     {"raw", true, virStorageSourceParseBackingJSONRaw, 0},
+     {"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0},
++    {"nvme", false, virStorageSourceParseBackingJSONNVMe, 0},
+ };
+ 
+ 
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 8b7a50712d..e461b3a23d 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1096,6 +1096,11 @@ mymain(void)
+     /* type VIR_STORAGE_TYPE_BLOCK is not tested since it parses back to 'file' */
+     /* type VIR_STORAGE_TYPE_DIR it is a 'format' driver in qemu */
+ 
++    TEST_JSON_FORMAT(VIR_STORAGE_TYPE_NVME,
++                     "<source type='pci' namespace='1'>\n"
++                     "  <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>\n"
++                     "</source>\n");
++
+     TEST_JSON_FORMAT_NET("<source protocol='http' name=''>\n"
+                          "  <host name='example.com' port='80'/>\n"
+                          "</source>\n");
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index a61522965b..d9244fdfe8 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1637,6 +1637,15 @@ mymain(void)
+                            "  <timeout seconds='2000'/>\n"
+                            "</source>\n", 0);
+ 
++    TEST_BACKING_PARSE("json:{\"file\":{\"driver\": \"nvme\","
++                                       "\"device\": \"0000:01:00.0\","
++                                       "\"namespace\": 1"
++                                      "}"
++                            "}",
++                        "<source type='pci' namespace='1'>\n"
++                        "  <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>\n"
++                        "</source>\n");
++
+ #endif /* WITH_YAJL */
+ 
+  cleanup:
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-testQemuDiskXMLToProps-Store-all-per-image-data-in-one-structure.patch b/SOURCES/libvirt-testQemuDiskXMLToProps-Store-all-per-image-data-in-one-structure.patch
new file mode 100644
index 0000000..a96e307
--- /dev/null
+++ b/SOURCES/libvirt-testQemuDiskXMLToProps-Store-all-per-image-data-in-one-structure.patch
@@ -0,0 +1,205 @@
+From bafa6f68029a497c78b3823694b6a2149622bc9e Mon Sep 17 00:00:00 2001
+Message-Id: <bafa6f68029a497c78b3823694b6a2149622bc9e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:26:01 +0100
+Subject: [PATCH] testQemuDiskXMLToProps: Store all per-image data in one
+ structure
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We had two non-syncrhonized arrays holding the individual data. This was
+a lazy way to do it when I was adding new tests recently. Since it's
+hard to extend with new data to test refactor the storage of test data
+to use a new struct where all per-image data are kept and can be
+extended easily.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 93171b63c3a28dad06c3af6d2483d953a6f79ad2)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <b8cad280efeab0fe40e4d426167d3095b8419d3a.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 90 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 54 insertions(+), 36 deletions(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 14c80960b1..c009db7996 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -180,6 +180,13 @@ testJSONtoJSON(const void *args)
+ }
+ 
+ 
++struct testQemuDiskXMLToJSONImageData {
++    virJSONValuePtr formatprops;
++    virJSONValuePtr storageprops;
++    virJSONValuePtr storagepropssrc;
++};
++
++
+ struct testQemuDiskXMLToJSONData {
+     virQEMUDriverPtr driver;
+     virHashTablePtr schema;
+@@ -187,11 +194,8 @@ struct testQemuDiskXMLToJSONData {
+     const char *name;
+     bool fail;
+ 
+-    virJSONValuePtr *props;
+-    size_t nprops;
+-
+-    virJSONValuePtr *propssrc;
+-    size_t npropssrc;
++    struct testQemuDiskXMLToJSONImageData *images;
++    size_t nimages;
+ 
+     virQEMUCapsPtr qemuCaps;
+ };
+@@ -202,16 +206,13 @@ testQemuDiskXMLToPropsClear(struct testQemuDiskXMLToJSONData *data)
+ {
+     size_t i;
+ 
+-    for (i = 0; i < data->nprops; i++)
+-        virJSONValueFree(data->props[i]);
+-
+-    for (i = 0; i < data->npropssrc; i++)
+-        virJSONValueFree(data->propssrc[i]);
+-
+-    data->nprops = 0;
+-    VIR_FREE(data->props);
+-    data->npropssrc = 0;
+-    VIR_FREE(data->propssrc);
++    for (i = 0; i < data->nimages; i++) {
++        virJSONValueFree(data->images[i].formatprops);
++        virJSONValueFree(data->images[i].storageprops);
++        virJSONValueFree(data->images[i].storagepropssrc);
++    }
++    data->nimages = 0;
++    VIR_FREE(data->images);
+ }
+ 
+ 
+@@ -286,6 +287,7 @@ testQemuDiskXMLToProps(const void *opaque)
+     }
+ 
+     for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
++
+         if (testQemuDiskXMLToJSONFakeSecrets(n) < 0)
+             return -1;
+ 
+@@ -306,10 +308,14 @@ testQemuDiskXMLToProps(const void *opaque)
+             return -1;
+         }
+ 
+-        if (VIR_APPEND_ELEMENT(data->props, data->nprops, formatProps) < 0 ||
+-            VIR_APPEND_ELEMENT(data->props, data->nprops, storageProps) < 0 ||
+-            VIR_APPEND_ELEMENT(data->propssrc, data->npropssrc, storageSrcOnlyProps) < 0)
++        if (VIR_REALLOC_N(data->images, data->nimages + 1) < 0)
+             return -1;
++
++        data->images[data->nimages].formatprops = g_steal_pointer(&formatProps);
++        data->images[data->nimages].storageprops = g_steal_pointer(&storageProps);
++        data->images[data->nimages].storagepropssrc = g_steal_pointer(&storageSrcOnlyProps);
++
++        data->nimages++;
+     }
+ 
+     return 0;
+@@ -326,27 +332,37 @@ testQemuDiskXMLToPropsValidateSchema(const void *opaque)
+     if (data->fail)
+         return EXIT_AM_SKIP;
+ 
+-    for (i = 0; i < data->nprops; i++) {
++    for (i = 0; i < data->nimages; i++) {
+         g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
+ 
+-        if (testQEMUSchemaValidate(data->props[i], data->schemaroot,
++        if (testQEMUSchemaValidate(data->images[i].formatprops, data->schemaroot,
+                                    data->schema, &debug) < 0) {
+             g_autofree char *debugmsg = virBufferContentAndReset(&debug);
+-            g_autofree char *propsstr = virJSONValueToString(data->props[i], true);
++            g_autofree char *propsstr = virJSONValueToString(data->images[i].formatprops, true);
+             VIR_TEST_VERBOSE("json does not conform to QAPI schema");
+             VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
+                            propsstr, NULLSTR(debugmsg));
+             ret = -1;
+         }
+-    }
+ 
+-    for (i = 0; i < data->npropssrc; i++) {
+-        g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
++        virBufferFreeAndReset(&debug);
+ 
+-        if (testQEMUSchemaValidate(data->propssrc[i], data->schemaroot,
++        if (testQEMUSchemaValidate(data->images[i].storageprops, data->schemaroot,
+                                    data->schema, &debug) < 0) {
+             g_autofree char *debugmsg = virBufferContentAndReset(&debug);
+-            g_autofree char *propsstr = virJSONValueToString(data->propssrc[i], true);
++            g_autofree char *propsstr = virJSONValueToString(data->images[i].storageprops, true);
++            VIR_TEST_VERBOSE("json does not conform to QAPI schema");
++            VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
++                           propsstr, NULLSTR(debugmsg));
++            ret = -1;
++        }
++
++        virBufferFreeAndReset(&debug);
++
++        if (testQEMUSchemaValidate(data->images[i].storagepropssrc, data->schemaroot,
++                                   data->schema, &debug) < 0) {
++            g_autofree char *debugmsg = virBufferContentAndReset(&debug);
++            g_autofree char *propsstr = virJSONValueToString(data->images[i].storagepropssrc, true);
+             VIR_TEST_VERBOSE("json does not conform to QAPI schema");
+             VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
+                            propsstr, NULLSTR(debugmsg));
+@@ -372,13 +388,17 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque)
+ 
+     jsonpath = g_strdup_printf("%s%s.json", testQemuDiskXMLToJSONPath, data->name);
+ 
+-    for (i = 0; i < data->nprops; i++) {
+-        g_autofree char *jsonstr = NULL;
++    for (i = 0; i < data->nimages; i++) {
++        g_autofree char *formatprops = NULL;
++        g_autofree char *storageprops = NULL;
+ 
+-        if (!(jsonstr = virJSONValueToString(data->props[i], true)))
++        if (!(formatprops = virJSONValueToString(data->images[i].formatprops, true)))
+             return -1;
+ 
+-        virBufferAdd(&buf, jsonstr, -1);
++        if (!(storageprops = virJSONValueToString(data->images[i].storageprops, true)))
++            return -1;
++
++        virBufferStrcat(&buf, formatprops, storageprops, NULL);
+     }
+ 
+     actual = virBufferContentAndReset(&buf);
+@@ -402,10 +422,10 @@ testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque)
+     jsonpath = g_strdup_printf("%s%s-srconly.json", testQemuDiskXMLToJSONPath,
+                                data->name);
+ 
+-    for (i = 0; i < data->npropssrc; i++) {
++    for (i = 0; i < data->nimages; i++) {
+         g_autofree char *jsonstr = NULL;
+ 
+-        if (!(jsonstr = virJSONValueToString(data->propssrc[i], true)))
++        if (!(jsonstr = virJSONValueToString(data->images[i].storagepropssrc, true)))
+             return -1;
+ 
+         virBufferAdd(&buf, jsonstr, -1);
+@@ -1117,10 +1137,8 @@ mymain(void)
+ #define TEST_DISK_TO_JSON_FULL(nme, fl) \
+     do { \
+         diskxmljsondata.name = nme; \
+-        diskxmljsondata.props = NULL; \
+-        diskxmljsondata.nprops = 0; \
+-        diskxmljsondata.propssrc = NULL; \
+-        diskxmljsondata.npropssrc = 0; \
++        diskxmljsondata.images = NULL; \
++        diskxmljsondata.nimages = 0; \
+         diskxmljsondata.fail = fl; \
+         if (virTestRun("disk xml to props " nme, testQemuDiskXMLToProps, \
+                        &diskxmljsondata) < 0) \
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-testQemuDiskXMLToPropsValidateFileSrcOnly-Move-together-with-rest-of-xml-json-code.patch b/SOURCES/libvirt-testQemuDiskXMLToPropsValidateFileSrcOnly-Move-together-with-rest-of-xml-json-code.patch
new file mode 100644
index 0000000..29a34cd
--- /dev/null
+++ b/SOURCES/libvirt-testQemuDiskXMLToPropsValidateFileSrcOnly-Move-together-with-rest-of-xml-json-code.patch
@@ -0,0 +1,106 @@
+From 067d165d1ffd968d07ff54c07ccd3bb529d0c130 Mon Sep 17 00:00:00 2001
+Message-Id: <067d165d1ffd968d07ff54c07ccd3bb529d0c130@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:25:59 +0100
+Subject: [PATCH] testQemuDiskXMLToPropsValidateFileSrcOnly: Move together with
+ rest of xml->json code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The function was misplaced. Group it together with other helper
+functions for testing disk XML to qemu JSON props conversion.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit fed97cb435092d9de6f3c862ef297e722f0c0263)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <8e84dfd63f90b8b0bf10fe72bb3dcf07af9f6e96.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c | 61 ++++++++++++++++++++++---------------------
+ 1 file changed, 31 insertions(+), 30 deletions(-)
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 40aa1e2825..14c80960b1 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -387,6 +387,37 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque)
+ }
+ 
+ 
++static int
++testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque)
++{
++    struct testQemuDiskXMLToJSONData *data = (void *) opaque;
++    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
++    g_autofree char *jsonpath = NULL;
++    g_autofree char *actual = NULL;
++    size_t i;
++
++    if (data->fail)
++        return EXIT_AM_SKIP;
++
++    jsonpath = g_strdup_printf("%s%s-srconly.json", testQemuDiskXMLToJSONPath,
++                               data->name);
++
++    for (i = 0; i < data->npropssrc; i++) {
++        g_autofree char *jsonstr = NULL;
++
++        if (!(jsonstr = virJSONValueToString(data->propssrc[i], true)))
++            return -1;
++
++        virBufferAdd(&buf, jsonstr, -1);
++    }
++
++    actual = virBufferContentAndReset(&buf);
++
++    return virTestCompareToFile(actual, jsonpath);
++}
++
++
++
+ struct testQemuImageCreateData {
+     const char *name;
+     const char *backingname;
+@@ -515,36 +546,6 @@ testQemuImageCreate(const void *opaque)
+ }
+ 
+ 
+-static int
+-testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque)
+-{
+-    struct testQemuDiskXMLToJSONData *data = (void *) opaque;
+-    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+-    g_autofree char *jsonpath = NULL;
+-    g_autofree char *actual = NULL;
+-    size_t i;
+-
+-    if (data->fail)
+-        return EXIT_AM_SKIP;
+-
+-    jsonpath = g_strdup_printf("%s%s-srconly.json", testQemuDiskXMLToJSONPath,
+-                               data->name);
+-
+-    for (i = 0; i < data->npropssrc; i++) {
+-        g_autofree char *jsonstr = NULL;
+-
+-        if (!(jsonstr = virJSONValueToString(data->propssrc[i], true)))
+-            return -1;
+-
+-        virBufferAdd(&buf, jsonstr, -1);
+-    }
+-
+-    actual = virBufferContentAndReset(&buf);
+-
+-    return virTestCompareToFile(actual, jsonpath);
+-}
+-
+-
+ static const char *bitmapDetectPrefix = "qemublocktestdata/bitmap/";
+ 
+ static void
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-tests-Add-capabilities-for-QEMU-5.0.0-on-aarch64.patch b/SOURCES/libvirt-tests-Add-capabilities-for-QEMU-5.0.0-on-aarch64.patch
new file mode 100644
index 0000000..b7037b5
--- /dev/null
+++ b/SOURCES/libvirt-tests-Add-capabilities-for-QEMU-5.0.0-on-aarch64.patch
@@ -0,0 +1,23543 @@
+From 3fddf6edcbf3b0448c96b82c358ae9a4d2272c39 Mon Sep 17 00:00:00 2001
+Message-Id: <3fddf6edcbf3b0448c96b82c358ae9a4d2272c39@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 13:12:32 +0100
+Subject: [PATCH] tests: Add capabilities for QEMU 5.0.0 on aarch64
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This will be the first QEMU version that will support the
+kvm-no-adjvtime CPU feature.
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 79ebc31a1b671577f413a4fed4addca8ae3423c9)
+
+Changes:
+
+  * tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
+    tests/domaincapsdata/qemu_5.0.0.aarch64.xml
+    tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+
+    + rng-builting support has not been backported
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214121237.623948-2-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ .../qemu_5.0.0-virt.aarch64.xml               |   155 +
+ tests/domaincapsdata/qemu_5.0.0.aarch64.xml   |   149 +
+ .../caps_5.0.0.aarch64.replies                | 22717 ++++++++++++++++
+ .../caps_5.0.0.aarch64.xml                    |   455 +
+ 4 files changed, 23476 insertions(+)
+ create mode 100644 tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
+ create mode 100644 tests/domaincapsdata/qemu_5.0.0.aarch64.xml
+ create mode 100644 tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies
+ create mode 100644 tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+
+diff --git a/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
+new file mode 100644
+index 0000000000..6b6235fccc
+--- /dev/null
++++ b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml
+@@ -0,0 +1,155 @@
++<domainCapabilities>
++  <path>/usr/bin/qemu-system-aarch64</path>
++  <domain>kvm</domain>
++  <machine>virt-5.0</machine>
++  <arch>aarch64</arch>
++  <vcpu max='512'/>
++  <iothreads supported='yes'/>
++  <os supported='yes'>
++    <enum name='firmware'>
++      <value>efi</value>
++    </enum>
++    <loader supported='yes'>
++      <value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
++      <value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
++      <value>/usr/share/OVMF/OVMF_CODE.fd</value>
++      <enum name='type'>
++        <value>rom</value>
++        <value>pflash</value>
++      </enum>
++      <enum name='readonly'>
++        <value>yes</value>
++        <value>no</value>
++      </enum>
++      <enum name='secure'>
++        <value>no</value>
++      </enum>
++    </loader>
++  </os>
++  <cpu>
++    <mode name='host-passthrough' supported='yes'/>
++    <mode name='host-model' supported='no'/>
++    <mode name='custom' supported='yes'>
++      <model usable='unknown'>pxa262</model>
++      <model usable='unknown'>pxa270-a0</model>
++      <model usable='unknown'>arm1136</model>
++      <model usable='unknown'>cortex-a15</model>
++      <model usable='unknown'>pxa260</model>
++      <model usable='unknown'>arm1136-r2</model>
++      <model usable='unknown'>pxa261</model>
++      <model usable='unknown'>pxa255</model>
++      <model usable='unknown'>cortex-a72</model>
++      <model usable='unknown'>cortex-m33</model>
++      <model usable='unknown'>arm926</model>
++      <model usable='unknown'>cortex-r5f</model>
++      <model usable='unknown'>arm11mpcore</model>
++      <model usable='unknown'>pxa250</model>
++      <model usable='unknown'>ti925t</model>
++      <model usable='unknown'>cortex-a57</model>
++      <model usable='unknown'>sa1110</model>
++      <model usable='unknown'>arm1176</model>
++      <model usable='unknown'>cortex-a53</model>
++      <model usable='unknown'>sa1100</model>
++      <model usable='unknown'>pxa270-c5</model>
++      <model usable='unknown'>cortex-a9</model>
++      <model usable='unknown'>cortex-m7</model>
++      <model usable='unknown'>cortex-a8</model>
++      <model usable='unknown'>cortex-a7</model>
++      <model usable='unknown'>pxa270-c0</model>
++      <model usable='unknown'>arm1026</model>
++      <model usable='unknown'>pxa270-b1</model>
++      <model usable='unknown'>cortex-m3</model>
++      <model usable='unknown'>max</model>
++      <model usable='unknown'>cortex-m4</model>
++      <model usable='unknown'>pxa270-b0</model>
++      <model usable='unknown'>arm946</model>
++      <model usable='unknown'>cortex-m0</model>
++      <model usable='unknown'>cortex-r5</model>
++      <model usable='unknown'>pxa270-a1</model>
++      <model usable='unknown'>pxa270</model>
++    </mode>
++  </cpu>
++  <devices>
++    <disk supported='yes'>
++      <enum name='diskDevice'>
++        <value>disk</value>
++        <value>cdrom</value>
++        <value>floppy</value>
++        <value>lun</value>
++      </enum>
++      <enum name='bus'>
++        <value>fdc</value>
++        <value>scsi</value>
++        <value>virtio</value>
++        <value>usb</value>
++        <value>sata</value>
++      </enum>
++      <enum name='model'>
++        <value>virtio</value>
++        <value>virtio-transitional</value>
++        <value>virtio-non-transitional</value>
++      </enum>
++    </disk>
++    <graphics supported='yes'>
++      <enum name='type'>
++        <value>sdl</value>
++        <value>vnc</value>
++      </enum>
++    </graphics>
++    <video supported='yes'>
++      <enum name='modelType'>
++        <value>vga</value>
++        <value>cirrus</value>
++        <value>vmvga</value>
++        <value>virtio</value>
++        <value>none</value>
++        <value>bochs</value>
++        <value>ramfb</value>
++      </enum>
++    </video>
++    <hostdev supported='yes'>
++      <enum name='mode'>
++        <value>subsystem</value>
++      </enum>
++      <enum name='startupPolicy'>
++        <value>default</value>
++        <value>mandatory</value>
++        <value>requisite</value>
++        <value>optional</value>
++      </enum>
++      <enum name='subsysType'>
++        <value>usb</value>
++        <value>pci</value>
++        <value>scsi</value>
++      </enum>
++      <enum name='capsType'/>
++      <enum name='pciBackend'>
++        <value>default</value>
++        <value>vfio</value>
++      </enum>
++    </hostdev>
++    <rng supported='yes'>
++      <enum name='model'>
++        <value>virtio</value>
++        <value>virtio-transitional</value>
++        <value>virtio-non-transitional</value>
++      </enum>
++      <enum name='backendModel'>
++        <value>random</value>
++        <value>egd</value>
++      </enum>
++    </rng>
++  </devices>
++  <features>
++    <gic supported='yes'>
++      <enum name='version'>
++        <value>3</value>
++      </enum>
++    </gic>
++    <vmcoreinfo supported='yes'/>
++    <genid supported='no'/>
++    <backingStoreInput supported='yes'/>
++    <backup supported='no'/>
++    <sev supported='no'/>
++  </features>
++</domainCapabilities>
+diff --git a/tests/domaincapsdata/qemu_5.0.0.aarch64.xml b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml
+new file mode 100644
+index 0000000000..5cebdcf7db
+--- /dev/null
++++ b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml
+@@ -0,0 +1,149 @@
++<domainCapabilities>
++  <path>/usr/bin/qemu-system-aarch64</path>
++  <domain>kvm</domain>
++  <machine>integratorcp</machine>
++  <arch>aarch64</arch>
++  <vcpu max='1'/>
++  <iothreads supported='yes'/>
++  <os supported='yes'>
++    <enum name='firmware'/>
++    <loader supported='yes'>
++      <value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
++      <value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
++      <value>/usr/share/OVMF/OVMF_CODE.fd</value>
++      <enum name='type'>
++        <value>rom</value>
++        <value>pflash</value>
++      </enum>
++      <enum name='readonly'>
++        <value>yes</value>
++        <value>no</value>
++      </enum>
++      <enum name='secure'>
++        <value>no</value>
++      </enum>
++    </loader>
++  </os>
++  <cpu>
++    <mode name='host-passthrough' supported='yes'/>
++    <mode name='host-model' supported='no'/>
++    <mode name='custom' supported='yes'>
++      <model usable='unknown'>pxa262</model>
++      <model usable='unknown'>pxa270-a0</model>
++      <model usable='unknown'>arm1136</model>
++      <model usable='unknown'>cortex-a15</model>
++      <model usable='unknown'>pxa260</model>
++      <model usable='unknown'>arm1136-r2</model>
++      <model usable='unknown'>pxa261</model>
++      <model usable='unknown'>pxa255</model>
++      <model usable='unknown'>cortex-a72</model>
++      <model usable='unknown'>cortex-m33</model>
++      <model usable='unknown'>arm926</model>
++      <model usable='unknown'>cortex-r5f</model>
++      <model usable='unknown'>arm11mpcore</model>
++      <model usable='unknown'>pxa250</model>
++      <model usable='unknown'>ti925t</model>
++      <model usable='unknown'>cortex-a57</model>
++      <model usable='unknown'>sa1110</model>
++      <model usable='unknown'>arm1176</model>
++      <model usable='unknown'>cortex-a53</model>
++      <model usable='unknown'>sa1100</model>
++      <model usable='unknown'>pxa270-c5</model>
++      <model usable='unknown'>cortex-a9</model>
++      <model usable='unknown'>cortex-m7</model>
++      <model usable='unknown'>cortex-a8</model>
++      <model usable='unknown'>cortex-a7</model>
++      <model usable='unknown'>pxa270-c0</model>
++      <model usable='unknown'>arm1026</model>
++      <model usable='unknown'>pxa270-b1</model>
++      <model usable='unknown'>cortex-m3</model>
++      <model usable='unknown'>max</model>
++      <model usable='unknown'>cortex-m4</model>
++      <model usable='unknown'>pxa270-b0</model>
++      <model usable='unknown'>arm946</model>
++      <model usable='unknown'>cortex-m0</model>
++      <model usable='unknown'>cortex-r5</model>
++      <model usable='unknown'>pxa270-a1</model>
++      <model usable='unknown'>pxa270</model>
++    </mode>
++  </cpu>
++  <devices>
++    <disk supported='yes'>
++      <enum name='diskDevice'>
++        <value>disk</value>
++        <value>cdrom</value>
++        <value>floppy</value>
++        <value>lun</value>
++      </enum>
++      <enum name='bus'>
++        <value>fdc</value>
++        <value>scsi</value>
++        <value>virtio</value>
++        <value>usb</value>
++        <value>sata</value>
++      </enum>
++      <enum name='model'>
++        <value>virtio</value>
++        <value>virtio-transitional</value>
++        <value>virtio-non-transitional</value>
++      </enum>
++    </disk>
++    <graphics supported='yes'>
++      <enum name='type'>
++        <value>sdl</value>
++        <value>vnc</value>
++      </enum>
++    </graphics>
++    <video supported='yes'>
++      <enum name='modelType'>
++        <value>vga</value>
++        <value>cirrus</value>
++        <value>vmvga</value>
++        <value>virtio</value>
++        <value>none</value>
++        <value>bochs</value>
++        <value>ramfb</value>
++      </enum>
++    </video>
++    <hostdev supported='yes'>
++      <enum name='mode'>
++        <value>subsystem</value>
++      </enum>
++      <enum name='startupPolicy'>
++        <value>default</value>
++        <value>mandatory</value>
++        <value>requisite</value>
++        <value>optional</value>
++      </enum>
++      <enum name='subsysType'>
++        <value>usb</value>
++        <value>pci</value>
++        <value>scsi</value>
++      </enum>
++      <enum name='capsType'/>
++      <enum name='pciBackend'>
++        <value>default</value>
++        <value>vfio</value>
++      </enum>
++    </hostdev>
++    <rng supported='yes'>
++      <enum name='model'>
++        <value>virtio</value>
++        <value>virtio-transitional</value>
++        <value>virtio-non-transitional</value>
++      </enum>
++      <enum name='backendModel'>
++        <value>random</value>
++        <value>egd</value>
++      </enum>
++    </rng>
++  </devices>
++  <features>
++    <gic supported='no'/>
++    <vmcoreinfo supported='yes'/>
++    <genid supported='no'/>
++    <backingStoreInput supported='yes'/>
++    <backup supported='no'/>
++    <sev supported='no'/>
++  </features>
++</domainCapabilities>
+diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies
+new file mode 100644
+index 0000000000..a3136a0966
+--- /dev/null
++++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies
+@@ -0,0 +1,22717 @@
++{
++  "execute": "qmp_capabilities",
++  "id": "libvirt-1"
++}
++
++{
++  "return": {
++  },
++  "id": "libvirt-1"
++}
++
++{
++  "execute": "query-version",
++  "id": "libvirt-2"
++}
++
++{
++  "return": {
++    "qemu": {
++      "micro": 50,
++      "minor": 2,
++      "major": 4
++    },
++    "package": "v4.2.0-1157-gadcd6e93b9"
++  },
++  "id": "libvirt-2"
++}
++
++{
++  "execute": "query-target",
++  "id": "libvirt-3"
++}
++
++{
++  "return": {
++    "arch": "aarch64"
++  },
++  "id": "libvirt-3"
++}
++
++{
++  "execute": "query-commands",
++  "id": "libvirt-4"
++}
++
++{
++  "return": [
++    {
++      "name": "netdev_add"
++    },
++    {
++      "name": "device_add"
++    },
++    {
++      "name": "query-qmp-schema"
++    },
++    {
++      "name": "query-gic-capabilities"
++    },
++    {
++      "name": "query-vm-generation-id"
++    },
++    {
++      "name": "xen-load-devices-state"
++    },
++    {
++      "name": "query-acpi-ospm-status"
++    },
++    {
++      "name": "query-memory-devices"
++    },
++    {
++      "name": "query-command-line-options"
++    },
++    {
++      "name": "query-fdsets"
++    },
++    {
++      "name": "remove-fd"
++    },
++    {
++      "name": "add-fd"
++    },
++    {
++      "name": "query-memory-size-summary"
++    },
++    {
++      "name": "closefd"
++    },
++    {
++      "name": "getfd"
++    },
++    {
++      "name": "xen-set-global-dirty-log"
++    },
++    {
++      "name": "change"
++    },
++    {
++      "name": "human-monitor-command"
++    },
++    {
++      "name": "balloon"
++    },
++    {
++      "name": "inject-nmi"
++    },
++    {
++      "name": "system_wakeup"
++    },
++    {
++      "name": "x-exit-preconfig"
++    },
++    {
++      "name": "cont"
++    },
++    {
++      "name": "pmemsave"
++    },
++    {
++      "name": "memsave"
++    },
++    {
++      "name": "system_powerdown"
++    },
++    {
++      "name": "system_reset"
++    },
++    {
++      "name": "stop"
++    },
++    {
++      "name": "quit"
++    },
++    {
++      "name": "query-pci"
++    },
++    {
++      "name": "query-balloon"
++    },
++    {
++      "name": "query-iothreads"
++    },
++    {
++      "name": "query-events"
++    },
++    {
++      "name": "query-uuid"
++    },
++    {
++      "name": "query-kvm"
++    },
++    {
++      "name": "query-name"
++    },
++    {
++      "name": "add_client"
++    },
++    {
++      "name": "query-commands"
++    },
++    {
++      "name": "query-version"
++    },
++    {
++      "name": "qmp_capabilities"
++    },
++    {
++      "name": "query-cpu-definitions"
++    },
++    {
++      "name": "query-cpu-model-expansion"
++    },
++    {
++      "name": "set-numa-node"
++    },
++    {
++      "name": "query-hotpluggable-cpus"
++    },
++    {
++      "name": "query-memdev"
++    },
++    {
++      "name": "query-target"
++    },
++    {
++      "name": "query-current-machine"
++    },
++    {
++      "name": "query-machines"
++    },
++    {
++      "name": "cpu-add"
++    },
++    {
++      "name": "query-cpus-fast"
++    },
++    {
++      "name": "query-cpus"
++    },
++    {
++      "name": "device_del"
++    },
++    {
++      "name": "device-list-properties"
++    },
++    {
++      "name": "object-del"
++    },
++    {
++      "name": "object-add"
++    },
++    {
++      "name": "qom-list-properties"
++    },
++    {
++      "name": "qom-list-types"
++    },
++    {
++      "name": "qom-set"
++    },
++    {
++      "name": "qom-get"
++    },
++    {
++      "name": "qom-list"
++    },
++    {
++      "name": "trace-event-set-state"
++    },
++    {
++      "name": "trace-event-get-state"
++    },
++    {
++      "name": "transaction"
++    },
++    {
++      "name": "migrate-pause"
++    },
++    {
++      "name": "migrate-recover"
++    },
++    {
++      "name": "query-colo-status"
++    },
++    {
++      "name": "xen-colo-do-checkpoint"
++    },
++    {
++      "name": "query-xen-replication-status"
++    },
++    {
++      "name": "xen-set-replication"
++    },
++    {
++      "name": "xen-save-devices-state"
++    },
++    {
++      "name": "migrate-incoming"
++    },
++    {
++      "name": "migrate"
++    },
++    {
++      "name": "query-migrate-cache-size"
++    },
++    {
++      "name": "migrate-set-cache-size"
++    },
++    {
++      "name": "migrate_set_speed"
++    },
++    {
++      "name": "migrate_set_downtime"
++    },
++    {
++      "name": "migrate-continue"
++    },
++    {
++      "name": "migrate_cancel"
++    },
++    {
++      "name": "x-colo-lost-heartbeat"
++    },
++    {
++      "name": "migrate-start-postcopy"
++    },
++    {
++      "name": "client_migrate_info"
++    },
++    {
++      "name": "query-migrate-parameters"
++    },
++    {
++      "name": "migrate-set-parameters"
++    },
++    {
++      "name": "query-migrate-capabilities"
++    },
++    {
++      "name": "migrate-set-capabilities"
++    },
++    {
++      "name": "query-migrate"
++    },
++    {
++      "name": "query-display-options"
++    },
++    {
++      "name": "input-send-event"
++    },
++    {
++      "name": "send-key"
++    },
++    {
++      "name": "query-mice"
++    },
++    {
++      "name": "change-vnc-password"
++    },
++    {
++      "name": "query-vnc-servers"
++    },
++    {
++      "name": "query-vnc"
++    },
++    {
++      "name": "screendump"
++    },
++    {
++      "name": "expire_password"
++    },
++    {
++      "name": "set_password"
++    },
++    {
++      "name": "query-tpm"
++    },
++    {
++      "name": "query-tpm-types"
++    },
++    {
++      "name": "query-tpm-models"
++    },
++    {
++      "name": "query-rocker-of-dpa-groups"
++    },
++    {
++      "name": "query-rocker-of-dpa-flows"
++    },
++    {
++      "name": "query-rocker-ports"
++    },
++    {
++      "name": "query-rocker"
++    },
++    {
++      "name": "announce-self"
++    },
++    {
++      "name": "query-rx-filter"
++    },
++    {
++      "name": "netdev_del"
++    },
++    {
++      "name": "set_link"
++    },
++    {
++      "name": "query-dump-guest-memory-capability"
++    },
++    {
++      "name": "query-dump"
++    },
++    {
++      "name": "dump-guest-memory"
++    },
++    {
++      "name": "chardev-send-break"
++    },
++    {
++      "name": "chardev-remove"
++    },
++    {
++      "name": "chardev-change"
++    },
++    {
++      "name": "chardev-add"
++    },
++    {
++      "name": "ringbuf-read"
++    },
++    {
++      "name": "ringbuf-write"
++    },
++    {
++      "name": "query-chardev-backends"
++    },
++    {
++      "name": "query-chardev"
++    },
++    {
++      "name": "query-jobs"
++    },
++    {
++      "name": "job-finalize"
++    },
++    {
++      "name": "job-dismiss"
++    },
++    {
++      "name": "job-complete"
++    },
++    {
++      "name": "job-cancel"
++    },
++    {
++      "name": "job-resume"
++    },
++    {
++      "name": "job-pause"
++    },
++    {
++      "name": "x-blockdev-set-iothread"
++    },
++    {
++      "name": "x-blockdev-change"
++    },
++    {
++      "name": "block-set-write-threshold"
++    },
++    {
++      "name": "blockdev-change-medium"
++    },
++    {
++      "name": "blockdev-insert-medium"
++    },
++    {
++      "name": "blockdev-remove-medium"
++    },
++    {
++      "name": "blockdev-close-tray"
++    },
++    {
++      "name": "blockdev-open-tray"
++    },
++    {
++      "name": "blockdev-create"
++    },
++    {
++      "name": "blockdev-del"
++    },
++    {
++      "name": "x-blockdev-reopen"
++    },
++    {
++      "name": "blockdev-add"
++    },
++    {
++      "name": "block-job-finalize"
++    },
++    {
++      "name": "block-job-dismiss"
++    },
++    {
++      "name": "block-job-complete"
++    },
++    {
++      "name": "block-job-resume"
++    },
++    {
++      "name": "block-job-pause"
++    },
++    {
++      "name": "block-job-cancel"
++    },
++    {
++      "name": "block-job-set-speed"
++    },
++    {
++      "name": "block-stream"
++    },
++    {
++      "name": "block_set_io_throttle"
++    },
++    {
++      "name": "blockdev-mirror"
++    },
++    {
++      "name": "x-debug-block-dirty-bitmap-sha256"
++    },
++    {
++      "name": "block-dirty-bitmap-merge"
++    },
++    {
++      "name": "block-dirty-bitmap-disable"
++    },
++    {
++      "name": "block-dirty-bitmap-enable"
++    },
++    {
++      "name": "block-dirty-bitmap-clear"
++    },
++    {
++      "name": "block-dirty-bitmap-remove"
++    },
++    {
++      "name": "block-dirty-bitmap-add"
++    },
++    {
++      "name": "drive-mirror"
++    },
++    {
++      "name": "x-debug-query-block-graph"
++    },
++    {
++      "name": "query-named-block-nodes"
++    },
++    {
++      "name": "blockdev-backup"
++    },
++    {
++      "name": "drive-backup"
++    },
++    {
++      "name": "block-commit"
++    },
++    {
++      "name": "change-backing-file"
++    },
++    {
++      "name": "blockdev-snapshot"
++    },
++    {
++      "name": "blockdev-snapshot-sync"
++    },
++    {
++      "name": "block_resize"
++    },
++    {
++      "name": "block_passwd"
++    },
++    {
++      "name": "query-block-jobs"
++    },
++    {
++      "name": "query-blockstats"
++    },
++    {
++      "name": "query-block"
++    },
++    {
++      "name": "block-latency-histogram-set"
++    },
++    {
++      "name": "nbd-server-stop"
++    },
++    {
++      "name": "nbd-server-remove"
++    },
++    {
++      "name": "nbd-server-add"
++    },
++    {
++      "name": "nbd-server-start"
++    },
++    {
++      "name": "eject"
++    },
++    {
++      "name": "blockdev-snapshot-delete-internal-sync"
++    },
++    {
++      "name": "blockdev-snapshot-internal-sync"
++    },
++    {
++      "name": "query-pr-managers"
++    },
++    {
++      "name": "watchdog-set-action"
++    },
++    {
++      "name": "query-status"
++    }
++  ],
++  "id": "libvirt-4"
++}
++
++{
++  "execute": "query-kvm",
++  "id": "libvirt-5"
++}
++
++{
++  "return": {
++    "enabled": true,
++    "present": true
++  },
++  "id": "libvirt-5"
++}
++
++{
++  "execute": "qom-list-types",
++  "id": "libvirt-6"
++}
++
++{
++  "return": [
++    {
++      "name": "scsi-hd",
++      "parent": "scsi-disk-base"
++    },
++    {
++      "name": "chardev-parallel",
++      "parent": "chardev"
++    },
++    {
++      "name": "vhost-vsock-pci",
++      "parent": "vhost-vsock-pci-base"
++    },
++    {
++      "name": "pxa270-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "imx7.analog",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.gpio-ast2600",
++      "parent": "aspeed.gpio"
++    },
++    {
++      "name": "chardev-pty",
++      "parent": "chardev"
++    },
++    {
++      "name": "pxa270-a1-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "digic",
++      "parent": "device"
++    },
++    {
++      "name": "mv88w8618_flashcfg",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "at25df641",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "lm3s811evb-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "chardev-null",
++      "parent": "chardev"
++    },
++    {
++      "name": "bcm2835-property",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pxa2xx-pcmcia",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mx25l3205d",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "vhost-user-fs-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "canon-a1100-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "n25q512a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "lsi53c895a",
++      "parent": "pci-device"
++    },
++    {
++      "name": "pr-manager-helper",
++      "parent": "pr-manager"
++    },
++    {
++      "name": "cpu-cluster",
++      "parent": "device"
++    },
++    {
++      "name": "virtio-keyboard-pci",
++      "parent": "virtio-keyboard-pci-base-type"
++    },
++    {
++      "name": "imx2.wdt",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virt-3.1-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "mx25l6405d",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virt-5.0-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "w25q256",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "ich9-usb-uhci4",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "s25fl064k",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "musicpal_gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vhost-scsi-pci-non-transitional",
++      "parent": "vhost-scsi-pci-base"
++    },
++    {
++      "name": "ide-hd",
++      "parent": "ide-device"
++    },
++    {
++      "name": "virtio-net-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "virtio-9p-pci-non-transitional",
++      "parent": "virtio-9p-pci-base"
++    },
++    {
++      "name": "iotkit-secctl",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "usb-mtp",
++      "parent": "usb-device"
++    },
++    {
++      "name": "n25q00",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "tz-mpc-iommu-memory-region",
++      "parent": "qemu:iommu-memory-region"
++    },
++    {
++      "name": "cortex-r5-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "usb-mouse",
++      "parent": "usb-hid"
++    },
++    {
++      "name": "xlnx-zcu102-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "vexpress-a15-machine",
++      "parent": "vexpress"
++    },
++    {
++      "name": "imx7.gpt",
++      "parent": "imx25.gpt"
++    },
++    {
++      "name": "at45db081d",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "en25p32",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "imx7.gpr",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pxa2xx-i2c-slave",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "gpex-pcihost",
++      "parent": "pcie-host-bridge"
++    },
++    {
++      "name": "cortex-m0-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "aspeed.gpio-ast2500",
++      "parent": "aspeed.gpio"
++    },
++    {
++      "name": "ftgmac100",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "filter-rewriter",
++      "parent": "netfilter"
++    },
++    {
++      "name": "loader",
++      "parent": "device"
++    },
++    {
++      "name": "s25fl256s1",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "arm946-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "iotkit",
++      "parent": "arm-sse"
++    },
++    {
++      "name": "m25pe80",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa270-b0-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "s25fl256s0",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virtio-serial-pci",
++      "parent": "virtio-serial-pci-base"
++    },
++    {
++      "name": "usb-audio",
++      "parent": "usb-device"
++    },
++    {
++      "name": "platform-bus-device",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "qio-channel-file",
++      "parent": "qio-channel"
++    },
++    {
++      "name": "usb-host",
++      "parent": "usb-device"
++    },
++    {
++      "name": "pcie-root-port",
++      "parent": "pcie-root-port-base"
++    },
++    {
++      "name": "iotkit-sysinfo",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mt25qu01g",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virtio-crypto-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "platform-ehci-usb",
++      "parent": "sysbus-ehci-usb"
++    },
++    {
++      "name": "ich9-usb-uhci1",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "ccid-bus",
++      "parent": "bus"
++    },
++    {
++      "name": "xlnx,ps7-usb",
++      "parent": "sysbus-ehci-usb"
++    },
++    {
++      "name": "imx31.gpt",
++      "parent": "imx25.gpt"
++    },
++    {
++      "name": "s25fl129p1",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "s25fl129p0",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "xlnx.xps-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "ich9-usb-uhci6",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "ich9-usb-uhci5",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "xlnx.xps-intc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "ich9-usb-uhci3",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "kvm-arm-gicv3",
++      "parent": "arm-gicv3-common"
++    },
++    {
++      "name": "virtio-input-host-pci",
++      "parent": "virtio-input-host-pci-base-type"
++    },
++    {
++      "name": "mcimx6ul-evk-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "SSI",
++      "parent": "bus"
++    },
++    {
++      "name": "e1000",
++      "parent": "e1000-base"
++    },
++    {
++      "name": "xlnx,zynq-xadc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xlnx.axi-dma",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "s25sl12801",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "s25sl12800",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa2xx_rtc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "exynos4210",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "ich9-usb-uhci2",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "cortex-m4-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "sysbus-ahci",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "kvm-arm-gic",
++      "parent": "arm_gic_common"
++    },
++    {
++      "name": "imx.fec",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.timer-ast2600",
++      "parent": "aspeed.timer"
++    },
++    {
++      "name": "tpci200",
++      "parent": "pci-device"
++    },
++    {
++      "name": "aspeed.gpio-ast2400",
++      "parent": "aspeed.gpio"
++    },
++    {
++      "name": "spitz-lcdtg",
++      "parent": "ssi-slave"
++    },
++    {
++      "name": "memory-backend-file",
++      "parent": "memory-backend"
++    },
++    {
++      "name": "stm32f2xx-usart",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "max-arm-cpu",
++      "parent": "aarch64-cpu"
++    },
++    {
++      "name": "cortex-m3-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "s25sl064p",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "input-barrier",
++      "parent": "object"
++    },
++    {
++      "name": "container",
++      "parent": "object"
++    },
++    {
++      "name": "lan9118",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "stm32f2xx-syscfg",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mps2-an521-machine",
++      "parent": "mps2tz"
++    },
++    {
++      "name": "rtl8139",
++      "parent": "pci-device"
++    },
++    {
++      "name": "armsse-mhu",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "exynos4210.i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "s25sl064a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "vexpress-a9-machine",
++      "parent": "vexpress"
++    },
++    {
++      "name": "usb-chipidea",
++      "parent": "sysbus-ehci-usb"
++    },
++    {
++      "name": "megasas",
++      "parent": "megasas-base"
++    },
++    {
++      "name": "corgi-ssp",
++      "parent": "ssi-slave"
++    },
++    {
++      "name": "pxa2xx-fir",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-balloon-pci-non-transitional",
++      "parent": "virtio-balloon-pci-base"
++    },
++    {
++      "name": "designware-pcie-host",
++      "parent": "pci-host-bridge"
++    },
++    {
++      "name": "scsi-block",
++      "parent": "scsi-disk-base"
++    },
++    {
++      "name": "mx66u1g45g",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "omap-intc",
++      "parent": "common-omap-intc"
++    },
++    {
++      "name": "unimplemented-device",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vhost-user-input",
++      "parent": "virtio-input-device"
++    },
++    {
++      "name": "strongarm_pic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "max7310",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "sst25wf512",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "scsi-cd",
++      "parent": "scsi-disk-base"
++    },
++    {
++      "name": "chardev-udp",
++      "parent": "chardev"
++    },
++    {
++      "name": "aspeed.fmc-ast2600",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "accel",
++      "parent": "object"
++    },
++    {
++      "name": "microbit.i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pxa270-b1-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "luminary-watchdog",
++      "parent": "cmsdk-apb-watchdog"
++    },
++    {
++      "name": "m45pe80",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa2xx-dma",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xlnx.axi-ethernet",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vmware-svga",
++      "parent": "pci-device"
++    },
++    {
++      "name": "ast2600-evb-machine",
++      "parent": "aspeed-machine"
++    },
++    {
++      "name": "imx.gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "tegra2-ehci-usb",
++      "parent": "sysbus-ehci-usb"
++    },
++    {
++      "name": "virtio-serial-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "digic-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "integrator_debug",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.scu-ast2600",
++      "parent": "aspeed.scu"
++    },
++    {
++      "name": "chardev-gdb",
++      "parent": "chardev"
++    },
++    {
++      "name": "vhost-scsi-pci",
++      "parent": "vhost-scsi-pci-base"
++    },
++    {
++      "name": "xlnx.usmp-gqspi",
++      "parent": "xlnx.ps7-qspi"
++    },
++    {
++      "name": "imx25.ccm",
++      "parent": "imx.ccm"
++    },
++    {
++      "name": "a15mpcore_priv",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "dc390",
++      "parent": "am53c974"
++    },
++    {
++      "name": "fw_cfg_mem",
++      "parent": "fw_cfg"
++    },
++    {
++      "name": "virtio-scsi-pci-transitional",
++      "parent": "virtio-scsi-pci-base"
++    },
++    {
++      "name": "chardev-socket",
++      "parent": "chardev"
++    },
++    {
++      "name": "usb-ccid",
++      "parent": "usb-device"
++    },
++    {
++      "name": "virtio-rng-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "usb-uas",
++      "parent": "usb-device"
++    },
++    {
++      "name": "chardev-mux",
++      "parent": "chardev"
++    },
++    {
++      "name": "ide-cd",
++      "parent": "ide-device"
++    },
++    {
++      "name": "mss-spi",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cadence_uart",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mps2-an385-machine",
++      "parent": "mps2"
++    },
++    {
++      "name": "virtio-balloon-pci",
++      "parent": "virtio-balloon-pci-base"
++    },
++    {
++      "name": "gpio_i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "imx.rngc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "iothread",
++      "parent": "object"
++    },
++    {
++      "name": "spitz-keyboard",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "lm8323",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "qio-channel-rdma",
++      "parent": "qio-channel"
++    },
++    {
++      "name": "n25q256a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "bochs-display",
++      "parent": "pci-device"
++    },
++    {
++      "name": "bcm2835-ic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xilinx-zynq-a9-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "aspeed.timer-ast2400",
++      "parent": "aspeed.timer"
++    },
++    {
++      "name": "arm1026-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "twl92230",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "vhost-vsock-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "qio-channel-websock",
++      "parent": "qio-channel"
++    },
++    {
++      "name": "authz-list-file",
++      "parent": "authz"
++    },
++    {
++      "name": "sdhci-pci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "virtio-input-host-device",
++      "parent": "virtio-input-device"
++    },
++    {
++      "name": "nrf51_soc.timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.timer-ast2500",
++      "parent": "aspeed.timer"
++    },
++    {
++      "name": "xlnx.v-dp",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "stm32f2xx-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pci-bridge",
++      "parent": "base-pci-bridge"
++    },
++    {
++      "name": "i82559er",
++      "parent": "pci-device"
++    },
++    {
++      "name": "aspeed.fmc-ast2500",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "ivshmem-doorbell",
++      "parent": "ivshmem-common"
++    },
++    {
++      "name": "arm-gicv2m",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mx66l1g45g",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "am53c974",
++      "parent": "pci-device"
++    },
++    {
++      "name": "versatile_pci_host",
++      "parent": "pci-device"
++    },
++    {
++      "name": "w25x80",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "mv88w8618_wlan",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pci-bridge-seat",
++      "parent": "pci-bridge"
++    },
++    {
++      "name": "en25q32b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa27x-timer",
++      "parent": "pxa2xx-timer"
++    },
++    {
++      "name": "pxa270-c0-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "witherspoon-bmc-machine",
++      "parent": "aspeed-machine"
++    },
++    {
++      "name": "mx25l1606e",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "microbit-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "nand",
++      "parent": "device"
++    },
++    {
++      "name": "aspeed.scu-ast2500",
++      "parent": "aspeed.scu"
++    },
++    {
++      "name": "designware-pcie-root",
++      "parent": "base-pci-bridge"
++    },
++    {
++      "name": "gpio-key",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "serial-mm",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "hda-micro",
++      "parent": "hda-audio"
++    },
++    {
++      "name": "fw_cfg_io",
++      "parent": "fw_cfg"
++    },
++    {
++      "name": "pl190",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.sdmc-ast2600",
++      "parent": "aspeed.sdmc"
++    },
++    {
++      "name": "s3c-sdhci",
++      "parent": "generic-sdhci"
++    },
++    {
++      "name": "IDE",
++      "parent": "bus"
++    },
++    {
++      "name": "qemu,register",
++      "parent": "device"
++    },
++    {
++      "name": "cortex-a7-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "at25256a-nonjedec",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "m25pe20",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "integrator_core",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virt-2.12-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "ads7846",
++      "parent": "ssi-slave"
++    },
++    {
++      "name": "sst25wf080",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "memory-backend-ram",
++      "parent": "memory-backend"
++    },
++    {
++      "name": "arm_gic",
++      "parent": "arm_gic_common"
++    },
++    {
++      "name": "aspeed.fmc-ast2400",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "exynos4210.mct",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "stellaris-adc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "connex-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "virtio-blk-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "imx6.ccm",
++      "parent": "imx.ccm"
++    },
++    {
++      "name": "virt-2.11-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "at25128a-nonjedec",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "n25q512a13",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "cortex-a8-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "n25q512a11",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "sl-nand",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "armv7m",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "icp-ctrl-regs",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "bcm2835-sdhost",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "stellaris-gptm",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "chardev-pipe",
++      "parent": "chardev-fd"
++    },
++    {
++      "name": "chardev-msmouse",
++      "parent": "chardev"
++    },
++    {
++      "name": "virt-2.10-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "pl181",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cortex-m7-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "cryptodev-backend-builtin",
++      "parent": "cryptodev-backend"
++    },
++    {
++      "name": "m25pe16",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "hda-output",
++      "parent": "hda-audio"
++    },
++    {
++      "name": "w25x64",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "VGA",
++      "parent": "pci-vga"
++    },
++    {
++      "name": "qio-net-listener",
++      "parent": "object"
++    },
++    {
++      "name": "iotkit-sysctl",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "s25fl016k",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "n800-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "vfio-pci-nohotplug",
++      "parent": "vfio-pci"
++    },
++    {
++      "name": "m25p80",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "at25df321a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa2xx-mmci-bus",
++      "parent": "sd-bus"
++    },
++    {
++      "name": "edu",
++      "parent": "pci-device"
++    },
++    {
++      "name": "mptsas1068",
++      "parent": "pci-device"
++    },
++    {
++      "name": "bcm2835-fb",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "lm3s6965evb-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "aspeed.scu-ast2400",
++      "parent": "aspeed.scu"
++    },
++    {
++      "name": "versatileab-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "virtio-mouse-pci",
++      "parent": "virtio-mouse-pci-base-type"
++    },
++    {
++      "name": "strongarm-uart",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pl330",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "gpex-root",
++      "parent": "pci-device"
++    },
++    {
++      "name": "cmsdk-apb-watchdog",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vfio-pci-igd-lpc-bridge",
++      "parent": "pci-device"
++    },
++    {
++      "name": "mv88w8618_pit",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "qio-channel-command",
++      "parent": "qio-channel"
++    },
++    {
++      "name": "HDA",
++      "parent": "bus"
++    },
++    {
++      "name": "chardev-ringbuf",
++      "parent": "chardev"
++    },
++    {
++      "name": "stm32f2xx-adc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cmsdk-apb-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mx66u51235f",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "aspeed.sdmc-ast2500",
++      "parent": "aspeed.sdmc"
++    },
++    {
++      "name": "aspeed.xdma",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pcm3680_pci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "usb-serial",
++      "parent": "usb-serial-dev"
++    },
++    {
++      "name": "qemu:memory-region",
++      "parent": "object"
++    },
++    {
++      "name": "mioe3680_pci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "mv88w8618_pic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "ssd0323",
++      "parent": "ssi-slave"
++    },
++    {
++      "name": "i2c-ddc",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "omap2-intc",
++      "parent": "common-omap-intc"
++    },
++    {
++      "name": "sysbus-ohci",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xlnx.ps7-dev-cfg",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pl080",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "borzoi-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "stellaris-i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pl081",
++      "parent": "pl080"
++    },
++    {
++      "name": "xlnx.dpdma",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.smc-ast2400",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "can-bus",
++      "parent": "object"
++    },
++    {
++      "name": "qtest-accel",
++      "parent": "accel"
++    },
++    {
++      "name": "m25p64",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "w25x40",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "tosa-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "cirrus-vga",
++      "parent": "pci-device"
++    },
++    {
++      "name": "xio3130-downstream",
++      "parent": "pcie-slot"
++    },
++    {
++      "name": "acpi-ged",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vhost-user-gpu",
++      "parent": "virtio-gpu-base"
++    },
++    {
++      "name": "n25q128a13",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virtio-blk-pci",
++      "parent": "virtio-blk-pci-base"
++    },
++    {
++      "name": "cortex-a9-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "virtio-gpu-device",
++      "parent": "virtio-gpu-base"
++    },
++    {
++      "name": "xlnx-versal",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cryptodev-vhost-user",
++      "parent": "cryptodev-backend"
++    },
++    {
++      "name": "ast2500-a1",
++      "parent": "aspeed-soc"
++    },
++    {
++      "name": "n25q128a11",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "vt82c686b-usb-uhci",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "imx-gpcv2",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "lsi53c810",
++      "parent": "lsi53c895a"
++    },
++    {
++      "name": "chardev-file",
++      "parent": "chardev-fd"
++    },
++    {
++      "name": "System",
++      "parent": "bus"
++    },
++    {
++      "name": "strongarm-gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cheetah-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "m45pe16",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "usb-hub",
++      "parent": "usb-device"
++    },
++    {
++      "name": "pxa270-c5-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "sst25wf040",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "m45pe10",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "chardev-braille",
++      "parent": "chardev"
++    },
++    {
++      "name": "exynos4210.rtc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "romulus-bmc-machine",
++      "parent": "aspeed-machine"
++    },
++    {
++      "name": "w25x32",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "s25sl032p",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "vhost-user-scsi-pci-non-transitional",
++      "parent": "vhost-user-scsi-pci-base"
++    },
++    {
++      "name": "aspeed.gpio-ast2600-1_8v",
++      "parent": "aspeed.gpio"
++    },
++    {
++      "name": "aspeed.sdmc-ast2400",
++      "parent": "aspeed.sdmc"
++    },
++    {
++      "name": "filter-dump",
++      "parent": "netfilter"
++    },
++    {
++      "name": "imx25.gpt",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "PCIE",
++      "parent": "PCI"
++    },
++    {
++      "name": "pl061",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pcie-pci-bridge",
++      "parent": "base-pci-bridge"
++    },
++    {
++      "name": "sa1100-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "ssd0303",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "s25sl032a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "s25sl016a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virtio-net-pci-transitional",
++      "parent": "virtio-net-pci-base"
++    },
++    {
++      "name": "mv88w8618_audio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vhost-user-blk-pci",
++      "parent": "vhost-user-blk-pci-base"
++    },
++    {
++      "name": "s25sl008a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virtio-serial-bus",
++      "parent": "bus"
++    },
++    {
++      "name": "ssi-sd",
++      "parent": "ssi-slave"
++    },
++    {
++      "name": "secondary-vga",
++      "parent": "pci-vga"
++    },
++    {
++      "name": "vhost-scsi",
++      "parent": "vhost-scsi-common"
++    },
++    {
++      "name": "serial-io",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "exynos4210-ehci-usb",
++      "parent": "sysbus-ehci-usb"
++    },
++    {
++      "name": "exynos4210.pwm",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cfi.pflash02",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pci-ohci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "s70fl01gs",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "cfi.pflash01",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "w25x20",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "tmp421",
++      "parent": "tmp421-generic"
++    },
++    {
++      "name": "s25fl512s",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "m25p40",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "mx25l12855e",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "tmp423",
++      "parent": "tmp421-generic"
++    },
++    {
++      "name": "input-linux",
++      "parent": "object"
++    },
++    {
++      "name": "midway-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "tmp422",
++      "parent": "tmp421-generic"
++    },
++    {
++      "name": "netduinoplus2-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "bcm2835-aux",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "sabrelite-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "aspeed.spi2-ast2600",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "arm_mptimer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "musicpal-misc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "bcm2835-sys-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.spi1-ast2600",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "stm32f4xx-syscfg",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "SCSI",
++      "parent": "bus"
++    },
++    {
++      "name": "virtio-rng-pci-transitional",
++      "parent": "virtio-rng-pci-base"
++    },
++    {
++      "name": "virtio-serial-pci-transitional",
++      "parent": "virtio-serial-pci-base"
++    },
++    {
++      "name": "w25x16",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "ati-vga",
++      "parent": "pci-device"
++    },
++    {
++      "name": "sst25wf020",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "m25p32",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "vfio-amd-xgbe",
++      "parent": "vfio-platform"
++    },
++    {
++      "name": "w25x10",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa2xx-gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "tacoma-bmc-machine",
++      "parent": "aspeed-machine"
++    },
++    {
++      "name": "palmetto-bmc-machine",
++      "parent": "aspeed-machine"
++    },
++    {
++      "name": "xlnx.xps-uartlite",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mainstone-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "n810-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "pci-serial",
++      "parent": "pci-device"
++    },
++    {
++      "name": "at26df161a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "rocker",
++      "parent": "pci-device"
++    },
++    {
++      "name": "terrier-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "max1111",
++      "parent": "max111x"
++    },
++    {
++      "name": "netduino2-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "max1110",
++      "parent": "max111x"
++    },
++    {
++      "name": "i82559c",
++      "parent": "pci-device"
++    },
++    {
++      "name": "i82559b",
++      "parent": "pci-device"
++    },
++    {
++      "name": "i82559a",
++      "parent": "pci-device"
++    },
++    {
++      "name": "vhost-user-scsi-pci",
++      "parent": "vhost-user-scsi-pci-base"
++    },
++    {
++      "name": "xlnx,zynqmp",
++      "parent": "device"
++    },
++    {
++      "name": "virtio-blk-pci-non-transitional",
++      "parent": "virtio-blk-pci-base"
++    },
++    {
++      "name": "realview_pci",
++      "parent": "versatile_pci"
++    },
++    {
++      "name": "pcnet",
++      "parent": "pci-device"
++    },
++    {
++      "name": "pl041",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "nrf51_soc.uart",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "n25q032a13",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "n25q032a11",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "gd25q64",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "sst25wf010",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "rng-egd",
++      "parent": "rng-backend"
++    },
++    {
++      "name": "m25p20",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "xlnx.zdma",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "exynos4210.gic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "raspi3-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "migration",
++      "parent": "device"
++    },
++    {
++      "name": "l2x0",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "chardev-testdev",
++      "parent": "chardev"
++    },
++    {
++      "name": "n25q064",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "allwinner-A10-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.spi1-ast2500",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "n25q064a13",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "i82558b",
++      "parent": "pci-device"
++    },
++    {
++      "name": "n25q064a11",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pl031",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "raspi2-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "filter-mirror",
++      "parent": "netfilter"
++    },
++    {
++      "name": "strongarm-ssp",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "i82558a",
++      "parent": "pci-device"
++    },
++    {
++      "name": "smbus-eeprom",
++      "parent": "smbus-device"
++    },
++    {
++      "name": "scoop",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "msf2-soc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pl111",
++      "parent": "pl110"
++    },
++    {
++      "name": "pl110",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "tosa_dac",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "onenand",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virt-4.1-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "bcm2835-dma",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "m25p16",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "i82801",
++      "parent": "pci-device"
++    },
++    {
++      "name": "virtio-keyboard-device",
++      "parent": "virtio-input-hid-device"
++    },
++    {
++      "name": "i82562",
++      "parent": "pci-device"
++    },
++    {
++      "name": "virtio-net-pci",
++      "parent": "virtio-net-pci-base"
++    },
++    {
++      "name": "exynos4210.fimd",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "m25p10",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "usb-net",
++      "parent": "usb-device"
++    },
++    {
++      "name": "highbank-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "virt-4.0-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "i82557c",
++      "parent": "pci-device"
++    },
++    {
++      "name": "at26df081a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "aspeed.spi2-ast2500",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "chardev-memory",
++      "parent": "chardev-ringbuf"
++    },
++    {
++      "name": "xilinx-axi-dma-control-stream",
++      "parent": "object"
++    },
++    {
++      "name": "i82557b",
++      "parent": "pci-device"
++    },
++    {
++      "name": "aspeed.wdt-ast2600",
++      "parent": "aspeed.wdt"
++    },
++    {
++      "name": "digic-uart",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cortex-a53-arm-cpu",
++      "parent": "aarch64-cpu"
++    },
++    {
++      "name": "sse-200",
++      "parent": "arm-sse"
++    },
++    {
++      "name": "arm1176-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "i82557a",
++      "parent": "pci-device"
++    },
++    {
++      "name": "s25sl004a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pl022",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "sdhci-bus",
++      "parent": "sd-bus"
++    },
++    {
++      "name": "split-irq",
++      "parent": "device"
++    },
++    {
++      "name": "bcm2835-rng",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-gpu-pci",
++      "parent": "virtio-gpu-pci-base-type"
++    },
++    {
++      "name": "pl061_luminary",
++      "parent": "pl061"
++    },
++    {
++      "name": "nrf51_soc.gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xilinx-axienet-control-stream",
++      "parent": "object"
++    },
++    {
++      "name": "m25p05",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "bcm2835-sdhost-bus",
++      "parent": "sd-bus"
++    },
++    {
++      "name": "strongarm-rtc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "n25q128",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "imx.epit",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "i82551",
++      "parent": "pci-device"
++    },
++    {
++      "name": "i82550",
++      "parent": "pci-device"
++    },
++    {
++      "name": "armv7m_nvic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cubieboard-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "fsl,imx31",
++      "parent": "device"
++    },
++    {
++      "name": "host-arm-cpu",
++      "parent": "aarch64-cpu"
++    },
++    {
++      "name": "qio-channel-socket",
++      "parent": "qio-channel"
++    },
++    {
++      "name": "cadence_ttc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "throttle-group",
++      "parent": "object"
++    },
++    {
++      "name": "imx.i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "highbank-regs",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.wdt-ast2500",
++      "parent": "aspeed.wdt"
++    },
++    {
++      "name": "virt-2.6-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "sa1110-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "arm.cortex-a9-global-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "exynos4210.rng",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "ich9-usb-ehci2",
++      "parent": "pci-ehci-usb"
++    },
++    {
++      "name": "virtio-crypto-pci",
++      "parent": "virtio-crypto-pci-base-type"
++    },
++    {
++      "name": "dpcd",
++      "parent": "aux-slave"
++    },
++    {
++      "name": "pl011",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "ich9-usb-ehci1",
++      "parent": "pci-ehci-usb"
++    },
++    {
++      "name": "vfio-pci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "nec-usb-xhci",
++      "parent": "base-xhci"
++    },
++    {
++      "name": "imx6.gpt",
++      "parent": "imx25.gpt"
++    },
++    {
++      "name": "irq",
++      "parent": "object"
++    },
++    {
++      "name": "tusb6010",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "realview_mpcore",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "can-host-socketcan",
++      "parent": "can-host"
++    },
++    {
++      "name": "fsl,imx25",
++      "parent": "device"
++    },
++    {
++      "name": "sx1-v1-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "w25q32dw",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "gd25q32",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "dbus-vmstate",
++      "parent": "object"
++    },
++    {
++      "name": "cortex-a57-arm-cpu",
++      "parent": "aarch64-cpu"
++    },
++    {
++      "name": "memory-backend-memfd",
++      "parent": "memory-backend"
++    },
++    {
++      "name": "n25q032",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "aspeed.spi1-ast2400",
++      "parent": "aspeed.smc"
++    },
++    {
++      "name": "aspeed-mmi",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pxa2xx_pic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "w25q512jv",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "piix3-usb-uhci",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "virtserialport",
++      "parent": "virtio-serial-port"
++    },
++    {
++      "name": "pvscsi",
++      "parent": "pci-device"
++    },
++    {
++      "name": "ti925t-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "virtio-rng-pci-non-transitional",
++      "parent": "virtio-rng-pci-base"
++    },
++    {
++      "name": "virt-4.2-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "virtio-serial-pci-non-transitional",
++      "parent": "virtio-serial-pci-base"
++    },
++    {
++      "name": "imx7.snvs",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "sd-bus",
++      "parent": "bus"
++    },
++    {
++      "name": "sx1-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "320s33b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "ich9-ahci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "serial",
++      "parent": "device"
++    },
++    {
++      "name": "dscm1xxxx",
++      "parent": "microdrive"
++    },
++    {
++      "name": "chardev-stdio",
++      "parent": "chardev-fd"
++    },
++    {
++      "name": "armv7m_systick",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "imx6ul.ccm",
++      "parent": "imx.ccm"
++    },
++    {
++      "name": "aux-to-i2c-bridge",
++      "parent": "device"
++    },
++    {
++      "name": "pc-dimm",
++      "parent": "device"
++    },
++    {
++      "name": "cmsdk-apb-dualtimer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vhost-vsock-pci-non-transitional",
++      "parent": "vhost-vsock-pci-base"
++    },
++    {
++      "name": "mcimx7d-sabre-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "tls-creds-anon",
++      "parent": "tls-creds"
++    },
++    {
++      "name": "arm-smmuv3",
++      "parent": "arm-smmu"
++    },
++    {
++      "name": "musca-a-machine",
++      "parent": "musca"
++    },
++    {
++      "name": "xlnx-zynmp.rtc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "n25q00a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "IndustryPack",
++      "parent": "bus"
++    },
++    {
++      "name": "cryptodev-backend",
++      "parent": "object"
++    },
++    {
++      "name": "realview-eb-mpcore-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "chardev-vc",
++      "parent": "chardev"
++    },
++    {
++      "name": "virt-2.8-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "sii9022",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "swift-bmc-machine",
++      "parent": "aspeed-machine"
++    },
++    {
++      "name": "exynos4210.clk",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "or-irq",
++      "parent": "device"
++    },
++    {
++      "name": "mx25l8005",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pl050_keyboard",
++      "parent": "pl050"
++    },
++    {
++      "name": "kzm-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "qio-channel-buffer",
++      "parent": "qio-channel"
++    },
++    {
++      "name": "pxa250-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "usb-ehci",
++      "parent": "pci-ehci-usb"
++    },
++    {
++      "name": "filter-redirector",
++      "parent": "netfilter"
++    },
++    {
++      "name": "virt-2.7-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "xgmac",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "versatile_pci",
++      "parent": "pci-host-bridge"
++    },
++    {
++      "name": "realview_sysctl",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "smc91c111",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "arm11mpcore-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "virtio-rng-pci",
++      "parent": "virtio-rng-pci-base"
++    },
++    {
++      "name": "pxa2xx-mmci",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "filter-replay",
++      "parent": "netfilter"
++    },
++    {
++      "name": "nrf51_soc.rng",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "sst25vf080b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "nrf51_soc.nvm",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "akita-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "aspeed.wdt-ast2400",
++      "parent": "aspeed.wdt"
++    },
++    {
++      "name": "qemu-console",
++      "parent": "object"
++    },
++    {
++      "name": "cortex-r5f-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "ppc4xx-ehci-usb",
++      "parent": "sysbus-ehci-usb"
++    },
++    {
++      "name": "e1000-82545em",
++      "parent": "e1000-base"
++    },
++    {
++      "name": "virtio-mmio-bus",
++      "parent": "virtio-bus"
++    },
++    {
++      "name": "vhost-user-blk-pci-transitional",
++      "parent": "vhost-user-blk-pci-base"
++    },
++    {
++      "name": "allwinner-a10",
++      "parent": "device"
++    },
++    {
++      "name": "armsse-cpuid",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "chardev-wctablet",
++      "parent": "chardev"
++    },
++    {
++      "name": "filter-buffer",
++      "parent": "netfilter"
++    },
++    {
++      "name": "sp804",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vhost-user-gpu-pci",
++      "parent": "vhost-user-gpu-pci-base-type"
++    },
++    {
++      "name": "tmp105",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "w25q80",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "piix4-usb-uhci",
++      "parent": "pci-uhci-usb"
++    },
++    {
++      "name": "integrator_pit",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "generic-sdhci",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "usb-storage",
++      "parent": "usb-storage-dev"
++    },
++    {
++      "name": "e1000-82544gc",
++      "parent": "e1000-base"
++    },
++    {
++      "name": "xilinx,zynq_slcr",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "ioh3420",
++      "parent": "pcie-root-port-base"
++    },
++    {
++      "name": "pci-serial-4x",
++      "parent": "pci-device"
++    },
++    {
++      "name": "vmcoreinfo",
++      "parent": "device"
++    },
++    {
++      "name": "mv88w8618_eth",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "versatilepb_sic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "aspeed.sdhci",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-9p-pci",
++      "parent": "virtio-9p-pci-base"
++    },
++    {
++      "name": "integrator_pic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "versatile_i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "m25p128",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "en25f32",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "z2-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "s70fs01gs",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "at26f004",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virtio-9p-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "ich9-intel-hda",
++      "parent": "intel-hda-generic"
++    },
++    {
++      "name": "s25fs512s",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "sbsa-ref-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "n25q256a13",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "160s33b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "n25q256a11",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "imx-usdhc",
++      "parent": "generic-sdhci"
++    },
++    {
++      "name": "secret",
++      "parent": "object"
++    },
++    {
++      "name": "exynos4210.irq_gate",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "musicpal-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "stm32f2xx-spi",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "imx6.src",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "exynos4210.combiner",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pxa25x-timer",
++      "parent": "pxa2xx-timer"
++    },
++    {
++      "name": "arm926-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "chardev-serial",
++      "parent": "chardev-fd"
++    },
++    {
++      "name": "virt-2.9-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "vhost-user-blk-pci-non-transitional",
++      "parent": "vhost-user-blk-pci-base"
++    },
++    {
++      "name": "exynos4210.pmu",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vhost-user-backend",
++      "parent": "object"
++    },
++    {
++      "name": "imx7.ccm",
++      "parent": "imx.ccm"
++    },
++    {
++      "name": "ipoctal232",
++      "parent": "ipack-device"
++    },
++    {
++      "name": "vhost-user-fs-pci",
++      "parent": "vhost-user-fs-pci-base"
++    },
++    {
++      "name": "virtio-pci-bus",
++      "parent": "virtio-bus"
++    },
++    {
++      "name": "omap_i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "omap-gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "cmsdk-apb-uart",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-tablet-device",
++      "parent": "virtio-input-hid-device"
++    },
++    {
++      "name": "w25q64",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "virtio-scsi-pci",
++      "parent": "virtio-scsi-pci-base"
++    },
++    {
++      "name": "at25df041a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "mx25l12805d",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "x3130-upstream",
++      "parent": "pcie-port"
++    },
++    {
++      "name": "ES1370",
++      "parent": "pci-device"
++    },
++    {
++      "name": "tz-ppc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pci-testdev",
++      "parent": "pci-device"
++    },
++    {
++      "name": "at25fs040",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "emcraft-sf2-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "aspeed.rtc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "authz-list",
++      "parent": "authz"
++    },
++    {
++      "name": "xlnx.ps7-spi",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "e1000e",
++      "parent": "pci-device"
++    },
++    {
++      "name": "cortex-m33-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "virtio-balloon-pci-transitional",
++      "parent": "virtio-balloon-pci-base"
++    },
++    {
++      "name": "cortex-a72-arm-cpu",
++      "parent": "aarch64-cpu"
++    },
++    {
++      "name": "ARM,bitband-memory",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "tcg-accel",
++      "parent": "accel"
++    },
++    {
++      "name": "nrf51-soc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtconsole",
++      "parent": "virtserialport"
++    },
++    {
++      "name": "mx25l25655e",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "mss-timer",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "msf2-sysreg",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pci-serial-2x",
++      "parent": "pci-device"
++    },
++    {
++      "name": "mps2-scc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "colo-compare",
++      "parent": "object"
++    },
++    {
++      "name": "vhost-user-scsi-pci-transitional",
++      "parent": "vhost-user-scsi-pci-base"
++    },
++    {
++      "name": "mps2-fpgaio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-tablet-pci",
++      "parent": "virtio-tablet-pci-base-type"
++    },
++    {
++      "name": "allwinner-emac",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "i82801b11-bridge",
++      "parent": "base-pci-bridge"
++    },
++    {
++      "name": "bcm2836-control",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "bcm2835-peripherals",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "arm-its-kvm",
++      "parent": "arm-gicv3-its-common"
++    },
++    {
++      "name": "realview-pb-a8-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "fsl,imx7",
++      "parent": "device"
++    },
++    {
++      "name": "fsl,imx6",
++      "parent": "device"
++    },
++    {
++      "name": "usb-bus",
++      "parent": "bus"
++    },
++    {
++      "name": "versatilepb-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "w25q80bl",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa255-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "at26df321",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "musicpal_key",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "PCI",
++      "parent": "bus"
++    },
++    {
++      "name": "pxa261-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "tosa-ssp",
++      "parent": "ssi-slave"
++    },
++    {
++      "name": "pl050_mouse",
++      "parent": "pl050"
++    },
++    {
++      "name": "tulip",
++      "parent": "pci-device"
++    },
++    {
++      "name": "tz-msc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "strongarm-ppc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "fusbh200-ehci-usb",
++      "parent": "sysbus-ehci-usb"
++    },
++    {
++      "name": "aspeed.i2c-ast2600",
++      "parent": "aspeed.i2c"
++    },
++    {
++      "name": "vhost-user-scsi",
++      "parent": "vhost-scsi-common"
++    },
++    {
++      "name": "arm1136-r2-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "imx.enet",
++      "parent": "imx.fec"
++    },
++    {
++      "name": "esp",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "usb-braille",
++      "parent": "usb-serial-dev"
++    },
++    {
++      "name": "pxa260-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "ast2400-a1",
++      "parent": "aspeed-soc"
++    },
++    {
++      "name": "arm-gicv3",
++      "parent": "arm-gicv3-common"
++    },
++    {
++      "name": "stellaris_enet",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "musicpal_lcd",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "fsl,imx6ul",
++      "parent": "device"
++    },
++    {
++      "name": "realview-eb-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "ne2k_pci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "realview-pbx-a9-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "ivshmem-plain",
++      "parent": "ivshmem-common"
++    },
++    {
++      "name": "vhost-user-blk",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "usb-kbd",
++      "parent": "usb-hid"
++    },
++    {
++      "name": "musca-b1-machine",
++      "parent": "musca"
++    },
++    {
++      "name": "authz-simple",
++      "parent": "authz"
++    },
++    {
++      "name": "pxa2xx_i2c",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "a9-scu",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "imx31.ccm",
++      "parent": "imx.ccm"
++    },
++    {
++      "name": "cortex-a15-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "spitz-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "hda-duplex",
++      "parent": "hda-audio"
++    },
++    {
++      "name": "megasas-gen2",
++      "parent": "megasas-base"
++    },
++    {
++      "name": "none-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "virtio-9p-pci-transitional",
++      "parent": "virtio-9p-pci-base"
++    },
++    {
++      "name": "mt25ql01g",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "w25q32",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "stm32f205-soc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "wm8750",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "virtio-balloon-device",
++      "parent": "virtio-device"
++    },
++    {
++      "name": "kvaser_pci",
++      "parent": "pci-device"
++    },
++    {
++      "name": "allwinner-ahci",
++      "parent": "sysbus-ahci"
++    },
++    {
++      "name": "m25px64",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pl011_luminary",
++      "parent": "pl011"
++    },
++    {
++      "name": "at25fs010",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "allwinner-a10-pic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "usb-wacom-tablet",
++      "parent": "usb-device"
++    },
++    {
++      "name": "nvme",
++      "parent": "pci-device"
++    },
++    {
++      "name": "imx25-pdk-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "scsi-disk",
++      "parent": "scsi-disk-base"
++    },
++    {
++      "name": "vhost-scsi-pci-transitional",
++      "parent": "vhost-scsi-pci-base"
++    },
++    {
++      "name": "ramfb",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "arm1136-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "mx25l4005a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "usb-tablet",
++      "parent": "usb-hid"
++    },
++    {
++      "name": "xlnx.ps7-qspi",
++      "parent": "xlnx.ps7-spi"
++    },
++    {
++      "name": "vhost-user-input-pci",
++      "parent": "vhost-user-input-pci-base-type"
++    },
++    {
++      "name": "bcm2835-thermal",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xlnx-versal-virt-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "intel-hda",
++      "parent": "intel-hda-generic"
++    },
++    {
++      "name": "aspeed.i2c-ast2500",
++      "parent": "aspeed.i2c"
++    },
++    {
++      "name": "en25q64",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "kvm-accel",
++      "parent": "accel"
++    },
++    {
++      "name": "collie-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "arm11mpcore_priv",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "imx.spi",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xlnx.xps-spi",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "realview_gic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-scsi-device",
++      "parent": "virtio-scsi-common"
++    },
++    {
++      "name": "bcm2835-mbox",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "smdkc210-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "AC97",
++      "parent": "pci-device"
++    },
++    {
++      "name": "ds1338",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "arm11-scu",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pxa270-a0-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "virtio-blk-pci-transitional",
++      "parent": "virtio-blk-pci-base"
++    },
++    {
++      "name": "xilinx-axi-dma-data-stream",
++      "parent": "object"
++    },
++    {
++      "name": "pxa262-arm-cpu",
++      "parent": "arm-cpu"
++    },
++    {
++      "name": "tls-creds-x509",
++      "parent": "tls-creds"
++    },
++    {
++      "name": "sd-card",
++      "parent": "device"
++    },
++    {
++      "name": "bcm2835_gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "i2c-bus",
++      "parent": "bus"
++    },
++    {
++      "name": "virtio-mouse-device",
++      "parent": "virtio-input-hid-device"
++    },
++    {
++      "name": "exynos4210.uart",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mx25l25635e",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "640s33b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pl110_versatile",
++      "parent": "pl110"
++    },
++    {
++      "name": "ast2500-evb-machine",
++      "parent": "aspeed-machine"
++    },
++    {
++      "name": "ast2600-a0",
++      "parent": "aspeed-soc"
++    },
++    {
++      "name": "i6300esb",
++      "parent": "pci-device"
++    },
++    {
++      "name": "mainstone-fpga",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "qio-dns-resolver",
++      "parent": "object"
++    },
++    {
++      "name": "aux-bus",
++      "parent": "bus"
++    },
++    {
++      "name": "virt-3.0-machine",
++      "parent": "virt-machine"
++    },
++    {
++      "name": "stm32f405-soc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "mx25l2005a",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "a9mpcore_priv",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xilinx-axienet-data-stream",
++      "parent": "object"
++    },
++    {
++      "name": "aspeed.vic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "stm32f4xx-exti",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "pvrdma",
++      "parent": "pci-device"
++    },
++    {
++      "name": "cadence_gem",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "sst25vf040b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "ide-drive",
++      "parent": "ide-device"
++    },
++    {
++      "name": "sst25vf032b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "bcm2837",
++      "parent": "bcm283x"
++    },
++    {
++      "name": "bcm2836",
++      "parent": "bcm283x"
++    },
++    {
++      "name": "sst25vf016b",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "vfio-platform",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-net-pci-non-transitional",
++      "parent": "virtio-net-pci-base"
++    },
++    {
++      "name": "omap2-gpio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "imx.serial",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "vmxnet3",
++      "parent": "pci-device"
++    },
++    {
++      "name": "pca9552",
++      "parent": "i2c-slave"
++    },
++    {
++      "name": "aspeed.i2c-ast2400",
++      "parent": "aspeed.i2c"
++    },
++    {
++      "name": "en25p64",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "pxa2xx-ssp",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "xlnx.zynqmp_ipi",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "tz-mpc",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "virtio-scsi-pci-non-transitional",
++      "parent": "virtio-scsi-pci-base"
++    },
++    {
++      "name": "verdex-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "mps2-an505-machine",
++      "parent": "mps2tz"
++    },
++    {
++      "name": "m25px32",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "smmuv3-iommu-memory-region",
++      "parent": "qemu:iommu-memory-region"
++    },
++    {
++      "name": "m25px32-s1",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "m25px32-s0",
++      "parent": "m25p80-generic"
++    },
++    {
++      "name": "mps2-an511-machine",
++      "parent": "mps2"
++    },
++    {
++      "name": "vfio-calxeda-xgmac",
++      "parent": "vfio-platform"
++    },
++    {
++      "name": "imx.avic",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "nuri-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "tls-creds-psk",
++      "parent": "tls-creds"
++    },
++    {
++      "name": "vhost-vsock-pci-transitional",
++      "parent": "vhost-vsock-pci-base"
++    },
++    {
++      "name": "integratorcp-machine",
++      "parent": "machine"
++    },
++    {
++      "name": "qio-channel-tls",
++      "parent": "qio-channel"
++    },
++    {
++      "name": "virtio-mmio",
++      "parent": "sys-bus-device"
++    },
++    {
++      "name": "scsi-generic",
++      "parent": "scsi-device"
++    },
++    {
++      "name": "rng-random",
++      "parent": "rng-backend"
++    },
++    {
++      "name": "rng-builtin",
++      "parent": "rng-backend"
++    },
++    {
++      "name": "usb-bot",
++      "parent": "usb-storage-dev"
++    },
++    {
++      "name": "qemu-xhci",
++      "parent": "base-xhci"
++    }
++  ],
++  "id": "libvirt-6"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-blk-pci"
++  },
++  "id": "libvirt-7"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": false,
++      "name": "virtio-pci-bus-master-bug-migration",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnkctl-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-flr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-ignore-backend-features",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "page-per-vq",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "migrate-extra",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-pm-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "modern-pio-notify",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-deverr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "ats",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-disable-pcie",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "vectors",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "ioeventfd",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "class",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "disable-modern",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "disable-legacy",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": true,
++      "name": "request-merging",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "secs",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "min_io_size",
++      "type": "uint16"
++    },
++    {
++      "default-value": true,
++      "name": "event_idx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "lsecs",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "heads",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "use-disabled-flag",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "write-zeroes",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "cyls",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "logical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "default-value": false,
++      "name": "scsi",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "lcyls",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "indirect_desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 4194303,
++      "name": "max-write-zeroes-sectors",
++      "type": "uint32"
++    },
++    {
++      "name": "drive",
++      "description": "Node name or ID of a block device to use as a backend",
++      "type": "str"
++    },
++    {
++      "default-value": "auto",
++      "name": "werror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "discard_granularity",
++      "type": "uint32"
++    },
++    {
++      "default-value": "auto",
++      "name": "rerror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "default-value": true,
++      "name": "x-enable-wce-if-config-wce",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "lheads",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "any_layout",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "share-rw",
++      "type": "bool"
++    },
++    {
++      "name": "iothread",
++      "type": "link<iothread>"
++    },
++    {
++      "default-value": true,
++      "name": "use-started",
++      "type": "bool"
++    },
++    {
++      "name": "bootindex",
++      "type": "int32"
++    },
++    {
++      "default-value": 0,
++      "name": "physical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "default-value": false,
++      "name": "iommu_platform",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "packed",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "virtio-backend",
++      "type": "child<virtio-blk-device>"
++    },
++    {
++      "default-value": true,
++      "name": "seg-max-adjust",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "config-wce",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "discard",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "notify_on_empty",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "serial",
++      "type": "str"
++    },
++    {
++      "default-value": 128,
++      "name": "queue-size",
++      "type": "uint16"
++    },
++    {
++      "default-value": 1,
++      "name": "num-queues",
++      "type": "uint16"
++    },
++    {
++      "default-value": "auto",
++      "name": "write-cache",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": 4194303,
++      "name": "max-discard-sectors",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "opt_io_size",
++      "type": "uint32"
++    }
++  ],
++  "id": "libvirt-7"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-net-pci"
++  },
++  "id": "libvirt-8"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": false,
++      "name": "virtio-pci-bus-master-bug-migration",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnkctl-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-flr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-ignore-backend-features",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "page-per-vq",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "migrate-extra",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-pm-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "modern-pio-notify",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-deverr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "ats",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-disable-pcie",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 3,
++      "name": "vectors",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "ioeventfd",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "disable-modern",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "disable-legacy",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": true,
++      "name": "event_idx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "packed",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "guest_ufo",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "host_ecn",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 150000,
++      "name": "x-txtimer",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "mq",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "status",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 256,
++      "name": "tx_queue_size",
++      "type": "uint16"
++    },
++    {
++      "default-value": true,
++      "name": "use-disabled-flag",
++      "type": "bool"
++    },
++    {
++      "name": "tx",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "ctrl_rx_extra",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 300000,
++      "name": "rsc_interval",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "indirect_desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "mac",
++      "description": "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
++      "type": "str"
++    },
++    {
++      "default-value": 256,
++      "name": "rx_queue_size",
++      "type": "uint16"
++    },
++    {
++      "default-value": true,
++      "name": "guest_ecn",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "guest_tso6",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "speed",
++      "type": "int32"
++    },
++    {
++      "default-value": true,
++      "name": "guest_tso4",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "guest_csum",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "guest_announce",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "gso",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "ctrl_vq",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "ctrl_rx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "duplex",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "ctrl_vlan",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 256,
++      "name": "x-txburst",
++      "type": "int32"
++    },
++    {
++      "default-value": true,
++      "name": "csum",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "mrg_rxbuf",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "ctrl_guest_offloads",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "any_layout",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "failover",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "ctrl_mac_addr",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "host_tso6",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-mtu-bypass-backend",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "host_tso4",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "host_ufo",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "virtio-backend",
++      "type": "child<virtio-net-device>"
++    },
++    {
++      "name": "bootindex",
++      "type": "int32"
++    },
++    {
++      "name": "netdev",
++      "description": "ID of a netdev to use as a backend",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "use-started",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "notify_on_empty",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "guest_rsc_ext",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "iommu_platform",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "host_mtu",
++      "type": "uint16"
++    }
++  ],
++  "id": "libvirt-8"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-scsi-pci"
++  },
++  "id": "libvirt-9"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": false,
++      "name": "virtio-pci-bus-master-bug-migration",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnkctl-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-flr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-ignore-backend-features",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "page-per-vq",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "migrate-extra",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-pm-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "modern-pio-notify",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-deverr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "ats",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-disable-pcie",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "vectors",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "ioeventfd",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "disable-modern",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "disable-legacy",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": true,
++      "name": "notify_on_empty",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 65535,
++      "name": "max_sectors",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "any_layout",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 128,
++      "name": "cmd_per_lun",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "indirect_desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-started",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "event_idx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "iothread",
++      "type": "link<iothread>"
++    },
++    {
++      "default-value": 128,
++      "name": "virtqueue_size",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "hotplug",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "virtio-backend",
++      "type": "child<virtio-scsi-device>"
++    },
++    {
++      "default-value": 1,
++      "name": "num_queues",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "param_change",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "seg_max_adjust",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "iommu_platform",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-disabled-flag",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "packed",
++      "description": "on/off",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-9"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-net-ccw"
++  },
++  "id": "libvirt-10"
++}
++
++{
++  "id": "libvirt-10",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'virtio-net-ccw' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-scsi-ccw"
++  },
++  "id": "libvirt-11"
++}
++
++{
++  "id": "libvirt-11",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'virtio-scsi-ccw' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-net-s390"
++  },
++  "id": "libvirt-12"
++}
++
++{
++  "id": "libvirt-12",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'virtio-net-s390' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "vfio-pci"
++  },
++  "id": "libvirt-13"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "x-pci-sub-device-id",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "x-no-kvm-msi",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-igd-opregion",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": "off",
++      "name": "display",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": false,
++      "name": "x-vga",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "x-pci-vendor-id",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "x-balloon-allowed",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-req",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-no-vfio-ioeventfd",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-no-geforce-quirks",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-no-kvm-ioeventfd",
++      "type": "bool"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "x-pci-device-id",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "x-no-kvm-intx",
++      "type": "bool"
++    },
++    {
++      "name": "host",
++      "description": "Address (bus/device/function) of the host device, example: 04:10.0",
++      "type": "str"
++    },
++    {
++      "default-value": false,
++      "name": "x-no-kvm-msix",
++      "type": "bool"
++    },
++    {
++      "default-value": 1100,
++      "name": "x-intx-mmap-timeout-ms",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "yres",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "x-igd-gms",
++      "type": "uint32"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "x-pci-sub-vendor-id",
++      "type": "uint32"
++    },
++    {
++      "name": "x-nv-gpudirect-clique",
++      "description": "NVIDIA GPUDirect Clique ID (0 - 15)",
++      "type": "uint4"
++    },
++    {
++      "name": "sysfsdev",
++      "type": "str"
++    },
++    {
++      "default-value": 0,
++      "name": "xres",
++      "type": "uint32"
++    },
++    {
++      "default-value": "off",
++      "name": "x-msix-relocation",
++      "description": "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
++      "type": "OffAutoPCIBAR"
++    },
++    {
++      "default-value": false,
++      "name": "x-no-mmap",
++      "type": "bool"
++    },
++    {
++      "name": "bootindex",
++      "type": "int32"
++    }
++  ],
++  "id": "libvirt-13"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "scsi-hd"
++  },
++  "id": "libvirt-14"
++}
++
++{
++  "return": [
++    {
++      "default-value": 4294967295,
++      "name": "scsi-id",
++      "type": "uint32"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "lun",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "channel",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "heads",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "port_index",
++      "type": "uint16"
++    },
++    {
++      "default-value": false,
++      "name": "dpofua",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "serial",
++      "type": "str"
++    },
++    {
++      "default-value": 1073741824,
++      "name": "max_unmap_size",
++      "type": "uint64"
++    },
++    {
++      "default-value": 0,
++      "name": "logical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "discard_granularity",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "rotation_rate",
++      "type": "uint16"
++    },
++    {
++      "name": "device_id",
++      "type": "str"
++    },
++    {
++      "name": "drive",
++      "description": "Node name or ID of a block device to use as a backend",
++      "type": "str"
++    },
++    {
++      "default-value": 0,
++      "name": "port_wwn",
++      "type": "uint64"
++    },
++    {
++      "default-value": 0,
++      "name": "opt_io_size",
++      "type": "uint32"
++    },
++    {
++      "default-value": 5,
++      "name": "scsi_version",
++      "type": "int32"
++    },
++    {
++      "default-value": 0,
++      "name": "min_io_size",
++      "type": "uint16"
++    },
++    {
++      "default-value": "auto",
++      "name": "write-cache",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": false,
++      "name": "share-rw",
++      "type": "bool"
++    },
++    {
++      "name": "product",
++      "type": "str"
++    },
++    {
++      "default-value": 0,
++      "name": "lsecs",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "lheads",
++      "type": "uint32"
++    },
++    {
++      "name": "vendor",
++      "type": "str"
++    },
++    {
++      "default-value": 0,
++      "name": "lcyls",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "secs",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "wwn",
++      "type": "uint64"
++    },
++    {
++      "default-value": "auto",
++      "name": "werror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "default-value": false,
++      "name": "removable",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "cyls",
++      "type": "uint32"
++    },
++    {
++      "name": "ver",
++      "type": "str"
++    },
++    {
++      "default-value": "auto",
++      "name": "rerror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "default-value": 0,
++      "name": "physical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "default-value": 2147483647,
++      "name": "max_io_size",
++      "type": "uint64"
++    },
++    {
++      "name": "bootindex",
++      "type": "int32"
++    }
++  ],
++  "id": "libvirt-14"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "ide-hd"
++  },
++  "id": "libvirt-15"
++}
++
++{
++  "return": [
++    {
++      "default-value": 4294967295,
++      "name": "unit",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "lsecs",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "secs",
++      "type": "uint32"
++    },
++    {
++      "name": "serial",
++      "type": "str"
++    },
++    {
++      "default-value": 0,
++      "name": "lcyls",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "logical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "discard_granularity",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "rotation_rate",
++      "type": "uint16"
++    },
++    {
++      "name": "drive",
++      "description": "Node name or ID of a block device to use as a backend",
++      "type": "str"
++    },
++    {
++      "default-value": 0,
++      "name": "heads",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "opt_io_size",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "min_io_size",
++      "type": "uint16"
++    },
++    {
++      "default-value": "auto",
++      "name": "write-cache",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": false,
++      "name": "share-rw",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "bios-chs-trans",
++      "description": "Logical CHS translation algorithm, auto/none/lba/large/rechs",
++      "type": "BiosAtaTranslation"
++    },
++    {
++      "default-value": 0,
++      "name": "lheads",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "wwn",
++      "type": "uint64"
++    },
++    {
++      "default-value": "auto",
++      "name": "werror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "name": "model",
++      "type": "str"
++    },
++    {
++      "name": "ver",
++      "type": "str"
++    },
++    {
++      "default-value": "auto",
++      "name": "rerror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "default-value": 0,
++      "name": "physical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "default-value": 0,
++      "name": "cyls",
++      "type": "uint32"
++    },
++    {
++      "name": "bootindex",
++      "type": "int32"
++    }
++  ],
++  "id": "libvirt-15"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "PIIX4_PM"
++  },
++  "id": "libvirt-16"
++}
++
++{
++  "id": "libvirt-16",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'PIIX4_PM' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "i440FX-pcihost"
++  },
++  "id": "libvirt-17"
++}
++
++{
++  "id": "libvirt-17",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'i440FX-pcihost' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "q35-pcihost"
++  },
++  "id": "libvirt-18"
++}
++
++{
++  "id": "libvirt-18",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'q35-pcihost' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "usb-storage"
++  },
++  "id": "libvirt-19"
++}
++
++{
++  "return": [
++    {
++      "default-value": true,
++      "name": "msos-desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "port",
++      "type": "str"
++    },
++    {
++      "name": "serial",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "full-path",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "logical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "default-value": 4294967295,
++      "name": "discard_granularity",
++      "type": "uint32"
++    },
++    {
++      "name": "drive",
++      "description": "Node name or ID of a block device to use as a backend",
++      "type": "str"
++    },
++    {
++      "default-value": 0,
++      "name": "opt_io_size",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "min_io_size",
++      "type": "uint16"
++    },
++    {
++      "default-value": "auto",
++      "name": "write-cache",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": false,
++      "name": "share-rw",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "werror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "default-value": false,
++      "name": "removable",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "rerror",
++      "description": "Error handling policy, report/ignore/enospc/stop/auto",
++      "type": "BlockdevOnError"
++    },
++    {
++      "default-value": 0,
++      "name": "physical_block_size",
++      "description": "A power of two between 512 and 32768",
++      "type": "uint16"
++    },
++    {
++      "name": "bootindex",
++      "type": "int32"
++    },
++    {
++      "name": "attached",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-19"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "kvm-pit"
++  },
++  "id": "libvirt-20"
++}
++
++{
++  "id": "libvirt-20",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'kvm-pit' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "VGA"
++  },
++  "id": "libvirt-21"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "mmio",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "qemu-extended-regs",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "ymax",
++      "type": "uint32"
++    },
++    {
++      "default-value": 16,
++      "name": "vgamem_mb",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "yres",
++      "type": "uint32"
++    },
++    {
++      "default-value": 0,
++      "name": "xmax",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "edid",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "xres",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "global-vmstate",
++      "type": "bool"
++    },
++    {
++      "name": "big-endian-framebuffer",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-21"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "vmware-svga"
++  },
++  "id": "libvirt-22"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": 16,
++      "name": "vgamem_mb",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "global-vmstate",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-22"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-gpu-pci"
++  },
++  "id": "libvirt-23"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": false,
++      "name": "virtio-pci-bus-master-bug-migration",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnkctl-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-flr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-ignore-backend-features",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "page-per-vq",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "migrate-extra",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-pm-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "modern-pio-notify",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-deverr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "ats",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-disable-pcie",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 3,
++      "name": "vectors",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "ioeventfd",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "disable-modern",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "disable-legacy",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": true,
++      "name": "notify_on_empty",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "any_layout",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "indirect_desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-started",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "event_idx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "virtio-backend",
++      "type": "child<virtio-gpu-device>"
++    },
++    {
++      "default-value": 768,
++      "name": "yres",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "use-disabled-flag",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "iommu_platform",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "edid",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 1,
++      "name": "max_outputs",
++      "type": "uint32"
++    },
++    {
++      "default-value": 268435456,
++      "name": "max_hostmem",
++      "type": "size"
++    },
++    {
++      "default-value": 1024,
++      "name": "xres",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "packed",
++      "description": "on/off",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-23"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-gpu-device"
++  },
++  "id": "libvirt-24"
++}
++
++{
++  "return": [
++    {
++      "default-value": true,
++      "name": "notify_on_empty",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "any_layout",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "indirect_desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-started",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "event_idx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "iommu_platform",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-disabled-flag",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "packed",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "edid",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 268435456,
++      "name": "max_hostmem",
++      "type": "size"
++    },
++    {
++      "default-value": 1024,
++      "name": "xres",
++      "type": "uint32"
++    },
++    {
++      "default-value": 768,
++      "name": "yres",
++      "type": "uint32"
++    },
++    {
++      "default-value": 1,
++      "name": "max_outputs",
++      "type": "uint32"
++    }
++  ],
++  "id": "libvirt-24"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "ICH9-LPC"
++  },
++  "id": "libvirt-25"
++}
++
++{
++  "id": "libvirt-25",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'ICH9-LPC' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-balloon-pci"
++  },
++  "id": "libvirt-26"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": false,
++      "name": "virtio-pci-bus-master-bug-migration",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnkctl-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-flr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-ignore-backend-features",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "page-per-vq",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "migrate-extra",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-pm-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "modern-pio-notify",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-deverr-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "ats",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "x-disable-pcie",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 0,
++      "name": "class",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "disable-modern",
++      "type": "bool"
++    },
++    {
++      "default-value": "auto",
++      "name": "disable-legacy",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": true,
++      "name": "notify_on_empty",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "any_layout",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "indirect_desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-started",
++      "type": "bool"
++    },
++    {
++      "name": "guest-stats",
++      "type": "guest statistics"
++    },
++    {
++      "name": "guest-stats-polling-interval",
++      "type": "int"
++    },
++    {
++      "default-value": true,
++      "name": "event_idx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "iothread",
++      "type": "link<iothread>"
++    },
++    {
++      "default-value": false,
++      "name": "free-page-hint",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "virtio-backend",
++      "type": "child<virtio-balloon-device>"
++    },
++    {
++      "default-value": false,
++      "name": "iommu_platform",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "qemu-4-0-config-size",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-disabled-flag",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "packed",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "deflate-on-oom",
++      "description": "on/off",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-26"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-balloon-ccw"
++  },
++  "id": "libvirt-27"
++}
++
++{
++  "id": "libvirt-27",
++  "error": {
++    "class": "DeviceNotFound",
++    "desc": "Device 'virtio-balloon-ccw' not found"
++  }
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "virtio-balloon-device"
++  },
++  "id": "libvirt-28"
++}
++
++{
++  "return": [
++    {
++      "default-value": true,
++      "name": "notify_on_empty",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "any_layout",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "indirect_desc",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-started",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "event_idx",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "iommu_platform",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": true,
++      "name": "use-disabled-flag",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "packed",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "free-page-hint",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "deflate-on-oom",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "iothread",
++      "type": "link<iothread>"
++    },
++    {
++      "default-value": false,
++      "name": "qemu-4-0-config-size",
++      "type": "bool"
++    },
++    {
++      "name": "guest-stats",
++      "type": "guest statistics"
++    },
++    {
++      "name": "guest-stats-polling-interval",
++      "type": "int"
++    }
++  ],
++  "id": "libvirt-28"
++}
++
++{
++  "execute": "device-list-properties",
++  "arguments": {
++    "typename": "nec-usb-xhci"
++  },
++  "id": "libvirt-29"
++}
++
++{
++  "return": [
++    {
++      "default-value": 1,
++      "name": "rombar",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-lnksta-dllla",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": false,
++      "name": "multifunction",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "name": "romfile",
++      "type": "str"
++    },
++    {
++      "default-value": true,
++      "name": "x-pcie-extcap-init",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": -1,
++      "name": "addr",
++      "description": "Slot and optional function number, example: 06.0 or 06",
++      "type": "int32"
++    },
++    {
++      "name": "failover_pair_id",
++      "type": "str"
++    },
++    {
++      "default-value": 4,
++      "name": "p3",
++      "type": "uint32"
++    },
++    {
++      "default-value": true,
++      "name": "streams",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 4,
++      "name": "p2",
++      "type": "uint32"
++    },
++    {
++      "default-value": "auto",
++      "name": "msi",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": 16,
++      "name": "intrs",
++      "type": "uint32"
++    },
++    {
++      "default-value": false,
++      "name": "force-pcie-endcap",
++      "description": "on/off",
++      "type": "bool"
++    },
++    {
++      "default-value": 64,
++      "name": "slots",
++      "type": "uint32"
++    },
++    {
++      "default-value": "auto",
++      "name": "msix",
++      "description": "on/off/auto",
++      "type": "OnOffAuto"
++    },
++    {
++      "default-value": true,
++      "name": "superspeed-ports-first",
++      "description": "on/off",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-29"
++}
++
++{
++  "execute": "qom-list-properties",
++  "arguments": {
++    "typename": "memory-backend-file"
++  },
++  "id": "libvirt-30"
++}
++
++{
++  "return": [
++    {
++      "name": "type",
++      "type": "string"
++    },
++    {
++      "name": "policy",
++      "description": "Set the NUMA policy",
++      "type": "HostMemPolicy"
++    },
++    {
++      "name": "dump",
++      "description": "Set to 'off' to exclude from core dump",
++      "type": "bool"
++    },
++    {
++      "name": "share",
++      "description": "Mark the memory as private to QEMU or shared",
++      "type": "bool"
++    },
++    {
++      "name": "prealloc",
++      "description": "Preallocate memory",
++      "type": "bool"
++    },
++    {
++      "name": "size",
++      "description": "Size of the memory region (ex: 500M)",
++      "type": "int"
++    },
++    {
++      "name": "x-use-canonical-path-for-ramblock-id",
++      "type": "bool"
++    },
++    {
++      "name": "host-nodes",
++      "description": "Binds memory to the list of NUMA host nodes",
++      "type": "int"
++    },
++    {
++      "name": "merge",
++      "description": "Mark memory as mergeable",
++      "type": "bool"
++    },
++    {
++      "name": "pmem",
++      "type": "bool"
++    },
++    {
++      "name": "align",
++      "type": "int"
++    },
++    {
++      "name": "mem-path",
++      "type": "string"
++    },
++    {
++      "name": "discard-data",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-30"
++}
++
++{
++  "execute": "qom-list-properties",
++  "arguments": {
++    "typename": "memory-backend-memfd"
++  },
++  "id": "libvirt-31"
++}
++
++{
++  "return": [
++    {
++      "name": "type",
++      "type": "string"
++    },
++    {
++      "name": "policy",
++      "description": "Set the NUMA policy",
++      "type": "HostMemPolicy"
++    },
++    {
++      "name": "dump",
++      "description": "Set to 'off' to exclude from core dump",
++      "type": "bool"
++    },
++    {
++      "name": "share",
++      "description": "Mark the memory as private to QEMU or shared",
++      "type": "bool"
++    },
++    {
++      "name": "prealloc",
++      "description": "Preallocate memory",
++      "type": "bool"
++    },
++    {
++      "name": "size",
++      "description": "Size of the memory region (ex: 500M)",
++      "type": "int"
++    },
++    {
++      "name": "x-use-canonical-path-for-ramblock-id",
++      "type": "bool"
++    },
++    {
++      "name": "host-nodes",
++      "description": "Binds memory to the list of NUMA host nodes",
++      "type": "int"
++    },
++    {
++      "name": "merge",
++      "description": "Mark memory as mergeable",
++      "type": "bool"
++    },
++    {
++      "name": "seal",
++      "description": "Seal growing & shrinking",
++      "type": "bool"
++    },
++    {
++      "name": "hugetlbsize",
++      "description": "Huge pages size (ex: 2M, 1G)",
++      "type": "int"
++    },
++    {
++      "name": "hugetlb",
++      "description": "Use huge pages",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-31"
++}
++
++{
++  "execute": "qom-list-properties",
++  "arguments": {
++    "typename": "max-arm-cpu"
++  },
++  "id": "libvirt-32"
++}
++
++{
++  "return": [
++    {
++      "name": "type",
++      "type": "string"
++    },
++    {
++      "name": "parent_bus",
++      "type": "link<bus>"
++    },
++    {
++      "name": "hotplugged",
++      "type": "bool"
++    },
++    {
++      "name": "hotpluggable",
++      "type": "bool"
++    },
++    {
++      "name": "realized",
++      "type": "bool"
++    },
++    {
++      "name": "legacy-memory",
++      "type": "str"
++    },
++    {
++      "name": "memory",
++      "type": "link<qemu:memory-region>"
++    },
++    {
++      "name": "psci-conduit",
++      "type": "uint32"
++    },
++    {
++      "name": "core-count",
++      "type": "int32"
++    },
++    {
++      "name": "start-powered-off",
++      "type": "bool"
++    },
++    {
++      "name": "mp-affinity",
++      "type": "uint64"
++    },
++    {
++      "name": "node-id",
++      "type": "int32"
++    },
++    {
++      "name": "midr",
++      "type": "uint32"
++    },
++    {
++      "name": "sve640",
++      "type": "bool"
++    },
++    {
++      "name": "sve1152",
++      "type": "bool"
++    },
++    {
++      "name": "sve1408",
++      "type": "bool"
++    },
++    {
++      "name": "unnamed-gpio-in[3]",
++      "type": "child<irq>"
++    },
++    {
++      "name": "unnamed-gpio-in[1]",
++      "type": "child<irq>"
++    },
++    {
++      "name": "sve1664",
++      "type": "bool"
++    },
++    {
++      "name": "sve128",
++      "type": "bool"
++    },
++    {
++      "name": "aarch64",
++      "description": "Set on/off to enable/disable aarch64 execution state ",
++      "type": "bool"
++    },
++    {
++      "name": "sve2048",
++      "type": "bool"
++    },
++    {
++      "name": "rvbar",
++      "type": "uint64"
++    },
++    {
++      "name": "cntfrq",
++      "type": "uint64"
++    },
++    {
++      "name": "sve384",
++      "type": "bool"
++    },
++    {
++      "name": "unnamed-gpio-out[2]",
++      "type": "link<irq>"
++    },
++    {
++      "name": "kvm-no-adjvtime",
++      "description": "Set on to disable the adjustment of the virtual counter. VM stopped time will be counted.",
++      "type": "bool"
++    },
++    {
++      "name": "unnamed-gpio-out[0]",
++      "type": "link<irq>"
++    },
++    {
++      "name": "sve512",
++      "type": "bool"
++    },
++    {
++      "name": "sve896",
++      "type": "bool"
++    },
++    {
++      "name": "gicv3-maintenance-interrupt[0]",
++      "type": "link<irq>"
++    },
++    {
++      "name": "sve1024",
++      "type": "bool"
++    },
++    {
++      "name": "pmu-interrupt[0]",
++      "type": "link<irq>"
++    },
++    {
++      "name": "sve1280",
++      "type": "bool"
++    },
++    {
++      "name": "sve1536",
++      "type": "bool"
++    },
++    {
++      "name": "unnamed-gpio-in[2]",
++      "type": "child<irq>"
++    },
++    {
++      "name": "sve-max-vq",
++      "type": "uint32"
++    },
++    {
++      "name": "sve",
++      "type": "bool"
++    },
++    {
++      "name": "unnamed-gpio-in[0]",
++      "type": "child<irq>"
++    },
++    {
++      "name": "sve256",
++      "type": "bool"
++    },
++    {
++      "name": "sve1792",
++      "type": "bool"
++    },
++    {
++      "name": "unnamed-gpio-out[3]",
++      "type": "link<irq>"
++    },
++    {
++      "name": "cfgend",
++      "type": "bool"
++    },
++    {
++      "name": "pmu",
++      "type": "bool"
++    },
++    {
++      "name": "unnamed-gpio-out[1]",
++      "type": "link<irq>"
++    },
++    {
++      "name": "sve1920",
++      "type": "bool"
++    },
++    {
++      "name": "reset-hivecs",
++      "type": "bool"
++    },
++    {
++      "name": "sve768",
++      "type": "bool"
++    }
++  ],
++  "id": "libvirt-32"
++}
++
++{
++  "execute": "query-machines",
++  "id": "libvirt-33"
++}
++
++{
++  "return": [
++    {
++      "hotpluggable-cpus": false,
++      "name": "integratorcp",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "nuri",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an511",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an505",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "verdex",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-3.0",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "ast2500-evb",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "smdkc210",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "collie",
++      "numa-mem-supported": false,
++      "default-cpu-type": "sa1110-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "xlnx-versal-virt",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "imx25-pdk",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "none",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "spitz",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "musca-b1",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-pbx-a9",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-eb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "versatilepb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-pb-a8",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a8-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "emcraft-sf2",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.9",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "musicpal",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sbsa-ref",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a57-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "z2",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c5-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "akita",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.7",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "kzm",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "swift-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.8",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-eb-mpcore",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm11mpcore-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "musca-a",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mcimx7d-sabre",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sx1",
++      "numa-mem-supported": false,
++      "default-cpu-type": "ti925t-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-4.2",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sx1-v1",
++      "numa-mem-supported": false,
++      "default-cpu-type": "ti925t-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.6",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "cubieboard",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-4.0",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "highbank",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-4.1",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "raspi2",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "raspi3",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "netduino2",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "terrier",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c5-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "n810",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm1136-r2-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mainstone",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c5-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "palmetto-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "tacoma-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sabrelite",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "netduinoplus2",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "midway",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "romulus-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "cheetah",
++      "numa-mem-supported": false,
++      "default-cpu-type": "ti925t-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "tosa",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "borzoi",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "versatileab",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "lm3s6965evb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "n800",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm1136-r2-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.10",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.11",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "connex",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.12",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "microbit",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "witherspoon-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "xilinx-zynq-a9",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an385",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "ast2600-evb",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "vexpress-a9",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an521",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mcimx6ul-evk",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "vexpress-a15",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "xlnx-zcu102",
++      "numa-mem-supported": false,
++      "cpu-max": 6,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-5.0",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false,
++      "alias": "virt"
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-3.1",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "canon-a1100",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "lm3s811evb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    }
++  ],
++  "id": "libvirt-33"
++}
++
++{
++  "execute": "qom-list-properties",
++  "arguments": {
++    "typename": "virt-5.0-machine"
++  },
++  "id": "libvirt-34"
++}
++
++{
++  "return": [
++    {
++      "name": "type",
++      "type": "string"
++    },
++    {
++      "name": "graphics",
++      "description": "Set on/off to enable/disable graphics emulation",
++      "type": "bool"
++    },
++    {
++      "name": "phandle-start",
++      "description": "The first phandle ID we may generate dynamically",
++      "type": "int"
++    },
++    {
++      "name": "dump-guest-core",
++      "description": "Include guest memory in a core dump",
++      "type": "bool"
++    },
++    {
++      "name": "append",
++      "description": "Linux kernel command line",
++      "type": "string"
++    },
++    {
++      "name": "dumpdtb",
++      "description": "Dump current dtb to a file and quit",
++      "type": "string"
++    },
++    {
++      "name": "memory-encryption",
++      "description": "Set memory encryption object to use",
++      "type": "string"
++    },
++    {
++      "name": "dt-compatible",
++      "description": "Overrides the \"compatible\" property of the dt root node",
++      "type": "string"
++    },
++    {
++      "name": "kernel",
++      "description": "Linux kernel image file",
++      "type": "string"
++    },
++    {
++      "name": "usb",
++      "description": "Set on/off to enable/disable usb",
++      "type": "bool"
++    },
++    {
++      "name": "suppress-vmdesc",
++      "description": "Set on to disable self-describing migration",
++      "type": "bool"
++    },
++    {
++      "name": "dtb",
++      "description": "Linux kernel device tree file",
++      "type": "string"
++    },
++    {
++      "name": "firmware",
++      "description": "Firmware image",
++      "type": "string"
++    },
++    {
++      "name": "mem-merge",
++      "description": "Enable/disable memory merge support",
++      "type": "bool"
++    },
++    {
++      "name": "initrd",
++      "description": "Linux initial ramdisk file",
++      "type": "string"
++    },
++    {
++      "name": "enforce-config-section",
++      "description": "Set on to enforce configuration section migration",
++      "type": "bool"
++    },
++    {
++      "name": "iommu",
++      "description": "Set the IOMMU type. Valid values are none and smmuv3",
++      "type": "string"
++    },
++    {
++      "name": "virt.flash0",
++      "type": "child<cfi.pflash01>"
++    },
++    {
++      "name": "highmem",
++      "description": "Set on/off to enable/disable using physical address space above 32 bits",
++      "type": "bool"
++    },
++    {
++      "name": "pflash1",
++      "description": "Node name or ID of a block device to use as a backend",
++      "type": "str"
++    },
++    {
++      "name": "pflash0",
++      "description": "Node name or ID of a block device to use as a backend",
++      "type": "str"
++    },
++    {
++      "name": "gic-version",
++      "description": "Set GIC version. Valid values are 2, 3 and host",
++      "type": "string"
++    },
++    {
++      "name": "its",
++      "description": "Set on/off to enable/disable ITS instantiation",
++      "type": "bool"
++    },
++    {
++      "name": "secure",
++      "description": "Set on/off to enable/disable the ARM Security Extensions (TrustZone)",
++      "type": "bool"
++    },
++    {
++      "name": "virtualization",
++      "description": "Set on/off to enable/disable emulating a guest CPU which implements the ARM Virtualization Extensions",
++      "type": "bool"
++    },
++    {
++      "name": "hmat",
++      "description": "Set on/off to enable/disable ACPI Heterogeneous Memory Attribute Table (HMAT)",
++      "type": "bool"
++    },
++    {
++      "name": "virt.flash1",
++      "type": "child<cfi.pflash01>"
++    }
++  ],
++  "id": "libvirt-34"
++}
++
++{
++  "execute": "query-cpu-definitions",
++  "id": "libvirt-35"
++}
++
++{
++  "return": [
++    {
++      "name": "pxa262",
++      "typename": "pxa262-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-a0",
++      "typename": "pxa270-a0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1136",
++      "typename": "arm1136-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a15",
++      "typename": "cortex-a15-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa260",
++      "typename": "pxa260-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1136-r2",
++      "typename": "arm1136-r2-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa261",
++      "typename": "pxa261-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa255",
++      "typename": "pxa255-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a72",
++      "typename": "cortex-a72-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m33",
++      "typename": "cortex-m33-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm926",
++      "typename": "arm926-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-r5f",
++      "typename": "cortex-r5f-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm11mpcore",
++      "typename": "arm11mpcore-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa250",
++      "typename": "pxa250-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "ti925t",
++      "typename": "ti925t-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a57",
++      "typename": "cortex-a57-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "sa1110",
++      "typename": "sa1110-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "host",
++      "typename": "host-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1176",
++      "typename": "arm1176-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a53",
++      "typename": "cortex-a53-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "sa1100",
++      "typename": "sa1100-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-c5",
++      "typename": "pxa270-c5-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a9",
++      "typename": "cortex-a9-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m7",
++      "typename": "cortex-m7-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a8",
++      "typename": "cortex-a8-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a7",
++      "typename": "cortex-a7-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-c0",
++      "typename": "pxa270-c0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1026",
++      "typename": "arm1026-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-b1",
++      "typename": "pxa270-b1-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m3",
++      "typename": "cortex-m3-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "max",
++      "typename": "max-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m4",
++      "typename": "cortex-m4-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-b0",
++      "typename": "pxa270-b0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm946",
++      "typename": "arm946-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m0",
++      "typename": "cortex-m0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-r5",
++      "typename": "cortex-r5-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-a1",
++      "typename": "pxa270-a1-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270",
++      "typename": "pxa270-arm-cpu",
++      "static": false
++    }
++  ],
++  "id": "libvirt-35"
++}
++
++{
++  "execute": "query-tpm-models",
++  "id": "libvirt-36"
++}
++
++{
++  "return": [
++  ],
++  "id": "libvirt-36"
++}
++
++{
++  "execute": "query-tpm-types",
++  "id": "libvirt-37"
++}
++
++{
++  "return": [
++  ],
++  "id": "libvirt-37"
++}
++
++{
++  "execute": "query-command-line-options",
++  "id": "libvirt-38"
++}
++
++{
++  "return": [
++    {
++      "parameters": [
++        {
++          "name": "timeout",
++          "help": "Request timeout in seconds (default 0 = no timeout)",
++          "type": "number"
++        },
++        {
++          "name": "initiator-name",
++          "help": "Initiator iqn name to use when connecting",
++          "type": "string"
++        },
++        {
++          "name": "header-digest",
++          "help": "HeaderDigest setting. {CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}",
++          "type": "string"
++        },
++        {
++          "name": "password-secret",
++          "help": "ID of the secret providing password for CHAP authentication to target",
++          "type": "string"
++        },
++        {
++          "name": "password",
++          "help": "password for CHAP authentication to target",
++          "type": "string"
++        },
++        {
++          "name": "user",
++          "help": "username for CHAP authentication to target",
++          "type": "string"
++        }
++      ],
++      "option": "iscsi"
++    },
++    {
++      "parameters": [
++        {
++          "name": "audiodev",
++          "type": "string"
++        },
++        {
++          "name": "non-adaptive",
++          "type": "boolean"
++        },
++        {
++          "name": "lossy",
++          "type": "boolean"
++        },
++        {
++          "name": "sasl-authz",
++          "type": "string"
++        },
++        {
++          "name": "tls-authz",
++          "type": "string"
++        },
++        {
++          "name": "acl",
++          "type": "boolean"
++        },
++        {
++          "name": "sasl",
++          "type": "boolean"
++        },
++        {
++          "name": "key-delay-ms",
++          "type": "number"
++        },
++        {
++          "name": "lock-key-sync",
++          "type": "boolean"
++        },
++        {
++          "name": "reverse",
++          "type": "boolean"
++        },
++        {
++          "name": "password",
++          "type": "boolean"
++        },
++        {
++          "name": "ipv6",
++          "type": "boolean"
++        },
++        {
++          "name": "ipv4",
++          "type": "boolean"
++        },
++        {
++          "name": "to",
++          "type": "number"
++        },
++        {
++          "name": "connections",
++          "type": "number"
++        },
++        {
++          "name": "head",
++          "type": "number"
++        },
++        {
++          "name": "display",
++          "type": "string"
++        },
++        {
++          "name": "share",
++          "type": "string"
++        },
++        {
++          "name": "tls-creds",
++          "type": "string"
++        },
++        {
++          "name": "websocket",
++          "type": "string"
++        },
++        {
++          "name": "vnc",
++          "type": "string"
++        }
++      ],
++      "option": "vnc"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "smbios"
++    },
++    {
++      "parameters": [
++        {
++          "name": "dmode",
++          "type": "number"
++        },
++        {
++          "name": "fmode",
++          "type": "number"
++        },
++        {
++          "name": "sock_fd",
++          "type": "number"
++        },
++        {
++          "name": "socket",
++          "type": "string"
++        },
++        {
++          "name": "multidevs",
++          "type": "string"
++        },
++        {
++          "name": "readonly",
++          "type": "boolean"
++        },
++        {
++          "name": "writeout",
++          "type": "string"
++        },
++        {
++          "name": "security_model",
++          "type": "string"
++        },
++        {
++          "name": "mount_tag",
++          "type": "string"
++        },
++        {
++          "name": "path",
++          "type": "string"
++        },
++        {
++          "name": "fsdriver",
++          "type": "string"
++        }
++      ],
++      "option": "virtfs"
++    },
++    {
++      "parameters": [
++        {
++          "name": "throttling.iops-size",
++          "help": "when limiting by iops max size of an I/O in bytes",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-write-max-length",
++          "help": "length of the bps-write-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-read-max-length",
++          "help": "length of the bps-read-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-total-max-length",
++          "help": "length of the bps-total-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-write-max-length",
++          "help": "length of the iops-write-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-read-max-length",
++          "help": "length of the iops-read-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-total-max-length",
++          "help": "length of the iops-total-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-write-max",
++          "help": "total bytes write burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-read-max",
++          "help": "total bytes read burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-total-max",
++          "help": "total bytes burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-write-max",
++          "help": "I/O operations write burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-read-max",
++          "help": "I/O operations read burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-total-max",
++          "help": "I/O operations burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-write",
++          "help": "limit write bytes per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-read",
++          "help": "limit read bytes per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-total",
++          "help": "limit total bytes per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-write",
++          "help": "limit write operations per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-read",
++          "help": "limit read operations per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-total",
++          "help": "limit total I/O operations per second",
++          "type": "number"
++        },
++        {
++          "name": "dmode",
++          "type": "number"
++        },
++        {
++          "name": "fmode",
++          "type": "number"
++        },
++        {
++          "name": "sock_fd",
++          "type": "number"
++        },
++        {
++          "name": "socket",
++          "type": "string"
++        },
++        {
++          "name": "multidevs",
++          "type": "string"
++        },
++        {
++          "name": "readonly",
++          "type": "boolean"
++        },
++        {
++          "name": "writeout",
++          "type": "string"
++        },
++        {
++          "name": "security_model",
++          "type": "string"
++        },
++        {
++          "name": "path",
++          "type": "string"
++        },
++        {
++          "name": "fsdriver",
++          "type": "string"
++        }
++      ],
++      "option": "fsdev"
++    },
++    {
++      "parameters": [
++        {
++          "name": "resourcecontrol",
++          "type": "string"
++        },
++        {
++          "name": "spawn",
++          "type": "string"
++        },
++        {
++          "name": "elevateprivileges",
++          "type": "string"
++        },
++        {
++          "name": "obsolete",
++          "type": "string"
++        },
++        {
++          "name": "enable",
++          "type": "boolean"
++        }
++      ],
++      "option": "sandbox"
++    },
++    {
++      "parameters": [
++        {
++          "name": "string",
++          "help": "Sets content of the blob to be inserted from a string",
++          "type": "string"
++        },
++        {
++          "name": "file",
++          "help": "Sets the name of the file from which the fw_cfg blob will be loaded",
++          "type": "string"
++        },
++        {
++          "name": "name",
++          "help": "Sets the fw_cfg name of the blob to be inserted",
++          "type": "string"
++        }
++      ],
++      "option": "fw_cfg"
++    },
++    {
++      "parameters": [
++        {
++          "name": "arg",
++          "type": "string"
++        },
++        {
++          "name": "chardev",
++          "type": "string"
++        },
++        {
++          "name": "target",
++          "type": "string"
++        },
++        {
++          "name": "enable",
++          "type": "boolean"
++        }
++      ],
++      "option": "semihosting-config"
++    },
++    {
++      "parameters": [
++        {
++          "name": "rrsnapshot",
++          "type": "string"
++        },
++        {
++          "name": "rrfile",
++          "type": "string"
++        },
++        {
++          "name": "rr",
++          "type": "string"
++        },
++        {
++          "name": "sleep",
++          "type": "boolean"
++        },
++        {
++          "name": "align",
++          "type": "boolean"
++        },
++        {
++          "name": "shift",
++          "type": "string"
++        }
++      ],
++      "option": "icount"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "numa"
++    },
++    {
++      "parameters": [
++        {
++          "name": "debug-threads",
++          "help": "When enabled, name the individual threads; defaults off.\nNOTE: The thread names are for debugging and not a\nstable API.",
++          "type": "boolean"
++        },
++        {
++          "name": "process",
++          "help": "Sets the name of the QEMU process, as shown in top etc",
++          "type": "string"
++        },
++        {
++          "name": "guest",
++          "help": "Sets the name of the guest.\nThis name will be displayed in the SDL window caption.\nThe name will also be used for the VNC server",
++          "type": "string"
++        }
++      ],
++      "option": "name"
++    },
++    {
++      "parameters": [
++        {
++          "name": "timestamp",
++          "type": "boolean"
++        }
++      ],
++      "option": "msg"
++    },
++    {
++      "parameters": [
++        {
++          "name": "cpu-pm",
++          "type": "boolean"
++        },
++        {
++          "name": "mem-lock",
++          "type": "boolean"
++        }
++      ],
++      "option": "overcommit"
++    },
++    {
++      "parameters": [
++        {
++          "name": "mlock",
++          "type": "boolean"
++        }
++      ],
++      "option": "realtime"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "tpmdev"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "object"
++    },
++    {
++      "parameters": [
++        {
++          "name": "opaque",
++          "help": "free-form string used to describe fd",
++          "type": "string"
++        },
++        {
++          "name": "set",
++          "help": "ID of the fd set to add fd to",
++          "type": "number"
++        },
++        {
++          "name": "fd",
++          "help": "file descriptor of which a duplicate is added to fd set",
++          "type": "number"
++        }
++      ],
++      "option": "add-fd"
++    },
++    {
++      "parameters": [
++        {
++          "name": "strict",
++          "type": "boolean"
++        },
++        {
++          "name": "reboot-timeout",
++          "type": "number"
++        },
++        {
++          "name": "splash-time",
++          "type": "number"
++        },
++        {
++          "name": "splash",
++          "type": "string"
++        },
++        {
++          "name": "menu",
++          "type": "boolean"
++        },
++        {
++          "name": "once",
++          "type": "string"
++        },
++        {
++          "name": "order",
++          "type": "string"
++        }
++      ],
++      "option": "boot-opts"
++    },
++    {
++      "parameters": [
++        {
++          "name": "maxcpus",
++          "type": "number"
++        },
++        {
++          "name": "threads",
++          "type": "number"
++        },
++        {
++          "name": "cores",
++          "type": "number"
++        },
++        {
++          "name": "dies",
++          "type": "number"
++        },
++        {
++          "name": "sockets",
++          "type": "number"
++        },
++        {
++          "name": "cpus",
++          "type": "number"
++        }
++      ],
++      "option": "smp-opts"
++    },
++    {
++      "parameters": [
++        {
++          "name": "maxmem",
++          "type": "size"
++        },
++        {
++          "name": "slots",
++          "type": "number"
++        },
++        {
++          "name": "size",
++          "type": "size"
++        }
++      ],
++      "option": "memory"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "accel"
++    },
++    {
++      "parameters": [
++        {
++          "name": "loadparm",
++          "help": "Up to 8 chars in set of [A-Za-z0-9. ](lower case chars converted to upper case) to pass to machine loader, boot manager, and guest kernel",
++          "type": "string"
++        },
++        {
++          "name": "dea-key-wrap",
++          "help": "enable/disable DEA key wrapping using the CPACF wrapping key",
++          "type": "boolean"
++        },
++        {
++          "name": "aes-key-wrap",
++          "help": "enable/disable AES key wrapping using the CPACF wrapping key",
++          "type": "boolean"
++        },
++        {
++          "name": "suppress-vmdesc",
++          "help": "Set on to disable self-describing migration",
++          "type": "boolean"
++        },
++        {
++          "name": "iommu",
++          "help": "Set on/off to enable/disable Intel IOMMU (VT-d)",
++          "type": "boolean"
++        },
++        {
++          "name": "firmware",
++          "help": "firmware image",
++          "type": "string"
++        },
++        {
++          "name": "usb",
++          "help": "Set on/off to enable/disable usb",
++          "type": "boolean"
++        },
++        {
++          "name": "mem-merge",
++          "help": "enable/disable memory merge support",
++          "type": "boolean"
++        },
++        {
++          "name": "dump-guest-core",
++          "help": "Include guest memory in  a core dump",
++          "type": "boolean"
++        },
++        {
++          "name": "dt_compatible",
++          "help": "Overrides the \"compatible\" property of the dt root node",
++          "type": "string"
++        },
++        {
++          "name": "phandle_start",
++          "help": "The first phandle ID we may generate dynamically",
++          "type": "number"
++        },
++        {
++          "name": "dumpdtb",
++          "help": "Dump current dtb to a file and quit",
++          "type": "string"
++        },
++        {
++          "name": "dtb",
++          "help": "Linux kernel device tree file",
++          "type": "string"
++        },
++        {
++          "name": "append",
++          "help": "Linux kernel command line",
++          "type": "string"
++        },
++        {
++          "name": "initrd",
++          "help": "Linux initial ramdisk file",
++          "type": "string"
++        },
++        {
++          "name": "kernel",
++          "help": "Linux kernel image file",
++          "type": "string"
++        },
++        {
++          "name": "kvm_shadow_mem",
++          "help": "KVM shadow MMU size",
++          "type": "size"
++        },
++        {
++          "name": "kernel_irqchip",
++          "help": "use KVM in-kernel irqchip",
++          "type": "boolean"
++        },
++        {
++          "name": "accel",
++          "help": "accelerator list",
++          "type": "string"
++        },
++        {
++          "name": "type",
++          "help": "emulated machine",
++          "type": "string"
++        }
++      ],
++      "option": "machine"
++    },
++    {
++      "parameters": [
++        {
++          "name": "romfile",
++          "type": "string"
++        },
++        {
++          "name": "bootindex",
++          "type": "number"
++        }
++      ],
++      "option": "option-rom"
++    },
++    {
++      "parameters": [
++        {
++          "name": "file",
++          "type": "string"
++        },
++        {
++          "name": "events",
++          "type": "string"
++        },
++        {
++          "name": "enable",
++          "type": "string"
++        }
++      ],
++      "option": "trace"
++    },
++    {
++      "parameters": [
++        {
++          "name": "pretty",
++          "type": "boolean"
++        },
++        {
++          "name": "chardev",
++          "type": "string"
++        },
++        {
++          "name": "mode",
++          "type": "string"
++        }
++      ],
++      "option": "mon"
++    },
++    {
++      "parameters": [
++        {
++          "name": "value",
++          "type": "string"
++        },
++        {
++          "name": "property",
++          "type": "string"
++        },
++        {
++          "name": "driver",
++          "type": "string"
++        }
++      ],
++      "option": "global"
++    },
++    {
++      "parameters": [
++        {
++          "name": "driftfix",
++          "type": "string"
++        },
++        {
++          "name": "clock",
++          "type": "string"
++        },
++        {
++          "name": "base",
++          "type": "string"
++        }
++      ],
++      "option": "rtc"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "net"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "nic"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "netdev"
++    },
++    {
++      "parameters": [
++      ],
++      "option": "device"
++    },
++    {
++      "parameters": [
++        {
++          "name": "logappend",
++          "type": "boolean"
++        },
++        {
++          "name": "logfile",
++          "type": "string"
++        },
++        {
++          "name": "append",
++          "type": "boolean"
++        },
++        {
++          "name": "chardev",
++          "type": "string"
++        },
++        {
++          "name": "size",
++          "type": "size"
++        },
++        {
++          "name": "debug",
++          "type": "number"
++        },
++        {
++          "name": "name",
++          "type": "string"
++        },
++        {
++          "name": "signal",
++          "type": "boolean"
++        },
++        {
++          "name": "mux",
++          "type": "boolean"
++        },
++        {
++          "name": "rows",
++          "type": "number"
++        },
++        {
++          "name": "cols",
++          "type": "number"
++        },
++        {
++          "name": "height",
++          "type": "number"
++        },
++        {
++          "name": "width",
++          "type": "number"
++        },
++        {
++          "name": "websocket",
++          "type": "boolean"
++        },
++        {
++          "name": "tls-authz",
++          "type": "string"
++        },
++        {
++          "name": "tls-creds",
++          "type": "string"
++        },
++        {
++          "name": "tn3270",
++          "type": "boolean"
++        },
++        {
++          "name": "telnet",
++          "type": "boolean"
++        },
++        {
++          "name": "reconnect",
++          "type": "number"
++        },
++        {
++          "name": "delay",
++          "type": "boolean"
++        },
++        {
++          "name": "server",
++          "type": "boolean"
++        },
++        {
++          "name": "wait",
++          "type": "boolean"
++        },
++        {
++          "name": "ipv6",
++          "type": "boolean"
++        },
++        {
++          "name": "ipv4",
++          "type": "boolean"
++        },
++        {
++          "name": "to",
++          "type": "number"
++        },
++        {
++          "name": "localport",
++          "type": "string"
++        },
++        {
++          "name": "localaddr",
++          "type": "string"
++        },
++        {
++          "name": "fd",
++          "type": "string"
++        },
++        {
++          "name": "port",
++          "type": "string"
++        },
++        {
++          "name": "host",
++          "type": "string"
++        },
++        {
++          "name": "path",
++          "type": "string"
++        },
++        {
++          "name": "backend",
++          "type": "string"
++        }
++      ],
++      "option": "chardev"
++    },
++    {
++      "parameters": [
++        {
++          "name": "copy-on-read",
++          "help": "copy read data from backing file into image file",
++          "type": "boolean"
++        },
++        {
++          "name": "werror",
++          "help": "write error action",
++          "type": "string"
++        },
++        {
++          "name": "rerror",
++          "help": "read error action",
++          "type": "string"
++        },
++        {
++          "name": "read-only",
++          "help": "open drive file as read-only",
++          "type": "boolean"
++        },
++        {
++          "name": "file",
++          "help": "file name",
++          "type": "string"
++        },
++        {
++          "name": "if",
++          "help": "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
++          "type": "string"
++        },
++        {
++          "name": "media",
++          "help": "media type (disk, cdrom)",
++          "type": "string"
++        },
++        {
++          "name": "index",
++          "help": "index number",
++          "type": "number"
++        },
++        {
++          "name": "unit",
++          "help": "unit number (i.e. lun for scsi)",
++          "type": "number"
++        },
++        {
++          "name": "bus",
++          "help": "bus number",
++          "type": "number"
++        },
++        {
++          "name": "stats-account-failed",
++          "help": "whether to account for failed I/O operations in the statistics",
++          "type": "boolean"
++        },
++        {
++          "name": "stats-account-invalid",
++          "help": "whether to account for invalid I/O operations in the statistics",
++          "type": "boolean"
++        },
++        {
++          "name": "detect-zeroes",
++          "help": "try to optimize zero writes (off, on, unmap)",
++          "type": "string"
++        },
++        {
++          "name": "throttling.group",
++          "help": "name of the block throttling group",
++          "type": "string"
++        },
++        {
++          "name": "throttling.iops-size",
++          "help": "when limiting by iops max size of an I/O in bytes",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-write-max-length",
++          "help": "length of the bps-write-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-read-max-length",
++          "help": "length of the bps-read-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-total-max-length",
++          "help": "length of the bps-total-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-write-max-length",
++          "help": "length of the iops-write-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-read-max-length",
++          "help": "length of the iops-read-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-total-max-length",
++          "help": "length of the iops-total-max burst period, in seconds",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-write-max",
++          "help": "total bytes write burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-read-max",
++          "help": "total bytes read burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-total-max",
++          "help": "total bytes burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-write-max",
++          "help": "I/O operations write burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-read-max",
++          "help": "I/O operations read burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-total-max",
++          "help": "I/O operations burst",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-write",
++          "help": "limit write bytes per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-read",
++          "help": "limit read bytes per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.bps-total",
++          "help": "limit total bytes per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-write",
++          "help": "limit write operations per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-read",
++          "help": "limit read operations per second",
++          "type": "number"
++        },
++        {
++          "name": "throttling.iops-total",
++          "help": "limit total I/O operations per second",
++          "type": "number"
++        },
++        {
++          "name": "werror",
++          "help": "write error action",
++          "type": "string"
++        },
++        {
++          "name": "format",
++          "help": "disk format (raw, qcow2, ...)",
++          "type": "string"
++        },
++        {
++          "name": "cache.writeback",
++          "help": "Enable writeback mode",
++          "type": "boolean"
++        },
++        {
++          "name": "aio",
++          "help": "host AIO implementation (threads, native, io_uring)",
++          "type": "string"
++        },
++        {
++          "name": "snapshot",
++          "help": "enable/disable snapshot mode",
++          "type": "boolean"
++        },
++        {
++          "name": "force-share",
++          "help": "always accept other writers (default: off)",
++          "type": "boolean"
++        },
++        {
++          "name": "discard",
++          "help": "discard operation (ignore/off, unmap/on)",
++          "type": "string"
++        },
++        {
++          "name": "auto-read-only",
++          "help": "Node can become read-only if opening read-write fails",
++          "type": "boolean"
++        },
++        {
++          "name": "cache.no-flush",
++          "help": "Ignore flush requests",
++          "type": "boolean"
++        },
++        {
++          "name": "cache.direct",
++          "help": "Bypass software writeback cache on the host",
++          "type": "boolean"
++        },
++        {
++          "name": "driver",
++          "help": "Block driver to use for the node",
++          "type": "string"
++        },
++        {
++          "name": "node-name",
++          "help": "Node name of the block device node",
++          "type": "string"
++        }
++      ],
++      "option": "drive"
++    }
++  ],
++  "id": "libvirt-38"
++}
++
++{
++  "execute": "query-migrate-capabilities",
++  "id": "libvirt-39"
++}
++
++{
++  "return": [
++    {
++      "state": false,
++      "capability": "xbzrle"
++    },
++    {
++      "state": false,
++      "capability": "rdma-pin-all"
++    },
++    {
++      "state": false,
++      "capability": "auto-converge"
++    },
++    {
++      "state": false,
++      "capability": "zero-blocks"
++    },
++    {
++      "state": false,
++      "capability": "compress"
++    },
++    {
++      "state": false,
++      "capability": "events"
++    },
++    {
++      "state": false,
++      "capability": "postcopy-ram"
++    },
++    {
++      "state": false,
++      "capability": "x-colo"
++    },
++    {
++      "state": false,
++      "capability": "release-ram"
++    },
++    {
++      "state": false,
++      "capability": "block"
++    },
++    {
++      "state": false,
++      "capability": "return-path"
++    },
++    {
++      "state": false,
++      "capability": "pause-before-switchover"
++    },
++    {
++      "state": false,
++      "capability": "multifd"
++    },
++    {
++      "state": false,
++      "capability": "dirty-bitmaps"
++    },
++    {
++      "state": false,
++      "capability": "postcopy-blocktime"
++    },
++    {
++      "state": false,
++      "capability": "late-block-activate"
++    },
++    {
++      "state": false,
++      "capability": "x-ignore-shared"
++    },
++    {
++      "state": false,
++      "capability": "validate-uuid"
++    }
++  ],
++  "id": "libvirt-39"
++}
++
++{
++  "execute": "query-qmp-schema",
++  "id": "libvirt-40"
++}
++
++{
++  "return": [
++    {
++      "name": "query-status",
++      "ret-type": "1",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "SHUTDOWN",
++      "meta-type": "event",
++      "arg-type": "2"
++    },
++    {
++      "name": "POWERDOWN",
++      "meta-type": "event",
++      "arg-type": "0"
++    },
++    {
++      "name": "RESET",
++      "meta-type": "event",
++      "arg-type": "3"
++    },
++    {
++      "name": "STOP",
++      "meta-type": "event",
++      "arg-type": "0"
++    },
++    {
++      "name": "RESUME",
++      "meta-type": "event",
++      "arg-type": "0"
++    },
++    {
++      "name": "SUSPEND",
++      "meta-type": "event",
++      "arg-type": "0"
++    },
++    {
++      "name": "SUSPEND_DISK",
++      "meta-type": "event",
++      "arg-type": "0"
++    },
++    {
++      "name": "WAKEUP",
++      "meta-type": "event",
++      "arg-type": "0"
++    },
++    {
++      "name": "WATCHDOG",
++      "meta-type": "event",
++      "arg-type": "4"
++    },
++    {
++      "name": "watchdog-set-action",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "5"
++    },
++    {
++      "name": "GUEST_PANICKED",
++      "meta-type": "event",
++      "arg-type": "6"
++    },
++    {
++      "name": "GUEST_CRASHLOADED",
++      "meta-type": "event",
++      "arg-type": "7"
++    },
++    {
++      "name": "query-pr-managers",
++      "ret-type": "[8]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "blockdev-snapshot-internal-sync",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "9"
++    },
++    {
++      "name": "blockdev-snapshot-delete-internal-sync",
++      "ret-type": "11",
++      "meta-type": "command",
++      "arg-type": "10"
++    },
++    {
++      "name": "eject",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "12"
++    },
++    {
++      "name": "nbd-server-start",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "13"
++    },
++    {
++      "name": "nbd-server-add",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "14"
++    },
++    {
++      "name": "nbd-server-remove",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "15"
++    },
++    {
++      "name": "nbd-server-stop",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "DEVICE_TRAY_MOVED",
++      "meta-type": "event",
++      "arg-type": "16"
++    },
++    {
++      "name": "PR_MANAGER_STATUS_CHANGED",
++      "meta-type": "event",
++      "arg-type": "17"
++    },
++    {
++      "name": "QUORUM_FAILURE",
++      "meta-type": "event",
++      "arg-type": "18"
++    },
++    {
++      "name": "QUORUM_REPORT_BAD",
++      "meta-type": "event",
++      "arg-type": "19"
++    },
++    {
++      "name": "block-latency-histogram-set",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "20"
++    },
++    {
++      "name": "query-block",
++      "ret-type": "[21]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-blockstats",
++      "ret-type": "[23]",
++      "meta-type": "command",
++      "arg-type": "22"
++    },
++    {
++      "name": "query-block-jobs",
++      "ret-type": "[24]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "block_passwd",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "25"
++    },
++    {
++      "name": "block_resize",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "26"
++    },
++    {
++      "name": "blockdev-snapshot-sync",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "27"
++    },
++    {
++      "name": "blockdev-snapshot",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "28"
++    },
++    {
++      "name": "change-backing-file",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "29"
++    },
++    {
++      "name": "block-commit",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "30"
++    },
++    {
++      "name": "drive-backup",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "31"
++    },
++    {
++      "name": "blockdev-backup",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "32"
++    },
++    {
++      "name": "query-named-block-nodes",
++      "ret-type": "[33]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "x-debug-query-block-graph",
++      "ret-type": "34",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "drive-mirror",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "35"
++    },
++    {
++      "name": "block-dirty-bitmap-add",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "36"
++    },
++    {
++      "name": "block-dirty-bitmap-remove",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "37"
++    },
++    {
++      "name": "block-dirty-bitmap-clear",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "37"
++    },
++    {
++      "name": "block-dirty-bitmap-enable",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "37"
++    },
++    {
++      "name": "block-dirty-bitmap-disable",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "37"
++    },
++    {
++      "name": "block-dirty-bitmap-merge",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "38"
++    },
++    {
++      "name": "x-debug-block-dirty-bitmap-sha256",
++      "ret-type": "39",
++      "meta-type": "command",
++      "arg-type": "37"
++    },
++    {
++      "name": "blockdev-mirror",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "40"
++    },
++    {
++      "name": "block_set_io_throttle",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "41"
++    },
++    {
++      "name": "block-stream",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "42"
++    },
++    {
++      "name": "block-job-set-speed",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "43"
++    },
++    {
++      "name": "block-job-cancel",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "44"
++    },
++    {
++      "name": "block-job-pause",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "45"
++    },
++    {
++      "name": "block-job-resume",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "46"
++    },
++    {
++      "name": "block-job-complete",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "47"
++    },
++    {
++      "name": "block-job-dismiss",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "48"
++    },
++    {
++      "name": "block-job-finalize",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "49"
++    },
++    {
++      "name": "blockdev-add",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "50"
++    },
++    {
++      "name": "x-blockdev-reopen",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "50"
++    },
++    {
++      "name": "blockdev-del",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "51"
++    },
++    {
++      "name": "blockdev-create",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "52"
++    },
++    {
++      "name": "blockdev-open-tray",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "53"
++    },
++    {
++      "name": "blockdev-close-tray",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "54"
++    },
++    {
++      "name": "blockdev-remove-medium",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "55"
++    },
++    {
++      "name": "blockdev-insert-medium",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "56"
++    },
++    {
++      "name": "blockdev-change-medium",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "57"
++    },
++    {
++      "name": "BLOCK_IMAGE_CORRUPTED",
++      "meta-type": "event",
++      "arg-type": "58"
++    },
++    {
++      "name": "BLOCK_IO_ERROR",
++      "meta-type": "event",
++      "arg-type": "59"
++    },
++    {
++      "name": "BLOCK_JOB_COMPLETED",
++      "meta-type": "event",
++      "arg-type": "60"
++    },
++    {
++      "name": "BLOCK_JOB_CANCELLED",
++      "meta-type": "event",
++      "arg-type": "61"
++    },
++    {
++      "name": "BLOCK_JOB_ERROR",
++      "meta-type": "event",
++      "arg-type": "62"
++    },
++    {
++      "name": "BLOCK_JOB_READY",
++      "meta-type": "event",
++      "arg-type": "63"
++    },
++    {
++      "name": "BLOCK_JOB_PENDING",
++      "meta-type": "event",
++      "arg-type": "64"
++    },
++    {
++      "name": "BLOCK_WRITE_THRESHOLD",
++      "meta-type": "event",
++      "arg-type": "65"
++    },
++    {
++      "name": "block-set-write-threshold",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "66"
++    },
++    {
++      "name": "x-blockdev-change",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "67"
++    },
++    {
++      "name": "x-blockdev-set-iothread",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "68"
++    },
++    {
++      "name": "JOB_STATUS_CHANGE",
++      "meta-type": "event",
++      "arg-type": "69"
++    },
++    {
++      "name": "job-pause",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "70"
++    },
++    {
++      "name": "job-resume",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "71"
++    },
++    {
++      "name": "job-cancel",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "72"
++    },
++    {
++      "name": "job-complete",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "73"
++    },
++    {
++      "name": "job-dismiss",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "74"
++    },
++    {
++      "name": "job-finalize",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "75"
++    },
++    {
++      "name": "query-jobs",
++      "ret-type": "[76]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-chardev",
++      "ret-type": "[77]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-chardev-backends",
++      "ret-type": "[78]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "ringbuf-write",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "79"
++    },
++    {
++      "name": "ringbuf-read",
++      "ret-type": "str",
++      "meta-type": "command",
++      "arg-type": "80"
++    },
++    {
++      "name": "chardev-add",
++      "ret-type": "82",
++      "meta-type": "command",
++      "arg-type": "81"
++    },
++    {
++      "name": "chardev-change",
++      "ret-type": "82",
++      "meta-type": "command",
++      "arg-type": "83"
++    },
++    {
++      "name": "chardev-remove",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "84"
++    },
++    {
++      "name": "chardev-send-break",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "85"
++    },
++    {
++      "name": "VSERPORT_CHANGE",
++      "meta-type": "event",
++      "arg-type": "86"
++    },
++    {
++      "name": "dump-guest-memory",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "87"
++    },
++    {
++      "name": "query-dump",
++      "ret-type": "88",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "DUMP_COMPLETED",
++      "meta-type": "event",
++      "arg-type": "89"
++    },
++    {
++      "name": "query-dump-guest-memory-capability",
++      "ret-type": "90",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "set_link",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "91"
++    },
++    {
++      "name": "netdev_add",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "92"
++    },
++    {
++      "name": "netdev_del",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "93"
++    },
++    {
++      "name": "query-rx-filter",
++      "ret-type": "[95]",
++      "meta-type": "command",
++      "arg-type": "94"
++    },
++    {
++      "name": "NIC_RX_FILTER_CHANGED",
++      "meta-type": "event",
++      "arg-type": "96"
++    },
++    {
++      "name": "announce-self",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "97"
++    },
++    {
++      "name": "FAILOVER_NEGOTIATED",
++      "meta-type": "event",
++      "arg-type": "98"
++    },
++    {
++      "name": "RDMA_GID_STATUS_CHANGED",
++      "meta-type": "event",
++      "arg-type": "99"
++    },
++    {
++      "name": "query-rocker",
++      "ret-type": "101",
++      "meta-type": "command",
++      "arg-type": "100"
++    },
++    {
++      "name": "query-rocker-ports",
++      "ret-type": "[103]",
++      "meta-type": "command",
++      "arg-type": "102"
++    },
++    {
++      "name": "query-rocker-of-dpa-flows",
++      "ret-type": "[105]",
++      "meta-type": "command",
++      "arg-type": "104"
++    },
++    {
++      "name": "query-rocker-of-dpa-groups",
++      "ret-type": "[107]",
++      "meta-type": "command",
++      "arg-type": "106"
++    },
++    {
++      "name": "query-tpm-models",
++      "ret-type": "[108]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-tpm-types",
++      "ret-type": "[109]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-tpm",
++      "ret-type": "[110]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "set_password",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "111"
++    },
++    {
++      "name": "expire_password",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "112"
++    },
++    {
++      "name": "screendump",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "113"
++    },
++    {
++      "name": "query-vnc",
++      "ret-type": "118",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-vnc-servers",
++      "ret-type": "[119]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "change-vnc-password",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "120"
++    },
++    {
++      "name": "VNC_CONNECTED",
++      "meta-type": "event",
++      "arg-type": "121"
++    },
++    {
++      "name": "VNC_INITIALIZED",
++      "meta-type": "event",
++      "arg-type": "122"
++    },
++    {
++      "name": "VNC_DISCONNECTED",
++      "meta-type": "event",
++      "arg-type": "123"
++    },
++    {
++      "name": "query-mice",
++      "ret-type": "[124]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "send-key",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "125"
++    },
++    {
++      "name": "input-send-event",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "126"
++    },
++    {
++      "name": "query-display-options",
++      "ret-type": "127",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-migrate",
++      "ret-type": "128",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "migrate-set-capabilities",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "129"
++    },
++    {
++      "name": "query-migrate-capabilities",
++      "ret-type": "[130]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "migrate-set-parameters",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "131"
++    },
++    {
++      "name": "query-migrate-parameters",
++      "ret-type": "132",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "client_migrate_info",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "133"
++    },
++    {
++      "name": "migrate-start-postcopy",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "MIGRATION",
++      "meta-type": "event",
++      "arg-type": "134"
++    },
++    {
++      "name": "MIGRATION_PASS",
++      "meta-type": "event",
++      "arg-type": "135"
++    },
++    {
++      "name": "COLO_EXIT",
++      "meta-type": "event",
++      "arg-type": "136"
++    },
++    {
++      "name": "x-colo-lost-heartbeat",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "migrate_cancel",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "migrate-continue",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "137"
++    },
++    {
++      "name": "migrate_set_downtime",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "138"
++    },
++    {
++      "name": "migrate_set_speed",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "139"
++    },
++    {
++      "name": "migrate-set-cache-size",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "140"
++    },
++    {
++      "name": "query-migrate-cache-size",
++      "ret-type": "int",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "migrate",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "141"
++    },
++    {
++      "name": "migrate-incoming",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "142"
++    },
++    {
++      "name": "xen-save-devices-state",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "143"
++    },
++    {
++      "name": "xen-set-replication",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "144"
++    },
++    {
++      "name": "query-xen-replication-status",
++      "ret-type": "145",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "xen-colo-do-checkpoint",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-colo-status",
++      "ret-type": "146",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "migrate-recover",
++      "ret-type": "0",
++      "allow-oob": true,
++      "meta-type": "command",
++      "arg-type": "147"
++    },
++    {
++      "name": "migrate-pause",
++      "ret-type": "0",
++      "allow-oob": true,
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "UNPLUG_PRIMARY",
++      "meta-type": "event",
++      "arg-type": "148"
++    },
++    {
++      "name": "transaction",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "149"
++    },
++    {
++      "name": "trace-event-get-state",
++      "ret-type": "[151]",
++      "meta-type": "command",
++      "arg-type": "150"
++    },
++    {
++      "name": "trace-event-set-state",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "152"
++    },
++    {
++      "name": "query-qmp-schema",
++      "ret-type": "[153]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "qom-list",
++      "ret-type": "[155]",
++      "meta-type": "command",
++      "arg-type": "154"
++    },
++    {
++      "name": "qom-get",
++      "ret-type": "any",
++      "meta-type": "command",
++      "arg-type": "156"
++    },
++    {
++      "name": "qom-set",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "157"
++    },
++    {
++      "name": "qom-list-types",
++      "ret-type": "[159]",
++      "meta-type": "command",
++      "arg-type": "158"
++    },
++    {
++      "name": "qom-list-properties",
++      "ret-type": "[155]",
++      "meta-type": "command",
++      "arg-type": "160"
++    },
++    {
++      "name": "object-add",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "161"
++    },
++    {
++      "name": "object-del",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "162"
++    },
++    {
++      "name": "device-list-properties",
++      "ret-type": "[155]",
++      "meta-type": "command",
++      "arg-type": "163"
++    },
++    {
++      "name": "device_add",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "164"
++    },
++    {
++      "name": "device_del",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "165"
++    },
++    {
++      "name": "DEVICE_DELETED",
++      "meta-type": "event",
++      "arg-type": "166"
++    },
++    {
++      "name": "query-cpus",
++      "ret-type": "[167]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-cpus-fast",
++      "ret-type": "[168]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "cpu-add",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "169"
++    },
++    {
++      "name": "query-machines",
++      "ret-type": "[170]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-current-machine",
++      "ret-type": "171",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-target",
++      "ret-type": "172",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-memdev",
++      "ret-type": "[173]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-hotpluggable-cpus",
++      "ret-type": "[174]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "set-numa-node",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "175"
++    },
++    {
++      "name": "query-cpu-model-expansion",
++      "ret-type": "181",
++      "meta-type": "command",
++      "arg-type": "180"
++    },
++    {
++      "name": "query-cpu-definitions",
++      "ret-type": "[182]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "qmp_capabilities",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "183"
++    },
++    {
++      "name": "query-version",
++      "ret-type": "184",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-commands",
++      "ret-type": "[185]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "add_client",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "186"
++    },
++    {
++      "name": "query-name",
++      "ret-type": "187",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-kvm",
++      "ret-type": "188",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-uuid",
++      "ret-type": "189",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-events",
++      "ret-type": "[190]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-iothreads",
++      "ret-type": "[191]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-balloon",
++      "ret-type": "192",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "BALLOON_CHANGE",
++      "meta-type": "event",
++      "arg-type": "193"
++    },
++    {
++      "name": "query-pci",
++      "ret-type": "[194]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "quit",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "stop",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "system_reset",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "system_powerdown",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "memsave",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "195"
++    },
++    {
++      "name": "pmemsave",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "196"
++    },
++    {
++      "name": "cont",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "x-exit-preconfig",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "system_wakeup",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "inject-nmi",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "balloon",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "197"
++    },
++    {
++      "name": "human-monitor-command",
++      "ret-type": "str",
++      "meta-type": "command",
++      "arg-type": "198",
++      "features": [
++        "savevm-monitor-nodes"
++      ]
++    },
++    {
++      "name": "change",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "199"
++    },
++    {
++      "name": "xen-set-global-dirty-log",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "200"
++    },
++    {
++      "name": "getfd",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "201"
++    },
++    {
++      "name": "closefd",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "202"
++    },
++    {
++      "name": "query-memory-size-summary",
++      "ret-type": "203",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "add-fd",
++      "ret-type": "205",
++      "meta-type": "command",
++      "arg-type": "204"
++    },
++    {
++      "name": "remove-fd",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "206"
++    },
++    {
++      "name": "query-fdsets",
++      "ret-type": "[207]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "query-command-line-options",
++      "ret-type": "[209]",
++      "meta-type": "command",
++      "arg-type": "208"
++    },
++    {
++      "name": "query-memory-devices",
++      "ret-type": "[210]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "MEM_UNPLUG_ERROR",
++      "meta-type": "event",
++      "arg-type": "211"
++    },
++    {
++      "name": "query-acpi-ospm-status",
++      "ret-type": "[212]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "ACPI_DEVICE_OST",
++      "meta-type": "event",
++      "arg-type": "213"
++    },
++    {
++      "name": "xen-load-devices-state",
++      "ret-type": "0",
++      "meta-type": "command",
++      "arg-type": "214"
++    },
++    {
++      "name": "query-vm-generation-id",
++      "ret-type": "215",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "RTC_CHANGE",
++      "meta-type": "event",
++      "arg-type": "216"
++    },
++    {
++      "name": "query-gic-capabilities",
++      "ret-type": "[221]",
++      "meta-type": "command",
++      "arg-type": "0"
++    },
++    {
++      "name": "0",
++      "members": [
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "1",
++      "members": [
++        {
++          "name": "running",
++          "type": "bool"
++        },
++        {
++          "name": "singlestep",
++          "type": "bool"
++        },
++        {
++          "name": "status",
++          "type": "222"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "2",
++      "members": [
++        {
++          "name": "guest",
++          "type": "bool"
++        },
++        {
++          "name": "reason",
++          "type": "223"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "3",
++      "members": [
++        {
++          "name": "guest",
++          "type": "bool"
++        },
++        {
++          "name": "reason",
++          "type": "223"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "4",
++      "members": [
++        {
++          "name": "action",
++          "type": "224"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "5",
++      "members": [
++        {
++          "name": "action",
++          "type": "224"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "6",
++      "members": [
++        {
++          "name": "action",
++          "type": "225"
++        },
++        {
++          "name": "info",
++          "default": null,
++          "type": "226"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "7",
++      "members": [
++        {
++          "name": "action",
++          "type": "225"
++        },
++        {
++          "name": "info",
++          "default": null,
++          "type": "226"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[8]",
++      "element-type": "8",
++      "meta-type": "array"
++    },
++    {
++      "name": "8",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "connected",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "9",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "10",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "name",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "11",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "vm-state-size",
++          "type": "int"
++        },
++        {
++          "name": "date-sec",
++          "type": "int"
++        },
++        {
++          "name": "date-nsec",
++          "type": "int"
++        },
++        {
++          "name": "vm-clock-sec",
++          "type": "int"
++        },
++        {
++          "name": "vm-clock-nsec",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "12",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "force",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "13",
++      "members": [
++        {
++          "name": "addr",
++          "type": "227"
++        },
++        {
++          "name": "tls-creds",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "tls-authz",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "14",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "writable",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "bitmap",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "15",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "mode",
++          "default": null,
++          "type": "228"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "16",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "tray-open",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "17",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "connected",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "18",
++      "members": [
++        {
++          "name": "reference",
++          "type": "str"
++        },
++        {
++          "name": "sector-num",
++          "type": "int"
++        },
++        {
++          "name": "sectors-count",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "19",
++      "members": [
++        {
++          "name": "type",
++          "type": "229"
++        },
++        {
++          "name": "error",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "type": "str"
++        },
++        {
++          "name": "sector-num",
++          "type": "int"
++        },
++        {
++          "name": "sectors-count",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "20",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "boundaries",
++          "default": null,
++          "type": "[int]"
++        },
++        {
++          "name": "boundaries-read",
++          "default": null,
++          "type": "[int]"
++        },
++        {
++          "name": "boundaries-write",
++          "default": null,
++          "type": "[int]"
++        },
++        {
++          "name": "boundaries-flush",
++          "default": null,
++          "type": "[int]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[21]",
++      "element-type": "21",
++      "meta-type": "array"
++    },
++    {
++      "name": "21",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "qdev",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "type",
++          "type": "str"
++        },
++        {
++          "name": "removable",
++          "type": "bool"
++        },
++        {
++          "name": "locked",
++          "type": "bool"
++        },
++        {
++          "name": "inserted",
++          "default": null,
++          "type": "33"
++        },
++        {
++          "name": "tray_open",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "io-status",
++          "default": null,
++          "type": "230"
++        },
++        {
++          "name": "dirty-bitmaps",
++          "default": null,
++          "type": "[231]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "22",
++      "members": [
++        {
++          "name": "query-nodes",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[23]",
++      "element-type": "23",
++      "meta-type": "array"
++    },
++    {
++      "name": "23",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "qdev",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "stats",
++          "type": "232"
++        },
++        {
++          "name": "driver-specific",
++          "default": null,
++          "type": "233"
++        },
++        {
++          "name": "parent",
++          "default": null,
++          "type": "23"
++        },
++        {
++          "name": "backing",
++          "default": null,
++          "type": "23"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[24]",
++      "element-type": "24",
++      "meta-type": "array"
++    },
++    {
++      "name": "24",
++      "members": [
++        {
++          "name": "type",
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "len",
++          "type": "int"
++        },
++        {
++          "name": "offset",
++          "type": "int"
++        },
++        {
++          "name": "busy",
++          "type": "bool"
++        },
++        {
++          "name": "paused",
++          "type": "bool"
++        },
++        {
++          "name": "speed",
++          "type": "int"
++        },
++        {
++          "name": "io-status",
++          "type": "230"
++        },
++        {
++          "name": "ready",
++          "type": "bool"
++        },
++        {
++          "name": "status",
++          "type": "234"
++        },
++        {
++          "name": "auto-finalize",
++          "type": "bool"
++        },
++        {
++          "name": "auto-dismiss",
++          "type": "bool"
++        },
++        {
++          "name": "error",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "25",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "password",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "26",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "27",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "snapshot-file",
++          "type": "str"
++        },
++        {
++          "name": "snapshot-node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "format",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "mode",
++          "default": null,
++          "type": "235"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "28",
++      "members": [
++        {
++          "name": "node",
++          "type": "str"
++        },
++        {
++          "name": "overlay",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "29",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "image-node-name",
++          "type": "str"
++        },
++        {
++          "name": "backing-file",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "30",
++      "members": [
++        {
++          "name": "job-id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "base-node",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "base",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "top-node",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "top",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "backing-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "speed",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "filter-node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "auto-finalize",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "auto-dismiss",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "31",
++      "members": [
++        {
++          "name": "job-id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "sync",
++          "type": "236"
++        },
++        {
++          "name": "speed",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bitmap",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "bitmap-mode",
++          "default": null,
++          "type": "237"
++        },
++        {
++          "name": "compress",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "on-source-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "on-target-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "auto-finalize",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "auto-dismiss",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "filter-node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "target",
++          "type": "str"
++        },
++        {
++          "name": "format",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "mode",
++          "default": null,
++          "type": "235"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "32",
++      "members": [
++        {
++          "name": "job-id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "sync",
++          "type": "236"
++        },
++        {
++          "name": "speed",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bitmap",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "bitmap-mode",
++          "default": null,
++          "type": "237"
++        },
++        {
++          "name": "compress",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "on-source-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "on-target-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "auto-finalize",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "auto-dismiss",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "filter-node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "target",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[33]",
++      "element-type": "33",
++      "meta-type": "array"
++    },
++    {
++      "name": "33",
++      "members": [
++        {
++          "name": "file",
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "ro",
++          "type": "bool"
++        },
++        {
++          "name": "drv",
++          "type": "str"
++        },
++        {
++          "name": "backing_file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "backing_file_depth",
++          "type": "int"
++        },
++        {
++          "name": "encrypted",
++          "type": "bool"
++        },
++        {
++          "name": "encryption_key_missing",
++          "type": "bool"
++        },
++        {
++          "name": "detect_zeroes",
++          "type": "239"
++        },
++        {
++          "name": "bps",
++          "type": "int"
++        },
++        {
++          "name": "bps_rd",
++          "type": "int"
++        },
++        {
++          "name": "bps_wr",
++          "type": "int"
++        },
++        {
++          "name": "iops",
++          "type": "int"
++        },
++        {
++          "name": "iops_rd",
++          "type": "int"
++        },
++        {
++          "name": "iops_wr",
++          "type": "int"
++        },
++        {
++          "name": "image",
++          "type": "240"
++        },
++        {
++          "name": "bps_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_rd_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_wr_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_rd_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_wr_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_rd_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_wr_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_rd_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_wr_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "group",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "cache",
++          "type": "241"
++        },
++        {
++          "name": "write_threshold",
++          "type": "int"
++        },
++        {
++          "name": "dirty-bitmaps",
++          "default": null,
++          "type": "[231]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "34",
++      "members": [
++        {
++          "name": "nodes",
++          "type": "[242]"
++        },
++        {
++          "name": "edges",
++          "type": "[243]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "35",
++      "members": [
++        {
++          "name": "job-id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "target",
++          "type": "str"
++        },
++        {
++          "name": "format",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "replaces",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "sync",
++          "type": "236"
++        },
++        {
++          "name": "mode",
++          "default": null,
++          "type": "235"
++        },
++        {
++          "name": "speed",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "granularity",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "buf-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "on-source-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "on-target-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "unmap",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "copy-mode",
++          "default": null,
++          "type": "244"
++        },
++        {
++          "name": "auto-finalize",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "auto-dismiss",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "36",
++      "members": [
++        {
++          "name": "node",
++          "type": "str"
++        },
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "granularity",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "persistent",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "disabled",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "37",
++      "members": [
++        {
++          "name": "node",
++          "type": "str"
++        },
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "38",
++      "members": [
++        {
++          "name": "node",
++          "type": "str"
++        },
++        {
++          "name": "target",
++          "type": "str"
++        },
++        {
++          "name": "bitmaps",
++          "type": "[245]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "39",
++      "members": [
++        {
++          "name": "sha256",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "40",
++      "members": [
++        {
++          "name": "job-id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "target",
++          "type": "str"
++        },
++        {
++          "name": "replaces",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "sync",
++          "type": "236"
++        },
++        {
++          "name": "speed",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "granularity",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "buf-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "on-source-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "on-target-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "filter-node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "copy-mode",
++          "default": null,
++          "type": "244"
++        },
++        {
++          "name": "auto-finalize",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "auto-dismiss",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "41",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "bps",
++          "type": "int"
++        },
++        {
++          "name": "bps_rd",
++          "type": "int"
++        },
++        {
++          "name": "bps_wr",
++          "type": "int"
++        },
++        {
++          "name": "iops",
++          "type": "int"
++        },
++        {
++          "name": "iops_rd",
++          "type": "int"
++        },
++        {
++          "name": "iops_wr",
++          "type": "int"
++        },
++        {
++          "name": "bps_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_rd_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_wr_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_rd_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_wr_max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_rd_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bps_wr_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_rd_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_wr_max_length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iops_size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "group",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "42",
++      "members": [
++        {
++          "name": "job-id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "base",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "base-node",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "backing-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "speed",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "on-error",
++          "default": null,
++          "type": "238"
++        },
++        {
++          "name": "auto-finalize",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "auto-dismiss",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "43",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "speed",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "44",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "force",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "45",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "46",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "47",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "48",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "49",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "50",
++      "tag": "driver",
++      "variants": [
++        {
++          "case": "blkdebug",
++          "type": "249"
++        },
++        {
++          "case": "blklogwrites",
++          "type": "250"
++        },
++        {
++          "case": "blkverify",
++          "type": "251"
++        },
++        {
++          "case": "blkreplay",
++          "type": "252"
++        },
++        {
++          "case": "bochs",
++          "type": "253"
++        },
++        {
++          "case": "cloop",
++          "type": "253"
++        },
++        {
++          "case": "compress",
++          "type": "253"
++        },
++        {
++          "case": "copy-on-read",
++          "type": "253"
++        },
++        {
++          "case": "dmg",
++          "type": "253"
++        },
++        {
++          "case": "file",
++          "type": "254"
++        },
++        {
++          "case": "ftp",
++          "type": "255"
++        },
++        {
++          "case": "ftps",
++          "type": "256"
++        },
++        {
++          "case": "gluster",
++          "type": "257"
++        },
++        {
++          "case": "host_cdrom",
++          "type": "254"
++        },
++        {
++          "case": "host_device",
++          "type": "254"
++        },
++        {
++          "case": "http",
++          "type": "258"
++        },
++        {
++          "case": "https",
++          "type": "259"
++        },
++        {
++          "case": "iscsi",
++          "type": "260"
++        },
++        {
++          "case": "luks",
++          "type": "261"
++        },
++        {
++          "case": "nbd",
++          "type": "262"
++        },
++        {
++          "case": "nfs",
++          "type": "263"
++        },
++        {
++          "case": "null-aio",
++          "type": "264"
++        },
++        {
++          "case": "null-co",
++          "type": "264"
++        },
++        {
++          "case": "nvme",
++          "type": "265"
++        },
++        {
++          "case": "parallels",
++          "type": "253"
++        },
++        {
++          "case": "qcow2",
++          "type": "266"
++        },
++        {
++          "case": "qcow",
++          "type": "267"
++        },
++        {
++          "case": "qed",
++          "type": "268"
++        },
++        {
++          "case": "quorum",
++          "type": "269"
++        },
++        {
++          "case": "raw",
++          "type": "270"
++        },
++        {
++          "case": "rbd",
++          "type": "271"
++        },
++        {
++          "case": "replication",
++          "type": "272"
++        },
++        {
++          "case": "sheepdog",
++          "type": "273"
++        },
++        {
++          "case": "ssh",
++          "type": "274"
++        },
++        {
++          "case": "throttle",
++          "type": "275"
++        },
++        {
++          "case": "vdi",
++          "type": "253"
++        },
++        {
++          "case": "vhdx",
++          "type": "253"
++        },
++        {
++          "case": "vmdk",
++          "type": "268"
++        },
++        {
++          "case": "vpc",
++          "type": "253"
++        },
++        {
++          "case": "vvfat",
++          "type": "276"
++        },
++        {
++          "case": "vxhs",
++          "type": "277"
++        }
++      ],
++      "members": [
++        {
++          "name": "driver",
++          "type": "246"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "discard",
++          "default": null,
++          "type": "247"
++        },
++        {
++          "name": "cache",
++          "default": null,
++          "type": "248"
++        },
++        {
++          "name": "read-only",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "auto-read-only",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "force-share",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "detect-zeroes",
++          "default": null,
++          "type": "239"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "51",
++      "members": [
++        {
++          "name": "node-name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "52",
++      "members": [
++        {
++          "name": "job-id",
++          "type": "str"
++        },
++        {
++          "name": "options",
++          "type": "278"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "53",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "force",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "54",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "55",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "56",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "57",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "format",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "read-only-mode",
++          "default": null,
++          "type": "279"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "58",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "msg",
++          "type": "str"
++        },
++        {
++          "name": "offset",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "fatal",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "59",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "node-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "operation",
++          "type": "280"
++        },
++        {
++          "name": "action",
++          "type": "281"
++        },
++        {
++          "name": "nospace",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "reason",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "60",
++      "members": [
++        {
++          "name": "type",
++          "type": "282"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "len",
++          "type": "int"
++        },
++        {
++          "name": "offset",
++          "type": "int"
++        },
++        {
++          "name": "speed",
++          "type": "int"
++        },
++        {
++          "name": "error",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "61",
++      "members": [
++        {
++          "name": "type",
++          "type": "282"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "len",
++          "type": "int"
++        },
++        {
++          "name": "offset",
++          "type": "int"
++        },
++        {
++          "name": "speed",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "62",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "operation",
++          "type": "280"
++        },
++        {
++          "name": "action",
++          "type": "281"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "63",
++      "members": [
++        {
++          "name": "type",
++          "type": "282"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "len",
++          "type": "int"
++        },
++        {
++          "name": "offset",
++          "type": "int"
++        },
++        {
++          "name": "speed",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "64",
++      "members": [
++        {
++          "name": "type",
++          "type": "282"
++        },
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "65",
++      "members": [
++        {
++          "name": "node-name",
++          "type": "str"
++        },
++        {
++          "name": "amount-exceeded",
++          "type": "int"
++        },
++        {
++          "name": "write-threshold",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "66",
++      "members": [
++        {
++          "name": "node-name",
++          "type": "str"
++        },
++        {
++          "name": "write-threshold",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "67",
++      "members": [
++        {
++          "name": "parent",
++          "type": "str"
++        },
++        {
++          "name": "child",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "node",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "68",
++      "members": [
++        {
++          "name": "node-name",
++          "type": "str"
++        },
++        {
++          "name": "iothread",
++          "type": "283"
++        },
++        {
++          "name": "force",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "69",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "status",
++          "type": "234"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "70",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "71",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "72",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "73",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "74",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "75",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[76]",
++      "element-type": "76",
++      "meta-type": "array"
++    },
++    {
++      "name": "76",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "type",
++          "type": "282"
++        },
++        {
++          "name": "status",
++          "type": "234"
++        },
++        {
++          "name": "current-progress",
++          "type": "int"
++        },
++        {
++          "name": "total-progress",
++          "type": "int"
++        },
++        {
++          "name": "error",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[77]",
++      "element-type": "77",
++      "meta-type": "array"
++    },
++    {
++      "name": "77",
++      "members": [
++        {
++          "name": "label",
++          "type": "str"
++        },
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "frontend-open",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[78]",
++      "element-type": "78",
++      "meta-type": "array"
++    },
++    {
++      "name": "78",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "79",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "data",
++          "type": "str"
++        },
++        {
++          "name": "format",
++          "default": null,
++          "type": "284"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "80",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "format",
++          "default": null,
++          "type": "284"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "str",
++      "json-type": "string",
++      "meta-type": "builtin"
++    },
++    {
++      "name": "81",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "backend",
++          "type": "285"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "82",
++      "members": [
++        {
++          "name": "pty",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "83",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "backend",
++          "type": "285"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "84",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "85",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "86",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "open",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "87",
++      "members": [
++        {
++          "name": "paging",
++          "type": "bool"
++        },
++        {
++          "name": "protocol",
++          "type": "str"
++        },
++        {
++          "name": "detach",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "begin",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "length",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "format",
++          "default": null,
++          "type": "286"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "88",
++      "members": [
++        {
++          "name": "status",
++          "type": "287"
++        },
++        {
++          "name": "completed",
++          "type": "int"
++        },
++        {
++          "name": "total",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "89",
++      "members": [
++        {
++          "name": "result",
++          "type": "88"
++        },
++        {
++          "name": "error",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "90",
++      "members": [
++        {
++          "name": "formats",
++          "type": "[286]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "91",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "up",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "92",
++      "members": [
++        {
++          "name": "type",
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "93",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "94",
++      "members": [
++        {
++          "name": "name",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[95]",
++      "element-type": "95",
++      "meta-type": "array"
++    },
++    {
++      "name": "95",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "promiscuous",
++          "type": "bool"
++        },
++        {
++          "name": "multicast",
++          "type": "288"
++        },
++        {
++          "name": "unicast",
++          "type": "288"
++        },
++        {
++          "name": "vlan",
++          "type": "288"
++        },
++        {
++          "name": "broadcast-allowed",
++          "type": "bool"
++        },
++        {
++          "name": "multicast-overflow",
++          "type": "bool"
++        },
++        {
++          "name": "unicast-overflow",
++          "type": "bool"
++        },
++        {
++          "name": "main-mac",
++          "type": "str"
++        },
++        {
++          "name": "vlan-table",
++          "type": "[int]"
++        },
++        {
++          "name": "unicast-table",
++          "type": "[str]"
++        },
++        {
++          "name": "multicast-table",
++          "type": "[str]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "96",
++      "members": [
++        {
++          "name": "name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "path",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "97",
++      "members": [
++        {
++          "name": "initial",
++          "type": "int"
++        },
++        {
++          "name": "max",
++          "type": "int"
++        },
++        {
++          "name": "rounds",
++          "type": "int"
++        },
++        {
++          "name": "step",
++          "type": "int"
++        },
++        {
++          "name": "interfaces",
++          "default": null,
++          "type": "[str]"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "98",
++      "members": [
++        {
++          "name": "device-id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "99",
++      "members": [
++        {
++          "name": "netdev",
++          "type": "str"
++        },
++        {
++          "name": "gid-status",
++          "type": "bool"
++        },
++        {
++          "name": "subnet-prefix",
++          "type": "int"
++        },
++        {
++          "name": "interface-id",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "100",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "101",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "type": "int"
++        },
++        {
++          "name": "ports",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "102",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[103]",
++      "element-type": "103",
++      "meta-type": "array"
++    },
++    {
++      "name": "103",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "enabled",
++          "type": "bool"
++        },
++        {
++          "name": "link-up",
++          "type": "bool"
++        },
++        {
++          "name": "speed",
++          "type": "int"
++        },
++        {
++          "name": "duplex",
++          "type": "289"
++        },
++        {
++          "name": "autoneg",
++          "type": "290"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "104",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "tbl-id",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[105]",
++      "element-type": "105",
++      "meta-type": "array"
++    },
++    {
++      "name": "105",
++      "members": [
++        {
++          "name": "cookie",
++          "type": "int"
++        },
++        {
++          "name": "hits",
++          "type": "int"
++        },
++        {
++          "name": "key",
++          "type": "291"
++        },
++        {
++          "name": "mask",
++          "type": "292"
++        },
++        {
++          "name": "action",
++          "type": "293"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "106",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "type",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[107]",
++      "element-type": "107",
++      "meta-type": "array"
++    },
++    {
++      "name": "107",
++      "members": [
++        {
++          "name": "id",
++          "type": "int"
++        },
++        {
++          "name": "type",
++          "type": "int"
++        },
++        {
++          "name": "vlan-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "pport",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "index",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "out-pport",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "group-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "set-vlan-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "pop-vlan",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "group-ids",
++          "default": null,
++          "type": "[int]"
++        },
++        {
++          "name": "set-eth-src",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "set-eth-dst",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "ttl-check",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[108]",
++      "element-type": "108",
++      "meta-type": "array"
++    },
++    {
++      "name": "108",
++      "meta-type": "enum",
++      "values": [
++        "tpm-tis",
++        "tpm-crb"
++      ]
++    },
++    {
++      "name": "[109]",
++      "element-type": "109",
++      "meta-type": "array"
++    },
++    {
++      "name": "109",
++      "meta-type": "enum",
++      "values": [
++        "passthrough",
++        "emulator"
++      ]
++    },
++    {
++      "name": "[110]",
++      "element-type": "110",
++      "meta-type": "array"
++    },
++    {
++      "name": "110",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "model",
++          "type": "108"
++        },
++        {
++          "name": "options",
++          "type": "294"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "111",
++      "members": [
++        {
++          "name": "protocol",
++          "type": "str"
++        },
++        {
++          "name": "password",
++          "type": "str"
++        },
++        {
++          "name": "connected",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "112",
++      "members": [
++        {
++          "name": "protocol",
++          "type": "str"
++        },
++        {
++          "name": "time",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "113",
++      "members": [
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "head",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "118",
++      "members": [
++        {
++          "name": "enabled",
++          "type": "bool"
++        },
++        {
++          "name": "host",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "family",
++          "default": null,
++          "type": "299"
++        },
++        {
++          "name": "service",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "auth",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "clients",
++          "default": null,
++          "type": "[300]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[119]",
++      "element-type": "119",
++      "meta-type": "array"
++    },
++    {
++      "name": "119",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "server",
++          "type": "[301]"
++        },
++        {
++          "name": "clients",
++          "type": "[300]"
++        },
++        {
++          "name": "auth",
++          "type": "302"
++        },
++        {
++          "name": "vencrypt",
++          "default": null,
++          "type": "303"
++        },
++        {
++          "name": "display",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "120",
++      "members": [
++        {
++          "name": "password",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "121",
++      "members": [
++        {
++          "name": "server",
++          "type": "304"
++        },
++        {
++          "name": "client",
++          "type": "305"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "122",
++      "members": [
++        {
++          "name": "server",
++          "type": "304"
++        },
++        {
++          "name": "client",
++          "type": "300"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "123",
++      "members": [
++        {
++          "name": "server",
++          "type": "304"
++        },
++        {
++          "name": "client",
++          "type": "300"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[124]",
++      "element-type": "124",
++      "meta-type": "array"
++    },
++    {
++      "name": "124",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "index",
++          "type": "int"
++        },
++        {
++          "name": "current",
++          "type": "bool"
++        },
++        {
++          "name": "absolute",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "125",
++      "members": [
++        {
++          "name": "keys",
++          "type": "[306]"
++        },
++        {
++          "name": "hold-time",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "126",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "head",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "events",
++          "type": "[307]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "127",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "gtk",
++          "type": "310"
++        },
++        {
++          "case": "curses",
++          "type": "311"
++        },
++        {
++          "case": "egl-headless",
++          "type": "312"
++        },
++        {
++          "case": "default",
++          "type": "0"
++        },
++        {
++          "case": "none",
++          "type": "0"
++        },
++        {
++          "case": "sdl",
++          "type": "0"
++        },
++        {
++          "case": "cocoa",
++          "type": "0"
++        },
++        {
++          "case": "spice-app",
++          "type": "0"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "308"
++        },
++        {
++          "name": "full-screen",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "window-close",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "gl",
++          "default": null,
++          "type": "309"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "128",
++      "members": [
++        {
++          "name": "status",
++          "default": null,
++          "type": "313"
++        },
++        {
++          "name": "ram",
++          "default": null,
++          "type": "314"
++        },
++        {
++          "name": "disk",
++          "default": null,
++          "type": "314"
++        },
++        {
++          "name": "xbzrle-cache",
++          "default": null,
++          "type": "315"
++        },
++        {
++          "name": "total-time",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "expected-downtime",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "downtime",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "setup-time",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cpu-throttle-percentage",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "error-desc",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "postcopy-blocktime",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "postcopy-vcpu-blocktime",
++          "default": null,
++          "type": "[int]"
++        },
++        {
++          "name": "compression",
++          "default": null,
++          "type": "316"
++        },
++        {
++          "name": "socket-address",
++          "default": null,
++          "type": "[317]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "129",
++      "members": [
++        {
++          "name": "capabilities",
++          "type": "[130]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[130]",
++      "element-type": "130",
++      "meta-type": "array"
++    },
++    {
++      "name": "130",
++      "members": [
++        {
++          "name": "capability",
++          "type": "318"
++        },
++        {
++          "name": "state",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "131",
++      "members": [
++        {
++          "name": "announce-initial",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "announce-max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "announce-rounds",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "announce-step",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "compress-level",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "compress-threads",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "compress-wait-thread",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "decompress-threads",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cpu-throttle-initial",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cpu-throttle-increment",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tls-creds",
++          "default": null,
++          "type": "283"
++        },
++        {
++          "name": "tls-hostname",
++          "default": null,
++          "type": "283"
++        },
++        {
++          "name": "tls-authz",
++          "default": null,
++          "type": "283"
++        },
++        {
++          "name": "max-bandwidth",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "downtime-limit",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "x-checkpoint-delay",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "block-incremental",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "multifd-channels",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "xbzrle-cache-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "max-postcopy-bandwidth",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "max-cpu-throttle",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "132",
++      "members": [
++        {
++          "name": "announce-initial",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "announce-max",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "announce-rounds",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "announce-step",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "compress-level",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "compress-threads",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "compress-wait-thread",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "decompress-threads",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cpu-throttle-initial",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cpu-throttle-increment",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tls-creds",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "tls-hostname",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "tls-authz",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "max-bandwidth",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "downtime-limit",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "x-checkpoint-delay",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "block-incremental",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "multifd-channels",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "xbzrle-cache-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "max-postcopy-bandwidth",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "max-cpu-throttle",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "133",
++      "members": [
++        {
++          "name": "protocol",
++          "type": "str"
++        },
++        {
++          "name": "hostname",
++          "type": "str"
++        },
++        {
++          "name": "port",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tls-port",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cert-subject",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "134",
++      "members": [
++        {
++          "name": "status",
++          "type": "313"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "135",
++      "members": [
++        {
++          "name": "pass",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "136",
++      "members": [
++        {
++          "name": "mode",
++          "type": "319"
++        },
++        {
++          "name": "reason",
++          "type": "320"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "137",
++      "members": [
++        {
++          "name": "state",
++          "type": "313"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "138",
++      "members": [
++        {
++          "name": "value",
++          "type": "number"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "139",
++      "members": [
++        {
++          "name": "value",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "140",
++      "members": [
++        {
++          "name": "value",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "int",
++      "json-type": "int",
++      "meta-type": "builtin"
++    },
++    {
++      "name": "141",
++      "members": [
++        {
++          "name": "uri",
++          "type": "str"
++        },
++        {
++          "name": "blk",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "inc",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "detach",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "resume",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "142",
++      "members": [
++        {
++          "name": "uri",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "143",
++      "members": [
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "live",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "144",
++      "members": [
++        {
++          "name": "enable",
++          "type": "bool"
++        },
++        {
++          "name": "primary",
++          "type": "bool"
++        },
++        {
++          "name": "failover",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "145",
++      "members": [
++        {
++          "name": "error",
++          "type": "bool"
++        },
++        {
++          "name": "desc",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "146",
++      "members": [
++        {
++          "name": "mode",
++          "type": "319"
++        },
++        {
++          "name": "last-mode",
++          "type": "319"
++        },
++        {
++          "name": "reason",
++          "type": "320"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "147",
++      "members": [
++        {
++          "name": "uri",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "148",
++      "members": [
++        {
++          "name": "device-id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "149",
++      "members": [
++        {
++          "name": "actions",
++          "type": "[321]"
++        },
++        {
++          "name": "properties",
++          "default": null,
++          "type": "322"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "150",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "vcpu",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[151]",
++      "element-type": "151",
++      "meta-type": "array"
++    },
++    {
++      "name": "151",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "state",
++          "type": "323"
++        },
++        {
++          "name": "vcpu",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "152",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "enable",
++          "type": "bool"
++        },
++        {
++          "name": "ignore-unavailable",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "vcpu",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[153]",
++      "element-type": "153",
++      "meta-type": "array"
++    },
++    {
++      "name": "153",
++      "tag": "meta-type",
++      "variants": [
++        {
++          "case": "builtin",
++          "type": "325"
++        },
++        {
++          "case": "enum",
++          "type": "326"
++        },
++        {
++          "case": "array",
++          "type": "327"
++        },
++        {
++          "case": "object",
++          "type": "328"
++        },
++        {
++          "case": "alternate",
++          "type": "329"
++        },
++        {
++          "case": "command",
++          "type": "330"
++        },
++        {
++          "case": "event",
++          "type": "331"
++        }
++      ],
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "meta-type",
++          "type": "324"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "154",
++      "members": [
++        {
++          "name": "path",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[155]",
++      "element-type": "155",
++      "meta-type": "array"
++    },
++    {
++      "name": "155",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "type",
++          "type": "str"
++        },
++        {
++          "name": "description",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "default-value",
++          "default": null,
++          "type": "any"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "156",
++      "members": [
++        {
++          "name": "path",
++          "type": "str"
++        },
++        {
++          "name": "property",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "any",
++      "json-type": "value",
++      "meta-type": "builtin"
++    },
++    {
++      "name": "157",
++      "members": [
++        {
++          "name": "path",
++          "type": "str"
++        },
++        {
++          "name": "property",
++          "type": "str"
++        },
++        {
++          "name": "value",
++          "type": "any"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "158",
++      "members": [
++        {
++          "name": "implements",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "abstract",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[159]",
++      "element-type": "159",
++      "meta-type": "array"
++    },
++    {
++      "name": "159",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "abstract",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "parent",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "160",
++      "members": [
++        {
++          "name": "typename",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "161",
++      "members": [
++        {
++          "name": "qom-type",
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "props",
++          "default": null,
++          "type": "any"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "162",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "163",
++      "members": [
++        {
++          "name": "typename",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "164",
++      "members": [
++        {
++          "name": "driver",
++          "type": "str"
++        },
++        {
++          "name": "bus",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "165",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "166",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "path",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[167]",
++      "element-type": "167",
++      "meta-type": "array"
++    },
++    {
++      "name": "167",
++      "tag": "arch",
++      "variants": [
++        {
++          "case": "x86",
++          "type": "334"
++        },
++        {
++          "case": "sparc",
++          "type": "335"
++        },
++        {
++          "case": "ppc",
++          "type": "336"
++        },
++        {
++          "case": "mips",
++          "type": "337"
++        },
++        {
++          "case": "tricore",
++          "type": "338"
++        },
++        {
++          "case": "s390",
++          "type": "339"
++        },
++        {
++          "case": "riscv",
++          "type": "340"
++        },
++        {
++          "case": "other",
++          "type": "0"
++        }
++      ],
++      "members": [
++        {
++          "name": "CPU",
++          "type": "int"
++        },
++        {
++          "name": "current",
++          "type": "bool"
++        },
++        {
++          "name": "halted",
++          "type": "bool"
++        },
++        {
++          "name": "qom_path",
++          "type": "str"
++        },
++        {
++          "name": "thread_id",
++          "type": "int"
++        },
++        {
++          "name": "props",
++          "default": null,
++          "type": "332"
++        },
++        {
++          "name": "arch",
++          "type": "333"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[168]",
++      "element-type": "168",
++      "meta-type": "array"
++    },
++    {
++      "name": "168",
++      "tag": "target",
++      "variants": [
++        {
++          "case": "s390x",
++          "type": "339"
++        },
++        {
++          "case": "aarch64",
++          "type": "0"
++        },
++        {
++          "case": "alpha",
++          "type": "0"
++        },
++        {
++          "case": "arm",
++          "type": "0"
++        },
++        {
++          "case": "cris",
++          "type": "0"
++        },
++        {
++          "case": "hppa",
++          "type": "0"
++        },
++        {
++          "case": "i386",
++          "type": "0"
++        },
++        {
++          "case": "lm32",
++          "type": "0"
++        },
++        {
++          "case": "m68k",
++          "type": "0"
++        },
++        {
++          "case": "microblaze",
++          "type": "0"
++        },
++        {
++          "case": "microblazeel",
++          "type": "0"
++        },
++        {
++          "case": "mips",
++          "type": "0"
++        },
++        {
++          "case": "mips64",
++          "type": "0"
++        },
++        {
++          "case": "mips64el",
++          "type": "0"
++        },
++        {
++          "case": "mipsel",
++          "type": "0"
++        },
++        {
++          "case": "moxie",
++          "type": "0"
++        },
++        {
++          "case": "nios2",
++          "type": "0"
++        },
++        {
++          "case": "or1k",
++          "type": "0"
++        },
++        {
++          "case": "ppc",
++          "type": "0"
++        },
++        {
++          "case": "ppc64",
++          "type": "0"
++        },
++        {
++          "case": "riscv32",
++          "type": "0"
++        },
++        {
++          "case": "riscv64",
++          "type": "0"
++        },
++        {
++          "case": "sh4",
++          "type": "0"
++        },
++        {
++          "case": "sh4eb",
++          "type": "0"
++        },
++        {
++          "case": "sparc",
++          "type": "0"
++        },
++        {
++          "case": "sparc64",
++          "type": "0"
++        },
++        {
++          "case": "tricore",
++          "type": "0"
++        },
++        {
++          "case": "unicore32",
++          "type": "0"
++        },
++        {
++          "case": "x86_64",
++          "type": "0"
++        },
++        {
++          "case": "xtensa",
++          "type": "0"
++        },
++        {
++          "case": "xtensaeb",
++          "type": "0"
++        }
++      ],
++      "members": [
++        {
++          "name": "cpu-index",
++          "type": "int"
++        },
++        {
++          "name": "qom-path",
++          "type": "str"
++        },
++        {
++          "name": "thread-id",
++          "type": "int"
++        },
++        {
++          "name": "props",
++          "default": null,
++          "type": "332"
++        },
++        {
++          "name": "arch",
++          "type": "333"
++        },
++        {
++          "name": "target",
++          "type": "341"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "169",
++      "members": [
++        {
++          "name": "id",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[170]",
++      "element-type": "170",
++      "meta-type": "array"
++    },
++    {
++      "name": "170",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "alias",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "is-default",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "cpu-max",
++          "type": "int"
++        },
++        {
++          "name": "hotpluggable-cpus",
++          "type": "bool"
++        },
++        {
++          "name": "numa-mem-supported",
++          "type": "bool"
++        },
++        {
++          "name": "deprecated",
++          "type": "bool"
++        },
++        {
++          "name": "default-cpu-type",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "171",
++      "members": [
++        {
++          "name": "wakeup-suspend-support",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "172",
++      "members": [
++        {
++          "name": "arch",
++          "type": "341"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[173]",
++      "element-type": "173",
++      "meta-type": "array"
++    },
++    {
++      "name": "173",
++      "members": [
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "merge",
++          "type": "bool"
++        },
++        {
++          "name": "dump",
++          "type": "bool"
++        },
++        {
++          "name": "prealloc",
++          "type": "bool"
++        },
++        {
++          "name": "host-nodes",
++          "type": "[int]"
++        },
++        {
++          "name": "policy",
++          "type": "342"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[174]",
++      "element-type": "174",
++      "meta-type": "array"
++    },
++    {
++      "name": "174",
++      "members": [
++        {
++          "name": "type",
++          "type": "str"
++        },
++        {
++          "name": "vcpus-count",
++          "type": "int"
++        },
++        {
++          "name": "props",
++          "type": "332"
++        },
++        {
++          "name": "qom-path",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "175",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "node",
++          "type": "344"
++        },
++        {
++          "case": "dist",
++          "type": "345"
++        },
++        {
++          "case": "cpu",
++          "type": "346"
++        },
++        {
++          "case": "hmat-lb",
++          "type": "347"
++        },
++        {
++          "case": "hmat-cache",
++          "type": "348"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "343"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "180",
++      "members": [
++        {
++          "name": "type",
++          "type": "351"
++        },
++        {
++          "name": "model",
++          "type": "349"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "181",
++      "members": [
++        {
++          "name": "model",
++          "type": "349"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[182]",
++      "element-type": "182",
++      "meta-type": "array"
++    },
++    {
++      "name": "182",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "migration-safe",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "static",
++          "type": "bool"
++        },
++        {
++          "name": "unavailable-features",
++          "default": null,
++          "type": "[str]"
++        },
++        {
++          "name": "typename",
++          "type": "str"
++        },
++        {
++          "name": "alias-of",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "183",
++      "members": [
++        {
++          "name": "enable",
++          "default": null,
++          "type": "[352]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "184",
++      "members": [
++        {
++          "name": "qemu",
++          "type": "353"
++        },
++        {
++          "name": "package",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[185]",
++      "element-type": "185",
++      "meta-type": "array"
++    },
++    {
++      "name": "185",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "186",
++      "members": [
++        {
++          "name": "protocol",
++          "type": "str"
++        },
++        {
++          "name": "fdname",
++          "type": "str"
++        },
++        {
++          "name": "skipauth",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "tls",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "187",
++      "members": [
++        {
++          "name": "name",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "188",
++      "members": [
++        {
++          "name": "enabled",
++          "type": "bool"
++        },
++        {
++          "name": "present",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "189",
++      "members": [
++        {
++          "name": "UUID",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[190]",
++      "element-type": "190",
++      "meta-type": "array"
++    },
++    {
++      "name": "190",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[191]",
++      "element-type": "191",
++      "meta-type": "array"
++    },
++    {
++      "name": "191",
++      "members": [
++        {
++          "name": "id",
++          "type": "str"
++        },
++        {
++          "name": "thread-id",
++          "type": "int"
++        },
++        {
++          "name": "poll-max-ns",
++          "type": "int"
++        },
++        {
++          "name": "poll-grow",
++          "type": "int"
++        },
++        {
++          "name": "poll-shrink",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "192",
++      "members": [
++        {
++          "name": "actual",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "193",
++      "members": [
++        {
++          "name": "actual",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[194]",
++      "element-type": "194",
++      "meta-type": "array"
++    },
++    {
++      "name": "194",
++      "members": [
++        {
++          "name": "bus",
++          "type": "int"
++        },
++        {
++          "name": "devices",
++          "type": "[354]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "195",
++      "members": [
++        {
++          "name": "val",
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "cpu-index",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "196",
++      "members": [
++        {
++          "name": "val",
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "filename",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "197",
++      "members": [
++        {
++          "name": "value",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "198",
++      "members": [
++        {
++          "name": "command-line",
++          "type": "str"
++        },
++        {
++          "name": "cpu-index",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "199",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "target",
++          "type": "str"
++        },
++        {
++          "name": "arg",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "200",
++      "members": [
++        {
++          "name": "enable",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "201",
++      "members": [
++        {
++          "name": "fdname",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "202",
++      "members": [
++        {
++          "name": "fdname",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "203",
++      "members": [
++        {
++          "name": "base-memory",
++          "type": "int"
++        },
++        {
++          "name": "plugged-memory",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "204",
++      "members": [
++        {
++          "name": "fdset-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "opaque",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "205",
++      "members": [
++        {
++          "name": "fdset-id",
++          "type": "int"
++        },
++        {
++          "name": "fd",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "206",
++      "members": [
++        {
++          "name": "fdset-id",
++          "type": "int"
++        },
++        {
++          "name": "fd",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[207]",
++      "element-type": "207",
++      "meta-type": "array"
++    },
++    {
++      "name": "207",
++      "members": [
++        {
++          "name": "fdset-id",
++          "type": "int"
++        },
++        {
++          "name": "fds",
++          "type": "[355]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "208",
++      "members": [
++        {
++          "name": "option",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[209]",
++      "element-type": "209",
++      "meta-type": "array"
++    },
++    {
++      "name": "209",
++      "members": [
++        {
++          "name": "option",
++          "type": "str"
++        },
++        {
++          "name": "parameters",
++          "type": "[356]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[210]",
++      "element-type": "210",
++      "meta-type": "array"
++    },
++    {
++      "name": "210",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "dimm",
++          "type": "358"
++        },
++        {
++          "case": "nvdimm",
++          "type": "358"
++        },
++        {
++          "case": "virtio-pmem",
++          "type": "359"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "357"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "211",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "msg",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[212]",
++      "element-type": "212",
++      "meta-type": "array"
++    },
++    {
++      "name": "212",
++      "members": [
++        {
++          "name": "device",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "slot",
++          "type": "str"
++        },
++        {
++          "name": "slot-type",
++          "type": "360"
++        },
++        {
++          "name": "source",
++          "type": "int"
++        },
++        {
++          "name": "status",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "213",
++      "members": [
++        {
++          "name": "info",
++          "type": "212"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "214",
++      "members": [
++        {
++          "name": "filename",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "215",
++      "members": [
++        {
++          "name": "guid",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "216",
++      "members": [
++        {
++          "name": "offset",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[221]",
++      "element-type": "221",
++      "meta-type": "array"
++    },
++    {
++      "name": "221",
++      "members": [
++        {
++          "name": "version",
++          "type": "int"
++        },
++        {
++          "name": "emulated",
++          "type": "bool"
++        },
++        {
++          "name": "kernel",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "bool",
++      "json-type": "boolean",
++      "meta-type": "builtin"
++    },
++    {
++      "name": "222",
++      "meta-type": "enum",
++      "values": [
++        "debug",
++        "inmigrate",
++        "internal-error",
++        "io-error",
++        "paused",
++        "postmigrate",
++        "prelaunch",
++        "finish-migrate",
++        "restore-vm",
++        "running",
++        "save-vm",
++        "shutdown",
++        "suspended",
++        "watchdog",
++        "guest-panicked",
++        "colo",
++        "preconfig"
++      ]
++    },
++    {
++      "name": "223",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "host-error",
++        "host-qmp-quit",
++        "host-qmp-system-reset",
++        "host-signal",
++        "host-ui",
++        "guest-shutdown",
++        "guest-reset",
++        "guest-panic",
++        "subsystem-reset"
++      ]
++    },
++    {
++      "name": "224",
++      "meta-type": "enum",
++      "values": [
++        "reset",
++        "shutdown",
++        "poweroff",
++        "pause",
++        "debug",
++        "none",
++        "inject-nmi"
++      ]
++    },
++    {
++      "name": "225",
++      "meta-type": "enum",
++      "values": [
++        "pause",
++        "poweroff",
++        "run"
++      ]
++    },
++    {
++      "name": "226",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "hyper-v",
++          "type": "363"
++        },
++        {
++          "case": "s390",
++          "type": "364"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "362"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "227",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "inet",
++          "type": "366"
++        },
++        {
++          "case": "unix",
++          "type": "367"
++        },
++        {
++          "case": "vsock",
++          "type": "368"
++        },
++        {
++          "case": "fd",
++          "type": "369"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "365"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "228",
++      "meta-type": "enum",
++      "values": [
++        "safe",
++        "hard"
++      ]
++    },
++    {
++      "name": "229",
++      "meta-type": "enum",
++      "values": [
++        "read",
++        "write",
++        "flush"
++      ]
++    },
++    {
++      "name": "[int]",
++      "element-type": "int",
++      "meta-type": "array"
++    },
++    {
++      "name": "230",
++      "meta-type": "enum",
++      "values": [
++        "ok",
++        "failed",
++        "nospace"
++      ]
++    },
++    {
++      "name": "[231]",
++      "element-type": "231",
++      "meta-type": "array"
++    },
++    {
++      "name": "231",
++      "members": [
++        {
++          "name": "name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "count",
++          "type": "int"
++        },
++        {
++          "name": "granularity",
++          "type": "int"
++        },
++        {
++          "name": "recording",
++          "type": "bool"
++        },
++        {
++          "name": "busy",
++          "type": "bool"
++        },
++        {
++          "name": "status",
++          "type": "370"
++        },
++        {
++          "name": "persistent",
++          "type": "bool"
++        },
++        {
++          "name": "inconsistent",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "232",
++      "members": [
++        {
++          "name": "rd_bytes",
++          "type": "int"
++        },
++        {
++          "name": "wr_bytes",
++          "type": "int"
++        },
++        {
++          "name": "unmap_bytes",
++          "type": "int"
++        },
++        {
++          "name": "rd_operations",
++          "type": "int"
++        },
++        {
++          "name": "wr_operations",
++          "type": "int"
++        },
++        {
++          "name": "flush_operations",
++          "type": "int"
++        },
++        {
++          "name": "unmap_operations",
++          "type": "int"
++        },
++        {
++          "name": "rd_total_time_ns",
++          "type": "int"
++        },
++        {
++          "name": "wr_total_time_ns",
++          "type": "int"
++        },
++        {
++          "name": "flush_total_time_ns",
++          "type": "int"
++        },
++        {
++          "name": "unmap_total_time_ns",
++          "type": "int"
++        },
++        {
++          "name": "wr_highest_offset",
++          "type": "int"
++        },
++        {
++          "name": "rd_merged",
++          "type": "int"
++        },
++        {
++          "name": "wr_merged",
++          "type": "int"
++        },
++        {
++          "name": "unmap_merged",
++          "type": "int"
++        },
++        {
++          "name": "idle_time_ns",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "failed_rd_operations",
++          "type": "int"
++        },
++        {
++          "name": "failed_wr_operations",
++          "type": "int"
++        },
++        {
++          "name": "failed_flush_operations",
++          "type": "int"
++        },
++        {
++          "name": "failed_unmap_operations",
++          "type": "int"
++        },
++        {
++          "name": "invalid_rd_operations",
++          "type": "int"
++        },
++        {
++          "name": "invalid_wr_operations",
++          "type": "int"
++        },
++        {
++          "name": "invalid_flush_operations",
++          "type": "int"
++        },
++        {
++          "name": "invalid_unmap_operations",
++          "type": "int"
++        },
++        {
++          "name": "account_invalid",
++          "type": "bool"
++        },
++        {
++          "name": "account_failed",
++          "type": "bool"
++        },
++        {
++          "name": "timed_stats",
++          "type": "[371]"
++        },
++        {
++          "name": "rd_latency_histogram",
++          "default": null,
++          "type": "372"
++        },
++        {
++          "name": "wr_latency_histogram",
++          "default": null,
++          "type": "372"
++        },
++        {
++          "name": "flush_latency_histogram",
++          "default": null,
++          "type": "372"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "233",
++      "tag": "driver",
++      "variants": [
++        {
++          "case": "file",
++          "type": "373"
++        },
++        {
++          "case": "host_device",
++          "type": "373"
++        },
++        {
++          "case": "blkdebug",
++          "type": "0"
++        },
++        {
++          "case": "blklogwrites",
++          "type": "0"
++        },
++        {
++          "case": "blkreplay",
++          "type": "0"
++        },
++        {
++          "case": "blkverify",
++          "type": "0"
++        },
++        {
++          "case": "bochs",
++          "type": "0"
++        },
++        {
++          "case": "cloop",
++          "type": "0"
++        },
++        {
++          "case": "compress",
++          "type": "0"
++        },
++        {
++          "case": "copy-on-read",
++          "type": "0"
++        },
++        {
++          "case": "dmg",
++          "type": "0"
++        },
++        {
++          "case": "ftp",
++          "type": "0"
++        },
++        {
++          "case": "ftps",
++          "type": "0"
++        },
++        {
++          "case": "gluster",
++          "type": "0"
++        },
++        {
++          "case": "host_cdrom",
++          "type": "0"
++        },
++        {
++          "case": "http",
++          "type": "0"
++        },
++        {
++          "case": "https",
++          "type": "0"
++        },
++        {
++          "case": "iscsi",
++          "type": "0"
++        },
++        {
++          "case": "luks",
++          "type": "0"
++        },
++        {
++          "case": "nbd",
++          "type": "0"
++        },
++        {
++          "case": "nfs",
++          "type": "0"
++        },
++        {
++          "case": "null-aio",
++          "type": "0"
++        },
++        {
++          "case": "null-co",
++          "type": "0"
++        },
++        {
++          "case": "nvme",
++          "type": "0"
++        },
++        {
++          "case": "parallels",
++          "type": "0"
++        },
++        {
++          "case": "qcow",
++          "type": "0"
++        },
++        {
++          "case": "qcow2",
++          "type": "0"
++        },
++        {
++          "case": "qed",
++          "type": "0"
++        },
++        {
++          "case": "quorum",
++          "type": "0"
++        },
++        {
++          "case": "raw",
++          "type": "0"
++        },
++        {
++          "case": "rbd",
++          "type": "0"
++        },
++        {
++          "case": "replication",
++          "type": "0"
++        },
++        {
++          "case": "sheepdog",
++          "type": "0"
++        },
++        {
++          "case": "ssh",
++          "type": "0"
++        },
++        {
++          "case": "throttle",
++          "type": "0"
++        },
++        {
++          "case": "vdi",
++          "type": "0"
++        },
++        {
++          "case": "vhdx",
++          "type": "0"
++        },
++        {
++          "case": "vmdk",
++          "type": "0"
++        },
++        {
++          "case": "vpc",
++          "type": "0"
++        },
++        {
++          "case": "vvfat",
++          "type": "0"
++        },
++        {
++          "case": "vxhs",
++          "type": "0"
++        }
++      ],
++      "members": [
++        {
++          "name": "driver",
++          "type": "246"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "234",
++      "meta-type": "enum",
++      "values": [
++        "undefined",
++        "created",
++        "running",
++        "paused",
++        "ready",
++        "standby",
++        "waiting",
++        "pending",
++        "aborting",
++        "concluded",
++        "null"
++      ]
++    },
++    {
++      "name": "235",
++      "meta-type": "enum",
++      "values": [
++        "existing",
++        "absolute-paths"
++      ]
++    },
++    {
++      "name": "236",
++      "meta-type": "enum",
++      "values": [
++        "top",
++        "full",
++        "none",
++        "incremental",
++        "bitmap"
++      ]
++    },
++    {
++      "name": "237",
++      "meta-type": "enum",
++      "values": [
++        "on-success",
++        "never",
++        "always"
++      ]
++    },
++    {
++      "name": "238",
++      "meta-type": "enum",
++      "values": [
++        "report",
++        "ignore",
++        "enospc",
++        "stop",
++        "auto"
++      ]
++    },
++    {
++      "name": "239",
++      "meta-type": "enum",
++      "values": [
++        "off",
++        "on",
++        "unmap"
++      ]
++    },
++    {
++      "name": "240",
++      "members": [
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "format",
++          "type": "str"
++        },
++        {
++          "name": "dirty-flag",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "actual-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "virtual-size",
++          "type": "int"
++        },
++        {
++          "name": "cluster-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "encrypted",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "compressed",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "backing-filename",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "full-backing-filename",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "backing-filename-format",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "snapshots",
++          "default": null,
++          "type": "[11]"
++        },
++        {
++          "name": "backing-image",
++          "default": null,
++          "type": "240"
++        },
++        {
++          "name": "format-specific",
++          "default": null,
++          "type": "374"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "241",
++      "members": [
++        {
++          "name": "writeback",
++          "type": "bool"
++        },
++        {
++          "name": "direct",
++          "type": "bool"
++        },
++        {
++          "name": "no-flush",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[242]",
++      "element-type": "242",
++      "meta-type": "array"
++    },
++    {
++      "name": "242",
++      "members": [
++        {
++          "name": "id",
++          "type": "int"
++        },
++        {
++          "name": "type",
++          "type": "375"
++        },
++        {
++          "name": "name",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[243]",
++      "element-type": "243",
++      "meta-type": "array"
++    },
++    {
++      "name": "243",
++      "members": [
++        {
++          "name": "parent",
++          "type": "int"
++        },
++        {
++          "name": "child",
++          "type": "int"
++        },
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "perm",
++          "type": "[376]"
++        },
++        {
++          "name": "shared-perm",
++          "type": "[376]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "244",
++      "meta-type": "enum",
++      "values": [
++        "background",
++        "write-blocking"
++      ]
++    },
++    {
++      "name": "[245]",
++      "element-type": "245",
++      "meta-type": "array"
++    },
++    {
++      "name": "245",
++      "members": [
++        {
++          "type": "str"
++        },
++        {
++          "type": "37"
++        }
++      ],
++      "meta-type": "alternate"
++    },
++    {
++      "name": "246",
++      "meta-type": "enum",
++      "values": [
++        "blkdebug",
++        "blklogwrites",
++        "blkreplay",
++        "blkverify",
++        "bochs",
++        "cloop",
++        "compress",
++        "copy-on-read",
++        "dmg",
++        "file",
++        "ftp",
++        "ftps",
++        "gluster",
++        "host_cdrom",
++        "host_device",
++        "http",
++        "https",
++        "iscsi",
++        "luks",
++        "nbd",
++        "nfs",
++        "null-aio",
++        "null-co",
++        "nvme",
++        "parallels",
++        "qcow",
++        "qcow2",
++        "qed",
++        "quorum",
++        "raw",
++        "rbd",
++        "replication",
++        "sheepdog",
++        "ssh",
++        "throttle",
++        "vdi",
++        "vhdx",
++        "vmdk",
++        "vpc",
++        "vvfat",
++        "vxhs"
++      ]
++    },
++    {
++      "name": "247",
++      "meta-type": "enum",
++      "values": [
++        "ignore",
++        "unmap"
++      ]
++    },
++    {
++      "name": "248",
++      "members": [
++        {
++          "name": "direct",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "no-flush",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "249",
++      "members": [
++        {
++          "name": "image",
++          "type": "377"
++        },
++        {
++          "name": "config",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "align",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "max-transfer",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "opt-write-zero",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "max-write-zero",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "opt-discard",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "max-discard",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "inject-error",
++          "default": null,
++          "type": "[378]"
++        },
++        {
++          "name": "set-state",
++          "default": null,
++          "type": "[379]"
++        },
++        {
++          "name": "take-child-perms",
++          "default": null,
++          "type": "[376]"
++        },
++        {
++          "name": "unshare-child-perms",
++          "default": null,
++          "type": "[376]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "250",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "log",
++          "type": "377"
++        },
++        {
++          "name": "log-sector-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "log-append",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "log-super-update-interval",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "251",
++      "members": [
++        {
++          "name": "test",
++          "type": "377"
++        },
++        {
++          "name": "raw",
++          "type": "377"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "252",
++      "members": [
++        {
++          "name": "image",
++          "type": "377"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "253",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "254",
++      "members": [
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "pr-manager",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "locking",
++          "default": null,
++          "type": "380"
++        },
++        {
++          "name": "aio",
++          "default": null,
++          "type": "381"
++        },
++        {
++          "name": "drop-cache",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "x-check-cache-dropped",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object",
++      "features": [
++        "dynamic-auto-read-only"
++      ]
++    },
++    {
++      "name": "255",
++      "members": [
++        {
++          "name": "url",
++          "type": "str"
++        },
++        {
++          "name": "readahead",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "timeout",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-password-secret",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "256",
++      "members": [
++        {
++          "name": "url",
++          "type": "str"
++        },
++        {
++          "name": "readahead",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "timeout",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "sslverify",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "257",
++      "members": [
++        {
++          "name": "volume",
++          "type": "str"
++        },
++        {
++          "name": "path",
++          "type": "str"
++        },
++        {
++          "name": "server",
++          "type": "[317]"
++        },
++        {
++          "name": "debug",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "258",
++      "members": [
++        {
++          "name": "url",
++          "type": "str"
++        },
++        {
++          "name": "readahead",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "timeout",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "cookie",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "cookie-secret",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "259",
++      "members": [
++        {
++          "name": "url",
++          "type": "str"
++        },
++        {
++          "name": "readahead",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "timeout",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-username",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "proxy-password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "cookie",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "sslverify",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "cookie-secret",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "260",
++      "members": [
++        {
++          "name": "transport",
++          "type": "382"
++        },
++        {
++          "name": "portal",
++          "type": "str"
++        },
++        {
++          "name": "target",
++          "type": "str"
++        },
++        {
++          "name": "lun",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "user",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "password-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "initiator-name",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "header-digest",
++          "default": null,
++          "type": "383"
++        },
++        {
++          "name": "timeout",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "261",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "key-secret",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "262",
++      "members": [
++        {
++          "name": "server",
++          "type": "317"
++        },
++        {
++          "name": "export",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "tls-creds",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "x-dirty-bitmap",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "reconnect-delay",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "263",
++      "members": [
++        {
++          "name": "server",
++          "type": "384"
++        },
++        {
++          "name": "path",
++          "type": "str"
++        },
++        {
++          "name": "user",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "group",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tcp-syn-count",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "readahead-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "page-cache-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "debug",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "264",
++      "members": [
++        {
++          "name": "size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "latency-ns",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "read-zeroes",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "265",
++      "members": [
++        {
++          "name": "device",
++          "type": "str"
++        },
++        {
++          "name": "namespace",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "266",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "backing",
++          "default": null,
++          "type": "385"
++        },
++        {
++          "name": "lazy-refcounts",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "pass-discard-request",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "pass-discard-snapshot",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "pass-discard-other",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "overlap-check",
++          "default": null,
++          "type": "386"
++        },
++        {
++          "name": "cache-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "l2-cache-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "l2-cache-entry-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "refcount-cache-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cache-clean-interval",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "encrypt",
++          "default": null,
++          "type": "387"
++        },
++        {
++          "name": "data-file",
++          "default": null,
++          "type": "377"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "267",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "backing",
++          "default": null,
++          "type": "385"
++        },
++        {
++          "name": "encrypt",
++          "default": null,
++          "type": "388"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "268",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "backing",
++          "default": null,
++          "type": "385"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "269",
++      "members": [
++        {
++          "name": "blkverify",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "children",
++          "type": "[377]"
++        },
++        {
++          "name": "vote-threshold",
++          "type": "int"
++        },
++        {
++          "name": "rewrite-corrupted",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "read-pattern",
++          "default": null,
++          "type": "389"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "270",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "offset",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "271",
++      "members": [
++        {
++          "name": "pool",
++          "type": "str"
++        },
++        {
++          "name": "image",
++          "type": "str"
++        },
++        {
++          "name": "conf",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "snapshot",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "user",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "auth-client-required",
++          "default": null,
++          "type": "[390]"
++        },
++        {
++          "name": "key-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "server",
++          "default": null,
++          "type": "[391]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "272",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "mode",
++          "type": "392"
++        },
++        {
++          "name": "top-id",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "273",
++      "members": [
++        {
++          "name": "server",
++          "type": "317"
++        },
++        {
++          "name": "vdi",
++          "type": "str"
++        },
++        {
++          "name": "snap-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tag",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "274",
++      "members": [
++        {
++          "name": "server",
++          "type": "393"
++        },
++        {
++          "name": "path",
++          "type": "str"
++        },
++        {
++          "name": "user",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "host-key-check",
++          "default": null,
++          "type": "394"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "275",
++      "members": [
++        {
++          "name": "throttle-group",
++          "type": "str"
++        },
++        {
++          "name": "file",
++          "type": "377"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "276",
++      "members": [
++        {
++          "name": "dir",
++          "type": "str"
++        },
++        {
++          "name": "fat-type",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "floppy",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "label",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "rw",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "277",
++      "members": [
++        {
++          "name": "vdisk-id",
++          "type": "str"
++        },
++        {
++          "name": "server",
++          "type": "391"
++        },
++        {
++          "name": "tls-creds",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "278",
++      "tag": "driver",
++      "variants": [
++        {
++          "case": "file",
++          "type": "395"
++        },
++        {
++          "case": "gluster",
++          "type": "396"
++        },
++        {
++          "case": "luks",
++          "type": "397"
++        },
++        {
++          "case": "nfs",
++          "type": "398"
++        },
++        {
++          "case": "parallels",
++          "type": "399"
++        },
++        {
++          "case": "qcow",
++          "type": "400"
++        },
++        {
++          "case": "qcow2",
++          "type": "401"
++        },
++        {
++          "case": "qed",
++          "type": "402"
++        },
++        {
++          "case": "rbd",
++          "type": "403"
++        },
++        {
++          "case": "sheepdog",
++          "type": "404"
++        },
++        {
++          "case": "ssh",
++          "type": "405"
++        },
++        {
++          "case": "vdi",
++          "type": "406"
++        },
++        {
++          "case": "vhdx",
++          "type": "407"
++        },
++        {
++          "case": "vmdk",
++          "type": "408"
++        },
++        {
++          "case": "vpc",
++          "type": "409"
++        },
++        {
++          "case": "blkdebug",
++          "type": "0"
++        },
++        {
++          "case": "blklogwrites",
++          "type": "0"
++        },
++        {
++          "case": "blkreplay",
++          "type": "0"
++        },
++        {
++          "case": "blkverify",
++          "type": "0"
++        },
++        {
++          "case": "bochs",
++          "type": "0"
++        },
++        {
++          "case": "cloop",
++          "type": "0"
++        },
++        {
++          "case": "compress",
++          "type": "0"
++        },
++        {
++          "case": "copy-on-read",
++          "type": "0"
++        },
++        {
++          "case": "dmg",
++          "type": "0"
++        },
++        {
++          "case": "ftp",
++          "type": "0"
++        },
++        {
++          "case": "ftps",
++          "type": "0"
++        },
++        {
++          "case": "host_cdrom",
++          "type": "0"
++        },
++        {
++          "case": "host_device",
++          "type": "0"
++        },
++        {
++          "case": "http",
++          "type": "0"
++        },
++        {
++          "case": "https",
++          "type": "0"
++        },
++        {
++          "case": "iscsi",
++          "type": "0"
++        },
++        {
++          "case": "nbd",
++          "type": "0"
++        },
++        {
++          "case": "null-aio",
++          "type": "0"
++        },
++        {
++          "case": "null-co",
++          "type": "0"
++        },
++        {
++          "case": "nvme",
++          "type": "0"
++        },
++        {
++          "case": "quorum",
++          "type": "0"
++        },
++        {
++          "case": "raw",
++          "type": "0"
++        },
++        {
++          "case": "replication",
++          "type": "0"
++        },
++        {
++          "case": "throttle",
++          "type": "0"
++        },
++        {
++          "case": "vvfat",
++          "type": "0"
++        },
++        {
++          "case": "vxhs",
++          "type": "0"
++        }
++      ],
++      "members": [
++        {
++          "name": "driver",
++          "type": "246"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "279",
++      "meta-type": "enum",
++      "values": [
++        "retain",
++        "read-only",
++        "read-write"
++      ]
++    },
++    {
++      "name": "280",
++      "meta-type": "enum",
++      "values": [
++        "read",
++        "write"
++      ]
++    },
++    {
++      "name": "281",
++      "meta-type": "enum",
++      "values": [
++        "ignore",
++        "report",
++        "stop"
++      ]
++    },
++    {
++      "name": "282",
++      "meta-type": "enum",
++      "values": [
++        "commit",
++        "stream",
++        "mirror",
++        "backup",
++        "create"
++      ]
++    },
++    {
++      "name": "283",
++      "members": [
++        {
++          "type": "str"
++        },
++        {
++          "type": "null"
++        }
++      ],
++      "meta-type": "alternate"
++    },
++    {
++      "name": "284",
++      "meta-type": "enum",
++      "values": [
++        "utf8",
++        "base64"
++      ]
++    },
++    {
++      "name": "285",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "file",
++          "type": "411"
++        },
++        {
++          "case": "serial",
++          "type": "412"
++        },
++        {
++          "case": "parallel",
++          "type": "412"
++        },
++        {
++          "case": "pipe",
++          "type": "412"
++        },
++        {
++          "case": "socket",
++          "type": "413"
++        },
++        {
++          "case": "udp",
++          "type": "414"
++        },
++        {
++          "case": "pty",
++          "type": "415"
++        },
++        {
++          "case": "null",
++          "type": "415"
++        },
++        {
++          "case": "mux",
++          "type": "416"
++        },
++        {
++          "case": "msmouse",
++          "type": "415"
++        },
++        {
++          "case": "wctablet",
++          "type": "415"
++        },
++        {
++          "case": "braille",
++          "type": "415"
++        },
++        {
++          "case": "testdev",
++          "type": "415"
++        },
++        {
++          "case": "stdio",
++          "type": "417"
++        },
++        {
++          "case": "console",
++          "type": "415"
++        },
++        {
++          "case": "vc",
++          "type": "420"
++        },
++        {
++          "case": "ringbuf",
++          "type": "421"
++        },
++        {
++          "case": "memory",
++          "type": "421"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "410"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "286",
++      "meta-type": "enum",
++      "values": [
++        "elf",
++        "kdump-zlib",
++        "kdump-lzo",
++        "kdump-snappy",
++        "win-dmp"
++      ]
++    },
++    {
++      "name": "287",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "active",
++        "completed",
++        "failed"
++      ]
++    },
++    {
++      "name": "[286]",
++      "element-type": "286",
++      "meta-type": "array"
++    },
++    {
++      "name": "288",
++      "meta-type": "enum",
++      "values": [
++        "normal",
++        "none",
++        "all"
++      ]
++    },
++    {
++      "name": "[str]",
++      "element-type": "str",
++      "meta-type": "array"
++    },
++    {
++      "name": "289",
++      "meta-type": "enum",
++      "values": [
++        "half",
++        "full"
++      ]
++    },
++    {
++      "name": "290",
++      "meta-type": "enum",
++      "values": [
++        "off",
++        "on"
++      ]
++    },
++    {
++      "name": "291",
++      "members": [
++        {
++          "name": "priority",
++          "type": "int"
++        },
++        {
++          "name": "tbl-id",
++          "type": "int"
++        },
++        {
++          "name": "in-pport",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tunnel-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "vlan-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "eth-type",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "eth-src",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "eth-dst",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "ip-proto",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "ip-tos",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "ip-dst",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "292",
++      "members": [
++        {
++          "name": "in-pport",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tunnel-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "vlan-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "eth-src",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "eth-dst",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "ip-proto",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "ip-tos",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "293",
++      "members": [
++        {
++          "name": "goto-tbl",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "group-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "tunnel-lport",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "vlan-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "new-vlan-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "out-pport",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "294",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "passthrough",
++          "type": "423"
++        },
++        {
++          "case": "emulator",
++          "type": "424"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "422"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "299",
++      "meta-type": "enum",
++      "values": [
++        "ipv4",
++        "ipv6",
++        "unix",
++        "vsock",
++        "unknown"
++      ]
++    },
++    {
++      "name": "[300]",
++      "element-type": "300",
++      "meta-type": "array"
++    },
++    {
++      "name": "300",
++      "members": [
++        {
++          "name": "host",
++          "type": "str"
++        },
++        {
++          "name": "service",
++          "type": "str"
++        },
++        {
++          "name": "family",
++          "type": "299"
++        },
++        {
++          "name": "websocket",
++          "type": "bool"
++        },
++        {
++          "name": "x509_dname",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "sasl_username",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[301]",
++      "element-type": "301",
++      "meta-type": "array"
++    },
++    {
++      "name": "301",
++      "members": [
++        {
++          "name": "host",
++          "type": "str"
++        },
++        {
++          "name": "service",
++          "type": "str"
++        },
++        {
++          "name": "family",
++          "type": "299"
++        },
++        {
++          "name": "websocket",
++          "type": "bool"
++        },
++        {
++          "name": "auth",
++          "type": "302"
++        },
++        {
++          "name": "vencrypt",
++          "default": null,
++          "type": "303"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "302",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "vnc",
++        "ra2",
++        "ra2ne",
++        "tight",
++        "ultra",
++        "tls",
++        "vencrypt",
++        "sasl"
++      ]
++    },
++    {
++      "name": "303",
++      "meta-type": "enum",
++      "values": [
++        "plain",
++        "tls-none",
++        "x509-none",
++        "tls-vnc",
++        "x509-vnc",
++        "tls-plain",
++        "x509-plain",
++        "tls-sasl",
++        "x509-sasl"
++      ]
++    },
++    {
++      "name": "304",
++      "members": [
++        {
++          "name": "host",
++          "type": "str"
++        },
++        {
++          "name": "service",
++          "type": "str"
++        },
++        {
++          "name": "family",
++          "type": "299"
++        },
++        {
++          "name": "websocket",
++          "type": "bool"
++        },
++        {
++          "name": "auth",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "305",
++      "members": [
++        {
++          "name": "host",
++          "type": "str"
++        },
++        {
++          "name": "service",
++          "type": "str"
++        },
++        {
++          "name": "family",
++          "type": "299"
++        },
++        {
++          "name": "websocket",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[306]",
++      "element-type": "306",
++      "meta-type": "array"
++    },
++    {
++      "name": "306",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "number",
++          "type": "426"
++        },
++        {
++          "case": "qcode",
++          "type": "427"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "425"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[307]",
++      "element-type": "307",
++      "meta-type": "array"
++    },
++    {
++      "name": "307",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "key",
++          "type": "429"
++        },
++        {
++          "case": "btn",
++          "type": "430"
++        },
++        {
++          "case": "rel",
++          "type": "431"
++        },
++        {
++          "case": "abs",
++          "type": "431"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "428"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "308",
++      "meta-type": "enum",
++      "values": [
++        "default",
++        "none",
++        "gtk",
++        "sdl",
++        "egl-headless",
++        "curses",
++        "cocoa",
++        "spice-app"
++      ]
++    },
++    {
++      "name": "309",
++      "meta-type": "enum",
++      "values": [
++        "off",
++        "on",
++        "core",
++        "es"
++      ]
++    },
++    {
++      "name": "310",
++      "members": [
++        {
++          "name": "grab-on-hover",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "zoom-to-fit",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "311",
++      "members": [
++        {
++          "name": "charset",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "312",
++      "members": [
++        {
++          "name": "rendernode",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "313",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "setup",
++        "cancelling",
++        "cancelled",
++        "active",
++        "postcopy-active",
++        "postcopy-paused",
++        "postcopy-recover",
++        "completed",
++        "failed",
++        "colo",
++        "pre-switchover",
++        "device",
++        "wait-unplug"
++      ]
++    },
++    {
++      "name": "314",
++      "members": [
++        {
++          "name": "transferred",
++          "type": "int"
++        },
++        {
++          "name": "remaining",
++          "type": "int"
++        },
++        {
++          "name": "total",
++          "type": "int"
++        },
++        {
++          "name": "duplicate",
++          "type": "int"
++        },
++        {
++          "name": "skipped",
++          "type": "int"
++        },
++        {
++          "name": "normal",
++          "type": "int"
++        },
++        {
++          "name": "normal-bytes",
++          "type": "int"
++        },
++        {
++          "name": "dirty-pages-rate",
++          "type": "int"
++        },
++        {
++          "name": "mbps",
++          "type": "number"
++        },
++        {
++          "name": "dirty-sync-count",
++          "type": "int"
++        },
++        {
++          "name": "postcopy-requests",
++          "type": "int"
++        },
++        {
++          "name": "page-size",
++          "type": "int"
++        },
++        {
++          "name": "multifd-bytes",
++          "type": "int"
++        },
++        {
++          "name": "pages-per-second",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "315",
++      "members": [
++        {
++          "name": "cache-size",
++          "type": "int"
++        },
++        {
++          "name": "bytes",
++          "type": "int"
++        },
++        {
++          "name": "pages",
++          "type": "int"
++        },
++        {
++          "name": "cache-miss",
++          "type": "int"
++        },
++        {
++          "name": "cache-miss-rate",
++          "type": "number"
++        },
++        {
++          "name": "overflow",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "316",
++      "members": [
++        {
++          "name": "pages",
++          "type": "int"
++        },
++        {
++          "name": "busy",
++          "type": "int"
++        },
++        {
++          "name": "busy-rate",
++          "type": "number"
++        },
++        {
++          "name": "compressed-size",
++          "type": "int"
++        },
++        {
++          "name": "compression-rate",
++          "type": "number"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[317]",
++      "element-type": "317",
++      "meta-type": "array"
++    },
++    {
++      "name": "317",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "inet",
++          "type": "393"
++        },
++        {
++          "case": "unix",
++          "type": "433"
++        },
++        {
++          "case": "vsock",
++          "type": "434"
++        },
++        {
++          "case": "fd",
++          "type": "435"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "432"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "318",
++      "meta-type": "enum",
++      "values": [
++        "xbzrle",
++        "rdma-pin-all",
++        "auto-converge",
++        "zero-blocks",
++        "compress",
++        "events",
++        "postcopy-ram",
++        "x-colo",
++        "release-ram",
++        "block",
++        "return-path",
++        "pause-before-switchover",
++        "multifd",
++        "dirty-bitmaps",
++        "postcopy-blocktime",
++        "late-block-activate",
++        "x-ignore-shared",
++        "validate-uuid"
++      ]
++    },
++    {
++      "name": "319",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "primary",
++        "secondary"
++      ]
++    },
++    {
++      "name": "320",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "request",
++        "error",
++        "processing"
++      ]
++    },
++    {
++      "name": "number",
++      "json-type": "number",
++      "meta-type": "builtin"
++    },
++    {
++      "name": "[321]",
++      "element-type": "321",
++      "meta-type": "array"
++    },
++    {
++      "name": "321",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "abort",
++          "type": "437"
++        },
++        {
++          "case": "block-dirty-bitmap-add",
++          "type": "438"
++        },
++        {
++          "case": "block-dirty-bitmap-remove",
++          "type": "439"
++        },
++        {
++          "case": "block-dirty-bitmap-clear",
++          "type": "439"
++        },
++        {
++          "case": "block-dirty-bitmap-enable",
++          "type": "439"
++        },
++        {
++          "case": "block-dirty-bitmap-disable",
++          "type": "439"
++        },
++        {
++          "case": "block-dirty-bitmap-merge",
++          "type": "440"
++        },
++        {
++          "case": "blockdev-backup",
++          "type": "441"
++        },
++        {
++          "case": "blockdev-snapshot",
++          "type": "442"
++        },
++        {
++          "case": "blockdev-snapshot-internal-sync",
++          "type": "443"
++        },
++        {
++          "case": "blockdev-snapshot-sync",
++          "type": "444"
++        },
++        {
++          "case": "drive-backup",
++          "type": "445"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "436"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "322",
++      "members": [
++        {
++          "name": "completion-mode",
++          "default": null,
++          "type": "446"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "323",
++      "meta-type": "enum",
++      "values": [
++        "unavailable",
++        "disabled",
++        "enabled"
++      ]
++    },
++    {
++      "name": "324",
++      "meta-type": "enum",
++      "values": [
++        "builtin",
++        "enum",
++        "array",
++        "object",
++        "alternate",
++        "command",
++        "event"
++      ]
++    },
++    {
++      "name": "325",
++      "members": [
++        {
++          "name": "json-type",
++          "type": "447"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "326",
++      "members": [
++        {
++          "name": "values",
++          "type": "[str]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "327",
++      "members": [
++        {
++          "name": "element-type",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "328",
++      "members": [
++        {
++          "name": "members",
++          "type": "[448]"
++        },
++        {
++          "name": "tag",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "variants",
++          "default": null,
++          "type": "[449]"
++        },
++        {
++          "name": "features",
++          "default": null,
++          "type": "[str]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "329",
++      "members": [
++        {
++          "name": "members",
++          "type": "[450]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "330",
++      "members": [
++        {
++          "name": "arg-type",
++          "type": "str"
++        },
++        {
++          "name": "ret-type",
++          "type": "str"
++        },
++        {
++          "name": "allow-oob",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "features",
++          "default": null,
++          "type": "[str]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "331",
++      "members": [
++        {
++          "name": "arg-type",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "332",
++      "members": [
++        {
++          "name": "node-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "socket-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "die-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "core-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "thread-id",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "333",
++      "meta-type": "enum",
++      "values": [
++        "x86",
++        "sparc",
++        "ppc",
++        "mips",
++        "tricore",
++        "s390",
++        "riscv",
++        "other"
++      ]
++    },
++    {
++      "name": "334",
++      "members": [
++        {
++          "name": "pc",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "335",
++      "members": [
++        {
++          "name": "pc",
++          "type": "int"
++        },
++        {
++          "name": "npc",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "336",
++      "members": [
++        {
++          "name": "nip",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "337",
++      "members": [
++        {
++          "name": "PC",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "338",
++      "members": [
++        {
++          "name": "PC",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "339",
++      "members": [
++        {
++          "name": "cpu-state",
++          "type": "451"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "340",
++      "members": [
++        {
++          "name": "pc",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "341",
++      "meta-type": "enum",
++      "values": [
++        "aarch64",
++        "alpha",
++        "arm",
++        "cris",
++        "hppa",
++        "i386",
++        "lm32",
++        "m68k",
++        "microblaze",
++        "microblazeel",
++        "mips",
++        "mips64",
++        "mips64el",
++        "mipsel",
++        "moxie",
++        "nios2",
++        "or1k",
++        "ppc",
++        "ppc64",
++        "riscv32",
++        "riscv64",
++        "s390x",
++        "sh4",
++        "sh4eb",
++        "sparc",
++        "sparc64",
++        "tricore",
++        "unicore32",
++        "x86_64",
++        "xtensa",
++        "xtensaeb"
++      ]
++    },
++    {
++      "name": "342",
++      "meta-type": "enum",
++      "values": [
++        "default",
++        "preferred",
++        "bind",
++        "interleave"
++      ]
++    },
++    {
++      "name": "343",
++      "meta-type": "enum",
++      "values": [
++        "node",
++        "dist",
++        "cpu",
++        "hmat-lb",
++        "hmat-cache"
++      ]
++    },
++    {
++      "name": "344",
++      "members": [
++        {
++          "name": "nodeid",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cpus",
++          "default": null,
++          "type": "[int]"
++        },
++        {
++          "name": "mem",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "memdev",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "initiator",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "345",
++      "members": [
++        {
++          "name": "src",
++          "type": "int"
++        },
++        {
++          "name": "dst",
++          "type": "int"
++        },
++        {
++          "name": "val",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "346",
++      "members": [
++        {
++          "name": "node-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "socket-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "die-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "core-id",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "thread-id",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "347",
++      "members": [
++        {
++          "name": "initiator",
++          "type": "int"
++        },
++        {
++          "name": "target",
++          "type": "int"
++        },
++        {
++          "name": "hierarchy",
++          "type": "452"
++        },
++        {
++          "name": "data-type",
++          "type": "453"
++        },
++        {
++          "name": "latency",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "bandwidth",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "348",
++      "members": [
++        {
++          "name": "node-id",
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "level",
++          "type": "int"
++        },
++        {
++          "name": "associativity",
++          "type": "454"
++        },
++        {
++          "name": "policy",
++          "type": "455"
++        },
++        {
++          "name": "line",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "349",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "props",
++          "default": null,
++          "type": "any"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "350",
++      "meta-type": "enum",
++      "values": [
++        "incompatible",
++        "identical",
++        "superset",
++        "subset"
++      ]
++    },
++    {
++      "name": "351",
++      "meta-type": "enum",
++      "values": [
++        "static",
++        "full"
++      ]
++    },
++    {
++      "name": "[352]",
++      "element-type": "352",
++      "meta-type": "array"
++    },
++    {
++      "name": "352",
++      "meta-type": "enum",
++      "values": [
++        "oob"
++      ]
++    },
++    {
++      "name": "353",
++      "members": [
++        {
++          "name": "major",
++          "type": "int"
++        },
++        {
++          "name": "minor",
++          "type": "int"
++        },
++        {
++          "name": "micro",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[354]",
++      "element-type": "354",
++      "meta-type": "array"
++    },
++    {
++      "name": "354",
++      "members": [
++        {
++          "name": "bus",
++          "type": "int"
++        },
++        {
++          "name": "slot",
++          "type": "int"
++        },
++        {
++          "name": "function",
++          "type": "int"
++        },
++        {
++          "name": "class_info",
++          "type": "456"
++        },
++        {
++          "name": "id",
++          "type": "457"
++        },
++        {
++          "name": "irq",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "qdev_id",
++          "type": "str"
++        },
++        {
++          "name": "pci_bridge",
++          "default": null,
++          "type": "458"
++        },
++        {
++          "name": "regions",
++          "type": "[459]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[355]",
++      "element-type": "355",
++      "meta-type": "array"
++    },
++    {
++      "name": "355",
++      "members": [
++        {
++          "name": "fd",
++          "type": "int"
++        },
++        {
++          "name": "opaque",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[356]",
++      "element-type": "356",
++      "meta-type": "array"
++    },
++    {
++      "name": "356",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "type",
++          "type": "460"
++        },
++        {
++          "name": "help",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "default",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "357",
++      "meta-type": "enum",
++      "values": [
++        "dimm",
++        "nvdimm",
++        "virtio-pmem"
++      ]
++    },
++    {
++      "name": "358",
++      "members": [
++        {
++          "name": "data",
++          "type": "461"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "359",
++      "members": [
++        {
++          "name": "data",
++          "type": "462"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "360",
++      "meta-type": "enum",
++      "values": [
++        "DIMM",
++        "CPU"
++      ]
++    },
++    {
++      "name": "362",
++      "meta-type": "enum",
++      "values": [
++        "hyper-v",
++        "s390"
++      ]
++    },
++    {
++      "name": "363",
++      "members": [
++        {
++          "name": "arg1",
++          "type": "int"
++        },
++        {
++          "name": "arg2",
++          "type": "int"
++        },
++        {
++          "name": "arg3",
++          "type": "int"
++        },
++        {
++          "name": "arg4",
++          "type": "int"
++        },
++        {
++          "name": "arg5",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "364",
++      "members": [
++        {
++          "name": "core",
++          "type": "int"
++        },
++        {
++          "name": "psw-mask",
++          "type": "int"
++        },
++        {
++          "name": "psw-addr",
++          "type": "int"
++        },
++        {
++          "name": "reason",
++          "type": "463"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "365",
++      "meta-type": "enum",
++      "values": [
++        "inet",
++        "unix",
++        "vsock",
++        "fd"
++      ]
++    },
++    {
++      "name": "366",
++      "members": [
++        {
++          "name": "data",
++          "type": "393"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "367",
++      "members": [
++        {
++          "name": "data",
++          "type": "433"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "368",
++      "members": [
++        {
++          "name": "data",
++          "type": "434"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "369",
++      "members": [
++        {
++          "name": "data",
++          "type": "435"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "370",
++      "meta-type": "enum",
++      "values": [
++        "active",
++        "disabled",
++        "frozen",
++        "locked",
++        "inconsistent"
++      ]
++    },
++    {
++      "name": "[371]",
++      "element-type": "371",
++      "meta-type": "array"
++    },
++    {
++      "name": "371",
++      "members": [
++        {
++          "name": "interval_length",
++          "type": "int"
++        },
++        {
++          "name": "min_rd_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "max_rd_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "avg_rd_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "min_wr_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "max_wr_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "avg_wr_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "min_flush_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "max_flush_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "avg_flush_latency_ns",
++          "type": "int"
++        },
++        {
++          "name": "avg_rd_queue_depth",
++          "type": "number"
++        },
++        {
++          "name": "avg_wr_queue_depth",
++          "type": "number"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "372",
++      "members": [
++        {
++          "name": "boundaries",
++          "type": "[int]"
++        },
++        {
++          "name": "bins",
++          "type": "[int]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "373",
++      "members": [
++        {
++          "name": "discard-nb-ok",
++          "type": "int"
++        },
++        {
++          "name": "discard-nb-failed",
++          "type": "int"
++        },
++        {
++          "name": "discard-bytes-ok",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[11]",
++      "element-type": "11",
++      "meta-type": "array"
++    },
++    {
++      "name": "374",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "qcow2",
++          "type": "465"
++        },
++        {
++          "case": "vmdk",
++          "type": "466"
++        },
++        {
++          "case": "luks",
++          "type": "467"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "464"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "375",
++      "meta-type": "enum",
++      "values": [
++        "block-backend",
++        "block-job",
++        "block-driver"
++      ]
++    },
++    {
++      "name": "[376]",
++      "element-type": "376",
++      "meta-type": "array"
++    },
++    {
++      "name": "376",
++      "meta-type": "enum",
++      "values": [
++        "consistent-read",
++        "write",
++        "write-unchanged",
++        "resize",
++        "graph-mod"
++      ]
++    },
++    {
++      "name": "377",
++      "members": [
++        {
++          "type": "50"
++        },
++        {
++          "type": "str"
++        }
++      ],
++      "meta-type": "alternate"
++    },
++    {
++      "name": "[378]",
++      "element-type": "378",
++      "meta-type": "array"
++    },
++    {
++      "name": "378",
++      "members": [
++        {
++          "name": "event",
++          "type": "468"
++        },
++        {
++          "name": "state",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "iotype",
++          "default": null,
++          "type": "469"
++        },
++        {
++          "name": "errno",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "sector",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "once",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "immediately",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[379]",
++      "element-type": "379",
++      "meta-type": "array"
++    },
++    {
++      "name": "379",
++      "members": [
++        {
++          "name": "event",
++          "type": "468"
++        },
++        {
++          "name": "state",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "new_state",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "380",
++      "meta-type": "enum",
++      "values": [
++        "auto",
++        "on",
++        "off"
++      ]
++    },
++    {
++      "name": "381",
++      "meta-type": "enum",
++      "values": [
++        "threads",
++        "native"
++      ]
++    },
++    {
++      "name": "382",
++      "meta-type": "enum",
++      "values": [
++        "tcp",
++        "iser"
++      ]
++    },
++    {
++      "name": "383",
++      "meta-type": "enum",
++      "values": [
++        "crc32c",
++        "none",
++        "crc32c-none",
++        "none-crc32c"
++      ]
++    },
++    {
++      "name": "384",
++      "members": [
++        {
++          "name": "type",
++          "type": "470"
++        },
++        {
++          "name": "host",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "385",
++      "members": [
++        {
++          "type": "50"
++        },
++        {
++          "type": "str"
++        },
++        {
++          "type": "null"
++        }
++      ],
++      "meta-type": "alternate"
++    },
++    {
++      "name": "386",
++      "members": [
++        {
++          "type": "471"
++        },
++        {
++          "type": "472"
++        }
++      ],
++      "meta-type": "alternate"
++    },
++    {
++      "name": "387",
++      "tag": "format",
++      "variants": [
++        {
++          "case": "aes",
++          "type": "474"
++        },
++        {
++          "case": "luks",
++          "type": "475"
++        }
++      ],
++      "members": [
++        {
++          "name": "format",
++          "type": "473"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "388",
++      "tag": "format",
++      "variants": [
++        {
++          "case": "aes",
++          "type": "474"
++        }
++      ],
++      "members": [
++        {
++          "name": "format",
++          "type": "476"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[377]",
++      "element-type": "377",
++      "meta-type": "array"
++    },
++    {
++      "name": "389",
++      "meta-type": "enum",
++      "values": [
++        "quorum",
++        "fifo"
++      ]
++    },
++    {
++      "name": "[390]",
++      "element-type": "390",
++      "meta-type": "array"
++    },
++    {
++      "name": "390",
++      "meta-type": "enum",
++      "values": [
++        "cephx",
++        "none"
++      ]
++    },
++    {
++      "name": "[391]",
++      "element-type": "391",
++      "meta-type": "array"
++    },
++    {
++      "name": "391",
++      "members": [
++        {
++          "name": "host",
++          "type": "str"
++        },
++        {
++          "name": "port",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "392",
++      "meta-type": "enum",
++      "values": [
++        "primary",
++        "secondary"
++      ]
++    },
++    {
++      "name": "393",
++      "members": [
++        {
++          "name": "host",
++          "type": "str"
++        },
++        {
++          "name": "port",
++          "type": "str"
++        },
++        {
++          "name": "numeric",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "to",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "ipv4",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "ipv6",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "keep-alive",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "394",
++      "tag": "mode",
++      "variants": [
++        {
++          "case": "hash",
++          "type": "478"
++        },
++        {
++          "case": "none",
++          "type": "0"
++        },
++        {
++          "case": "known_hosts",
++          "type": "0"
++        }
++      ],
++      "members": [
++        {
++          "name": "mode",
++          "type": "477"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "395",
++      "members": [
++        {
++          "name": "filename",
++          "type": "str"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "preallocation",
++          "default": null,
++          "type": "479"
++        },
++        {
++          "name": "nocow",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "396",
++      "members": [
++        {
++          "name": "location",
++          "type": "257"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "preallocation",
++          "default": null,
++          "type": "479"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "397",
++      "members": [
++        {
++          "name": "key-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "cipher-alg",
++          "default": null,
++          "type": "480"
++        },
++        {
++          "name": "cipher-mode",
++          "default": null,
++          "type": "481"
++        },
++        {
++          "name": "ivgen-alg",
++          "default": null,
++          "type": "482"
++        },
++        {
++          "name": "ivgen-hash-alg",
++          "default": null,
++          "type": "483"
++        },
++        {
++          "name": "hash-alg",
++          "default": null,
++          "type": "483"
++        },
++        {
++          "name": "iter-time",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "preallocation",
++          "default": null,
++          "type": "479"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "398",
++      "members": [
++        {
++          "name": "location",
++          "type": "263"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "399",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "cluster-size",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "400",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "backing-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "encrypt",
++          "default": null,
++          "type": "484"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "401",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "data-file",
++          "default": null,
++          "type": "377"
++        },
++        {
++          "name": "data-file-raw",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "version",
++          "default": null,
++          "type": "485"
++        },
++        {
++          "name": "backing-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "backing-fmt",
++          "default": null,
++          "type": "246"
++        },
++        {
++          "name": "encrypt",
++          "default": null,
++          "type": "484"
++        },
++        {
++          "name": "cluster-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "preallocation",
++          "default": null,
++          "type": "479"
++        },
++        {
++          "name": "lazy-refcounts",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "refcount-bits",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "402",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "backing-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "backing-fmt",
++          "default": null,
++          "type": "246"
++        },
++        {
++          "name": "cluster-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "table-size",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "403",
++      "members": [
++        {
++          "name": "location",
++          "type": "271"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "cluster-size",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "404",
++      "members": [
++        {
++          "name": "location",
++          "type": "273"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "backing-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "preallocation",
++          "default": null,
++          "type": "479"
++        },
++        {
++          "name": "redundancy",
++          "default": null,
++          "type": "486"
++        },
++        {
++          "name": "object-size",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "405",
++      "members": [
++        {
++          "name": "location",
++          "type": "274"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "406",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "preallocation",
++          "default": null,
++          "type": "479"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "407",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "log-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "block-size",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "subformat",
++          "default": null,
++          "type": "487"
++        },
++        {
++          "name": "block-state-zero",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "408",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "extents",
++          "default": null,
++          "type": "[377]"
++        },
++        {
++          "name": "subformat",
++          "default": null,
++          "type": "488"
++        },
++        {
++          "name": "backing-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "adapter-type",
++          "default": null,
++          "type": "489"
++        },
++        {
++          "name": "hwversion",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "zeroed-grain",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "409",
++      "members": [
++        {
++          "name": "file",
++          "type": "377"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "subformat",
++          "default": null,
++          "type": "490"
++        },
++        {
++          "name": "force-size",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "null",
++      "json-type": "null",
++      "meta-type": "builtin"
++    },
++    {
++      "name": "410",
++      "meta-type": "enum",
++      "values": [
++        "file",
++        "serial",
++        "parallel",
++        "pipe",
++        "socket",
++        "udp",
++        "pty",
++        "null",
++        "mux",
++        "msmouse",
++        "wctablet",
++        "braille",
++        "testdev",
++        "stdio",
++        "console",
++        "vc",
++        "ringbuf",
++        "memory"
++      ]
++    },
++    {
++      "name": "411",
++      "members": [
++        {
++          "name": "data",
++          "type": "491"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "412",
++      "members": [
++        {
++          "name": "data",
++          "type": "492"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "413",
++      "members": [
++        {
++          "name": "data",
++          "type": "493"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "414",
++      "members": [
++        {
++          "name": "data",
++          "type": "494"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "415",
++      "members": [
++        {
++          "name": "data",
++          "type": "495"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "416",
++      "members": [
++        {
++          "name": "data",
++          "type": "496"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "417",
++      "members": [
++        {
++          "name": "data",
++          "type": "497"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "420",
++      "members": [
++        {
++          "name": "data",
++          "type": "500"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "421",
++      "members": [
++        {
++          "name": "data",
++          "type": "501"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "422",
++      "meta-type": "enum",
++      "values": [
++        "passthrough",
++        "emulator"
++      ]
++    },
++    {
++      "name": "423",
++      "members": [
++        {
++          "name": "data",
++          "type": "502"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "424",
++      "members": [
++        {
++          "name": "data",
++          "type": "503"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "425",
++      "meta-type": "enum",
++      "values": [
++        "number",
++        "qcode"
++      ]
++    },
++    {
++      "name": "426",
++      "members": [
++        {
++          "name": "data",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "427",
++      "members": [
++        {
++          "name": "data",
++          "type": "504"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "428",
++      "meta-type": "enum",
++      "values": [
++        "key",
++        "btn",
++        "rel",
++        "abs"
++      ]
++    },
++    {
++      "name": "429",
++      "members": [
++        {
++          "name": "data",
++          "type": "505"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "430",
++      "members": [
++        {
++          "name": "data",
++          "type": "506"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "431",
++      "members": [
++        {
++          "name": "data",
++          "type": "507"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "432",
++      "meta-type": "enum",
++      "values": [
++        "inet",
++        "unix",
++        "vsock",
++        "fd"
++      ]
++    },
++    {
++      "name": "433",
++      "members": [
++        {
++          "name": "path",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "434",
++      "members": [
++        {
++          "name": "cid",
++          "type": "str"
++        },
++        {
++          "name": "port",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "435",
++      "members": [
++        {
++          "name": "str",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "436",
++      "meta-type": "enum",
++      "values": [
++        "abort",
++        "block-dirty-bitmap-add",
++        "block-dirty-bitmap-remove",
++        "block-dirty-bitmap-clear",
++        "block-dirty-bitmap-enable",
++        "block-dirty-bitmap-disable",
++        "block-dirty-bitmap-merge",
++        "blockdev-backup",
++        "blockdev-snapshot",
++        "blockdev-snapshot-internal-sync",
++        "blockdev-snapshot-sync",
++        "drive-backup"
++      ]
++    },
++    {
++      "name": "437",
++      "members": [
++        {
++          "name": "data",
++          "type": "508"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "438",
++      "members": [
++        {
++          "name": "data",
++          "type": "36"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "439",
++      "members": [
++        {
++          "name": "data",
++          "type": "37"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "440",
++      "members": [
++        {
++          "name": "data",
++          "type": "38"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "441",
++      "members": [
++        {
++          "name": "data",
++          "type": "32"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "442",
++      "members": [
++        {
++          "name": "data",
++          "type": "28"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "443",
++      "members": [
++        {
++          "name": "data",
++          "type": "9"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "444",
++      "members": [
++        {
++          "name": "data",
++          "type": "27"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "445",
++      "members": [
++        {
++          "name": "data",
++          "type": "31"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "446",
++      "meta-type": "enum",
++      "values": [
++        "individual",
++        "grouped"
++      ]
++    },
++    {
++      "name": "447",
++      "meta-type": "enum",
++      "values": [
++        "string",
++        "number",
++        "int",
++        "boolean",
++        "null",
++        "object",
++        "array",
++        "value"
++      ]
++    },
++    {
++      "name": "[448]",
++      "element-type": "448",
++      "meta-type": "array"
++    },
++    {
++      "name": "448",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "type",
++          "type": "str"
++        },
++        {
++          "name": "default",
++          "default": null,
++          "type": "any"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[449]",
++      "element-type": "449",
++      "meta-type": "array"
++    },
++    {
++      "name": "449",
++      "members": [
++        {
++          "name": "case",
++          "type": "str"
++        },
++        {
++          "name": "type",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[450]",
++      "element-type": "450",
++      "meta-type": "array"
++    },
++    {
++      "name": "450",
++      "members": [
++        {
++          "name": "type",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "451",
++      "meta-type": "enum",
++      "values": [
++        "uninitialized",
++        "stopped",
++        "check-stop",
++        "operating",
++        "load"
++      ]
++    },
++    {
++      "name": "452",
++      "meta-type": "enum",
++      "values": [
++        "memory",
++        "first-level",
++        "second-level",
++        "third-level"
++      ]
++    },
++    {
++      "name": "453",
++      "meta-type": "enum",
++      "values": [
++        "access-latency",
++        "read-latency",
++        "write-latency",
++        "access-bandwidth",
++        "read-bandwidth",
++        "write-bandwidth"
++      ]
++    },
++    {
++      "name": "454",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "direct",
++        "complex"
++      ]
++    },
++    {
++      "name": "455",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "write-back",
++        "write-through"
++      ]
++    },
++    {
++      "name": "456",
++      "members": [
++        {
++          "name": "desc",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "class",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "457",
++      "members": [
++        {
++          "name": "device",
++          "type": "int"
++        },
++        {
++          "name": "vendor",
++          "type": "int"
++        },
++        {
++          "name": "subsystem",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "subsystem-vendor",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "458",
++      "members": [
++        {
++          "name": "bus",
++          "type": "509"
++        },
++        {
++          "name": "devices",
++          "default": null,
++          "type": "[354]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[459]",
++      "element-type": "459",
++      "meta-type": "array"
++    },
++    {
++      "name": "459",
++      "members": [
++        {
++          "name": "bar",
++          "type": "int"
++        },
++        {
++          "name": "type",
++          "type": "str"
++        },
++        {
++          "name": "address",
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "prefetch",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "mem_type_64",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "460",
++      "meta-type": "enum",
++      "values": [
++        "string",
++        "boolean",
++        "number",
++        "size"
++      ]
++    },
++    {
++      "name": "461",
++      "members": [
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "addr",
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "slot",
++          "type": "int"
++        },
++        {
++          "name": "node",
++          "type": "int"
++        },
++        {
++          "name": "memdev",
++          "type": "str"
++        },
++        {
++          "name": "hotplugged",
++          "type": "bool"
++        },
++        {
++          "name": "hotpluggable",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "462",
++      "members": [
++        {
++          "name": "id",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "memaddr",
++          "type": "int"
++        },
++        {
++          "name": "size",
++          "type": "int"
++        },
++        {
++          "name": "memdev",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "463",
++      "meta-type": "enum",
++      "values": [
++        "unknown",
++        "disabled-wait",
++        "extint-loop",
++        "pgmint-loop",
++        "opint-loop"
++      ]
++    },
++    {
++      "name": "464",
++      "meta-type": "enum",
++      "values": [
++        "qcow2",
++        "vmdk",
++        "luks"
++      ]
++    },
++    {
++      "name": "465",
++      "members": [
++        {
++          "name": "data",
++          "type": "510"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "466",
++      "members": [
++        {
++          "name": "data",
++          "type": "511"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "467",
++      "members": [
++        {
++          "name": "data",
++          "type": "512"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "468",
++      "meta-type": "enum",
++      "values": [
++        "l1_update",
++        "l1_grow_alloc_table",
++        "l1_grow_write_table",
++        "l1_grow_activate_table",
++        "l2_load",
++        "l2_update",
++        "l2_update_compressed",
++        "l2_alloc_cow_read",
++        "l2_alloc_write",
++        "read_aio",
++        "read_backing_aio",
++        "read_compressed",
++        "write_aio",
++        "write_compressed",
++        "vmstate_load",
++        "vmstate_save",
++        "cow_read",
++        "cow_write",
++        "reftable_load",
++        "reftable_grow",
++        "reftable_update",
++        "refblock_load",
++        "refblock_update",
++        "refblock_update_part",
++        "refblock_alloc",
++        "refblock_alloc_hookup",
++        "refblock_alloc_write",
++        "refblock_alloc_write_blocks",
++        "refblock_alloc_write_table",
++        "refblock_alloc_switch_table",
++        "cluster_alloc",
++        "cluster_alloc_bytes",
++        "cluster_free",
++        "flush_to_os",
++        "flush_to_disk",
++        "pwritev_rmw_head",
++        "pwritev_rmw_after_head",
++        "pwritev_rmw_tail",
++        "pwritev_rmw_after_tail",
++        "pwritev",
++        "pwritev_zero",
++        "pwritev_done",
++        "empty_image_prepare",
++        "l1_shrink_write_table",
++        "l1_shrink_free_l2_clusters",
++        "cor_write",
++        "cluster_alloc_space",
++        "none"
++      ]
++    },
++    {
++      "name": "469",
++      "meta-type": "enum",
++      "values": [
++        "read",
++        "write",
++        "write-zeroes",
++        "discard",
++        "flush",
++        "block-status"
++      ]
++    },
++    {
++      "name": "470",
++      "meta-type": "enum",
++      "values": [
++        "inet"
++      ]
++    },
++    {
++      "name": "471",
++      "members": [
++        {
++          "name": "template",
++          "default": null,
++          "type": "472"
++        },
++        {
++          "name": "main-header",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "active-l1",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "active-l2",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "refcount-table",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "refcount-block",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "snapshot-table",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "inactive-l1",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "inactive-l2",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "bitmap-directory",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "472",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "constant",
++        "cached",
++        "all"
++      ]
++    },
++    {
++      "name": "473",
++      "meta-type": "enum",
++      "values": [
++        "aes",
++        "luks"
++      ]
++    },
++    {
++      "name": "474",
++      "members": [
++        {
++          "name": "key-secret",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "475",
++      "members": [
++        {
++          "name": "key-secret",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "476",
++      "meta-type": "enum",
++      "values": [
++        "aes"
++      ]
++    },
++    {
++      "name": "477",
++      "meta-type": "enum",
++      "values": [
++        "none",
++        "hash",
++        "known_hosts"
++      ]
++    },
++    {
++      "name": "478",
++      "members": [
++        {
++          "name": "type",
++          "type": "513"
++        },
++        {
++          "name": "hash",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "479",
++      "meta-type": "enum",
++      "values": [
++        "off",
++        "metadata",
++        "falloc",
++        "full"
++      ]
++    },
++    {
++      "name": "480",
++      "meta-type": "enum",
++      "values": [
++        "aes-128",
++        "aes-192",
++        "aes-256",
++        "des-rfb",
++        "3des",
++        "cast5-128",
++        "serpent-128",
++        "serpent-192",
++        "serpent-256",
++        "twofish-128",
++        "twofish-192",
++        "twofish-256"
++      ]
++    },
++    {
++      "name": "481",
++      "meta-type": "enum",
++      "values": [
++        "ecb",
++        "cbc",
++        "xts",
++        "ctr"
++      ]
++    },
++    {
++      "name": "482",
++      "meta-type": "enum",
++      "values": [
++        "plain",
++        "plain64",
++        "essiv"
++      ]
++    },
++    {
++      "name": "483",
++      "meta-type": "enum",
++      "values": [
++        "md5",
++        "sha1",
++        "sha224",
++        "sha256",
++        "sha384",
++        "sha512",
++        "ripemd160"
++      ]
++    },
++    {
++      "name": "484",
++      "tag": "format",
++      "variants": [
++        {
++          "case": "qcow",
++          "type": "474"
++        },
++        {
++          "case": "luks",
++          "type": "515"
++        }
++      ],
++      "members": [
++        {
++          "name": "format",
++          "type": "514"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "485",
++      "meta-type": "enum",
++      "values": [
++        "v2",
++        "v3"
++      ]
++    },
++    {
++      "name": "486",
++      "tag": "type",
++      "variants": [
++        {
++          "case": "full",
++          "type": "517"
++        },
++        {
++          "case": "erasure-coded",
++          "type": "518"
++        }
++      ],
++      "members": [
++        {
++          "name": "type",
++          "type": "516"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "487",
++      "meta-type": "enum",
++      "values": [
++        "dynamic",
++        "fixed"
++      ]
++    },
++    {
++      "name": "488",
++      "meta-type": "enum",
++      "values": [
++        "monolithicSparse",
++        "monolithicFlat",
++        "twoGbMaxExtentSparse",
++        "twoGbMaxExtentFlat",
++        "streamOptimized"
++      ]
++    },
++    {
++      "name": "489",
++      "meta-type": "enum",
++      "values": [
++        "ide",
++        "buslogic",
++        "lsilogic",
++        "legacyESX"
++      ]
++    },
++    {
++      "name": "490",
++      "meta-type": "enum",
++      "values": [
++        "dynamic",
++        "fixed"
++      ]
++    },
++    {
++      "name": "491",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "in",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "out",
++          "type": "str"
++        },
++        {
++          "name": "append",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "492",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "device",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "493",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "addr",
++          "type": "227"
++        },
++        {
++          "name": "tls-creds",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "tls-authz",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "server",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "wait",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "nodelay",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "telnet",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "tn3270",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "websocket",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "reconnect",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "494",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "remote",
++          "type": "227"
++        },
++        {
++          "name": "local",
++          "default": null,
++          "type": "227"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "495",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "496",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "chardev",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "497",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "signal",
++          "default": null,
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "500",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "width",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "height",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "cols",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "rows",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "501",
++      "members": [
++        {
++          "name": "logfile",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "logappend",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "size",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "502",
++      "members": [
++        {
++          "name": "path",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "cancel-path",
++          "default": null,
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "503",
++      "members": [
++        {
++          "name": "chardev",
++          "type": "str"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "504",
++      "meta-type": "enum",
++      "values": [
++        "unmapped",
++        "shift",
++        "shift_r",
++        "alt",
++        "alt_r",
++        "ctrl",
++        "ctrl_r",
++        "menu",
++        "esc",
++        "1",
++        "2",
++        "3",
++        "4",
++        "5",
++        "6",
++        "7",
++        "8",
++        "9",
++        "0",
++        "minus",
++        "equal",
++        "backspace",
++        "tab",
++        "q",
++        "w",
++        "e",
++        "r",
++        "t",
++        "y",
++        "u",
++        "i",
++        "o",
++        "p",
++        "bracket_left",
++        "bracket_right",
++        "ret",
++        "a",
++        "s",
++        "d",
++        "f",
++        "g",
++        "h",
++        "j",
++        "k",
++        "l",
++        "semicolon",
++        "apostrophe",
++        "grave_accent",
++        "backslash",
++        "z",
++        "x",
++        "c",
++        "v",
++        "b",
++        "n",
++        "m",
++        "comma",
++        "dot",
++        "slash",
++        "asterisk",
++        "spc",
++        "caps_lock",
++        "f1",
++        "f2",
++        "f3",
++        "f4",
++        "f5",
++        "f6",
++        "f7",
++        "f8",
++        "f9",
++        "f10",
++        "num_lock",
++        "scroll_lock",
++        "kp_divide",
++        "kp_multiply",
++        "kp_subtract",
++        "kp_add",
++        "kp_enter",
++        "kp_decimal",
++        "sysrq",
++        "kp_0",
++        "kp_1",
++        "kp_2",
++        "kp_3",
++        "kp_4",
++        "kp_5",
++        "kp_6",
++        "kp_7",
++        "kp_8",
++        "kp_9",
++        "less",
++        "f11",
++        "f12",
++        "print",
++        "home",
++        "pgup",
++        "pgdn",
++        "end",
++        "left",
++        "up",
++        "down",
++        "right",
++        "insert",
++        "delete",
++        "stop",
++        "again",
++        "props",
++        "undo",
++        "front",
++        "copy",
++        "open",
++        "paste",
++        "find",
++        "cut",
++        "lf",
++        "help",
++        "meta_l",
++        "meta_r",
++        "compose",
++        "pause",
++        "ro",
++        "hiragana",
++        "henkan",
++        "yen",
++        "muhenkan",
++        "katakanahiragana",
++        "kp_comma",
++        "kp_equals",
++        "power",
++        "sleep",
++        "wake",
++        "audionext",
++        "audioprev",
++        "audiostop",
++        "audioplay",
++        "audiomute",
++        "volumeup",
++        "volumedown",
++        "mediaselect",
++        "mail",
++        "calculator",
++        "computer",
++        "ac_home",
++        "ac_back",
++        "ac_forward",
++        "ac_refresh",
++        "ac_bookmarks"
++      ]
++    },
++    {
++      "name": "505",
++      "members": [
++        {
++          "name": "key",
++          "type": "306"
++        },
++        {
++          "name": "down",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "506",
++      "members": [
++        {
++          "name": "button",
++          "type": "519"
++        },
++        {
++          "name": "down",
++          "type": "bool"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "507",
++      "members": [
++        {
++          "name": "axis",
++          "type": "520"
++        },
++        {
++          "name": "value",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "508",
++      "members": [
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "509",
++      "members": [
++        {
++          "name": "number",
++          "type": "int"
++        },
++        {
++          "name": "secondary",
++          "type": "int"
++        },
++        {
++          "name": "subordinate",
++          "type": "int"
++        },
++        {
++          "name": "io_range",
++          "type": "521"
++        },
++        {
++          "name": "memory_range",
++          "type": "521"
++        },
++        {
++          "name": "prefetchable_range",
++          "type": "521"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "510",
++      "members": [
++        {
++          "name": "compat",
++          "type": "str"
++        },
++        {
++          "name": "data-file",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "data-file-raw",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "lazy-refcounts",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "corrupt",
++          "default": null,
++          "type": "bool"
++        },
++        {
++          "name": "refcount-bits",
++          "type": "int"
++        },
++        {
++          "name": "encrypt",
++          "default": null,
++          "type": "522"
++        },
++        {
++          "name": "bitmaps",
++          "default": null,
++          "type": "[523]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "511",
++      "members": [
++        {
++          "name": "create-type",
++          "type": "str"
++        },
++        {
++          "name": "cid",
++          "type": "int"
++        },
++        {
++          "name": "parent-cid",
++          "type": "int"
++        },
++        {
++          "name": "extents",
++          "type": "[240]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "512",
++      "members": [
++        {
++          "name": "cipher-alg",
++          "type": "480"
++        },
++        {
++          "name": "cipher-mode",
++          "type": "481"
++        },
++        {
++          "name": "ivgen-alg",
++          "type": "482"
++        },
++        {
++          "name": "ivgen-hash-alg",
++          "default": null,
++          "type": "483"
++        },
++        {
++          "name": "hash-alg",
++          "type": "483"
++        },
++        {
++          "name": "payload-offset",
++          "type": "int"
++        },
++        {
++          "name": "master-key-iters",
++          "type": "int"
++        },
++        {
++          "name": "uuid",
++          "type": "str"
++        },
++        {
++          "name": "slots",
++          "type": "[524]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "513",
++      "meta-type": "enum",
++      "values": [
++        "md5",
++        "sha1"
++      ]
++    },
++    {
++      "name": "514",
++      "meta-type": "enum",
++      "values": [
++        "qcow",
++        "luks"
++      ]
++    },
++    {
++      "name": "515",
++      "members": [
++        {
++          "name": "key-secret",
++          "default": null,
++          "type": "str"
++        },
++        {
++          "name": "cipher-alg",
++          "default": null,
++          "type": "480"
++        },
++        {
++          "name": "cipher-mode",
++          "default": null,
++          "type": "481"
++        },
++        {
++          "name": "ivgen-alg",
++          "default": null,
++          "type": "482"
++        },
++        {
++          "name": "ivgen-hash-alg",
++          "default": null,
++          "type": "483"
++        },
++        {
++          "name": "hash-alg",
++          "default": null,
++          "type": "483"
++        },
++        {
++          "name": "iter-time",
++          "default": null,
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "516",
++      "meta-type": "enum",
++      "values": [
++        "full",
++        "erasure-coded"
++      ]
++    },
++    {
++      "name": "517",
++      "members": [
++        {
++          "name": "copies",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "518",
++      "members": [
++        {
++          "name": "data-strips",
++          "type": "int"
++        },
++        {
++          "name": "parity-strips",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "519",
++      "meta-type": "enum",
++      "values": [
++        "left",
++        "middle",
++        "right",
++        "wheel-up",
++        "wheel-down",
++        "side",
++        "extra"
++      ]
++    },
++    {
++      "name": "520",
++      "meta-type": "enum",
++      "values": [
++        "x",
++        "y"
++      ]
++    },
++    {
++      "name": "521",
++      "members": [
++        {
++          "name": "base",
++          "type": "int"
++        },
++        {
++          "name": "limit",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "522",
++      "tag": "format",
++      "variants": [
++        {
++          "case": "luks",
++          "type": "512"
++        },
++        {
++          "case": "aes",
++          "type": "0"
++        }
++      ],
++      "members": [
++        {
++          "name": "format",
++          "type": "473"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[523]",
++      "element-type": "523",
++      "meta-type": "array"
++    },
++    {
++      "name": "523",
++      "members": [
++        {
++          "name": "name",
++          "type": "str"
++        },
++        {
++          "name": "granularity",
++          "type": "int"
++        },
++        {
++          "name": "flags",
++          "type": "[525]"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[240]",
++      "element-type": "240",
++      "meta-type": "array"
++    },
++    {
++      "name": "[524]",
++      "element-type": "524",
++      "meta-type": "array"
++    },
++    {
++      "name": "524",
++      "members": [
++        {
++          "name": "active",
++          "type": "bool"
++        },
++        {
++          "name": "iters",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "stripes",
++          "default": null,
++          "type": "int"
++        },
++        {
++          "name": "key-offset",
++          "type": "int"
++        }
++      ],
++      "meta-type": "object"
++    },
++    {
++      "name": "[525]",
++      "element-type": "525",
++      "meta-type": "array"
++    },
++    {
++      "name": "525",
++      "meta-type": "enum",
++      "values": [
++        "in-use",
++        "auto"
++      ]
++    }
++  ],
++  "id": "libvirt-40"
++}
++
++{
++  "execute": "query-gic-capabilities",
++  "id": "libvirt-41"
++}
++
++{
++  "return": [
++    {
++      "emulated": true,
++      "version": 3,
++      "kernel": true
++    },
++    {
++      "emulated": true,
++      "version": 2,
++      "kernel": false
++    }
++  ],
++  "id": "libvirt-41"
++}
++
++{
++  "execute": "query-cpu-model-expansion",
++  "arguments": {
++    "type": "full",
++    "model": {
++      "name": "host"
++    }
++  },
++  "id": "libvirt-42"
++}
++
++{
++  "return": {
++    "model": {
++      "name": "host",
++      "props": {
++        "sve768": false,
++        "sve128": false,
++        "sve1024": false,
++        "sve1280": false,
++        "sve896": false,
++        "sve256": false,
++        "sve1536": false,
++        "sve1792": false,
++        "sve384": false,
++        "sve": false,
++        "sve2048": false,
++        "kvm-no-adjvtime": false,
++        "sve512": false,
++        "aarch64": true,
++        "pmu": true,
++        "sve1920": false,
++        "sve1152": false,
++        "sve640": false,
++        "sve1408": false,
++        "sve1664": false
++      }
++    }
++  },
++  "id": "libvirt-42"
++}
++
++{
++  "execute": "query-cpu-model-expansion",
++  "arguments": {
++    "type": "full",
++    "model": {
++      "name": "host",
++      "props": {
++        "migratable": false
++      }
++    }
++  },
++  "id": "libvirt-43"
++}
++
++{
++  "id": "libvirt-43",
++  "error": {
++    "class": "GenericError",
++    "desc": "Parameter 'migratable' is unexpected"
++  }
++}
++
++{
++  "execute": "qmp_capabilities",
++  "id": "libvirt-1"
++}
++
++{
++  "return": {
++  },
++  "id": "libvirt-1"
++}
++
++{
++  "execute": "query-cpu-definitions",
++  "id": "libvirt-2"
++}
++
++{
++  "return": [
++    {
++      "name": "pxa262",
++      "typename": "pxa262-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-a0",
++      "typename": "pxa270-a0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1136",
++      "typename": "arm1136-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a15",
++      "typename": "cortex-a15-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa260",
++      "typename": "pxa260-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1136-r2",
++      "typename": "arm1136-r2-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa261",
++      "typename": "pxa261-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa255",
++      "typename": "pxa255-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a72",
++      "typename": "cortex-a72-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m33",
++      "typename": "cortex-m33-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm926",
++      "typename": "arm926-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-r5f",
++      "typename": "cortex-r5f-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm11mpcore",
++      "typename": "arm11mpcore-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa250",
++      "typename": "pxa250-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "ti925t",
++      "typename": "ti925t-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a57",
++      "typename": "cortex-a57-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "sa1110",
++      "typename": "sa1110-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "host",
++      "typename": "host-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1176",
++      "typename": "arm1176-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a53",
++      "typename": "cortex-a53-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "sa1100",
++      "typename": "sa1100-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-c5",
++      "typename": "pxa270-c5-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a9",
++      "typename": "cortex-a9-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m7",
++      "typename": "cortex-m7-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a8",
++      "typename": "cortex-a8-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-a7",
++      "typename": "cortex-a7-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-c0",
++      "typename": "pxa270-c0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm1026",
++      "typename": "arm1026-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-b1",
++      "typename": "pxa270-b1-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m3",
++      "typename": "cortex-m3-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "max",
++      "typename": "max-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m4",
++      "typename": "cortex-m4-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-b0",
++      "typename": "pxa270-b0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "arm946",
++      "typename": "arm946-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-m0",
++      "typename": "cortex-m0-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "cortex-r5",
++      "typename": "cortex-r5-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270-a1",
++      "typename": "pxa270-a1-arm-cpu",
++      "static": false
++    },
++    {
++      "name": "pxa270",
++      "typename": "pxa270-arm-cpu",
++      "static": false
++    }
++  ],
++  "id": "libvirt-2"
++}
++
++{
++  "execute": "query-cpu-model-expansion",
++  "arguments": {
++    "type": "full",
++    "model": {
++      "name": "max"
++    }
++  },
++  "id": "libvirt-3"
++}
++
++{
++  "return": {
++    "model": {
++      "name": "max",
++      "props": {
++        "sve768": true,
++        "sve128": true,
++        "sve1024": true,
++        "sve1280": true,
++        "sve896": true,
++        "sve256": true,
++        "sve1536": true,
++        "sve1792": true,
++        "sve384": true,
++        "sve": true,
++        "sve2048": true,
++        "sve512": true,
++        "aarch64": true,
++        "pmu": true,
++        "sve1920": true,
++        "sve1152": true,
++        "sve640": true,
++        "sve1408": true,
++        "sve1664": true
++      }
++    }
++  },
++  "id": "libvirt-3"
++}
++
++{
++  "execute": "query-cpu-model-expansion",
++  "arguments": {
++    "type": "full",
++    "model": {
++      "name": "max",
++      "props": {
++        "migratable": false
++      }
++    }
++  },
++  "id": "libvirt-4"
++}
++
++{
++  "id": "libvirt-4",
++  "error": {
++    "class": "GenericError",
++    "desc": "Parameter 'migratable' is unexpected"
++  }
++}
++
++{
++  "execute": "query-machines",
++  "id": "libvirt-5"
++}
++
++{
++  "return": [
++    {
++      "hotpluggable-cpus": false,
++      "name": "integratorcp",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "nuri",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an511",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an505",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "verdex",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-3.0",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "ast2500-evb",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "smdkc210",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "collie",
++      "numa-mem-supported": false,
++      "default-cpu-type": "sa1110-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "xlnx-versal-virt",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "imx25-pdk",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "none",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "spitz",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "musca-b1",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-pbx-a9",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-eb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "versatilepb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-pb-a8",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a8-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "emcraft-sf2",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.9",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "musicpal",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sbsa-ref",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a57-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "z2",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c5-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "akita",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.7",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "kzm",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "swift-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.8",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "realview-eb-mpcore",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm11mpcore-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "musca-a",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mcimx7d-sabre",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sx1",
++      "numa-mem-supported": false,
++      "default-cpu-type": "ti925t-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-4.2",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sx1-v1",
++      "numa-mem-supported": false,
++      "default-cpu-type": "ti925t-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.6",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "cubieboard",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-4.0",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "highbank",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-4.1",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "raspi2",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "raspi3",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "netduino2",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "terrier",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c5-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "n810",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm1136-r2-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mainstone",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c5-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "palmetto-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "tacoma-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "sabrelite",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "netduinoplus2",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "midway",
++      "numa-mem-supported": false,
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "romulus-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "cheetah",
++      "numa-mem-supported": false,
++      "default-cpu-type": "ti925t-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "tosa",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "borzoi",
++      "numa-mem-supported": false,
++      "default-cpu-type": "pxa270-c0-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "versatileab",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm926-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "lm3s6965evb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "n800",
++      "numa-mem-supported": false,
++      "default-cpu-type": "arm1136-r2-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.10",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.11",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "connex",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-2.12",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 255,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "microbit",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "witherspoon-bmc",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "xilinx-zynq-a9",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an385",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "ast2600-evb",
++      "numa-mem-supported": false,
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "vexpress-a9",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a9-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mps2-an521",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m33-arm-cpu",
++      "cpu-max": 2,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "mcimx6ul-evk",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "vexpress-a15",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 4,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "xlnx-zcu102",
++      "numa-mem-supported": false,
++      "cpu-max": 6,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-5.0",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false,
++      "alias": "virt"
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "virt-3.1",
++      "numa-mem-supported": true,
++      "default-cpu-type": "cortex-a15-arm-cpu",
++      "cpu-max": 512,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "canon-a1100",
++      "numa-mem-supported": false,
++      "cpu-max": 1,
++      "deprecated": false
++    },
++    {
++      "hotpluggable-cpus": false,
++      "name": "lm3s811evb",
++      "numa-mem-supported": false,
++      "default-cpu-type": "cortex-m3-arm-cpu",
++      "cpu-max": 1,
++      "deprecated": false
++    }
++  ],
++  "id": "libvirt-5"
++}
+diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+new file mode 100644
+index 0000000000..6b365dd75d
+--- /dev/null
++++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+@@ -0,0 +1,455 @@
++<qemuCaps>
++  <emulator>/usr/bin/qemu-system-aarch64</emulator>
++  <qemuctime>0</qemuctime>
++  <selfctime>0</selfctime>
++  <selfvers>0</selfvers>
++  <flag name='kvm'/>
++  <flag name='hda-duplex'/>
++  <flag name='virtio-tx-alg'/>
++  <flag name='virtio-blk-pci.ioeventfd'/>
++  <flag name='virtio-blk-pci.event_idx'/>
++  <flag name='virtio-net-pci.event_idx'/>
++  <flag name='piix3-usb-uhci'/>
++  <flag name='piix4-usb-uhci'/>
++  <flag name='usb-ehci'/>
++  <flag name='ich9-usb-ehci1'/>
++  <flag name='vt82c686b-usb-uhci'/>
++  <flag name='pci-ohci'/>
++  <flag name='usb-hub'/>
++  <flag name='ich9-ahci'/>
++  <flag name='no-acpi'/>
++  <flag name='virtio-blk-pci.scsi'/>
++  <flag name='scsi-disk.channel'/>
++  <flag name='scsi-block'/>
++  <flag name='hda-micro'/>
++  <flag name='dump-guest-memory'/>
++  <flag name='nec-usb-xhci'/>
++  <flag name='lsi'/>
++  <flag name='virtio-scsi-pci'/>
++  <flag name='blockio'/>
++  <flag name='ide-drive.wwn'/>
++  <flag name='scsi-disk.wwn'/>
++  <flag name='seccomp-sandbox'/>
++  <flag name='reboot-timeout'/>
++  <flag name='vnc'/>
++  <flag name='VGA'/>
++  <flag name='cirrus-vga'/>
++  <flag name='vmware-svga'/>
++  <flag name='device-video-primary'/>
++  <flag name='usb-serial'/>
++  <flag name='nbd-server'/>
++  <flag name='virtio-rng'/>
++  <flag name='rng-random'/>
++  <flag name='rng-egd'/>
++  <flag name='megasas'/>
++  <flag name='pci-bridge'/>
++  <flag name='vfio-pci'/>
++  <flag name='mem-merge'/>
++  <flag name='drive-discard'/>
++  <flag name='dmi-to-pci-bridge'/>
++  <flag name='usb-storage'/>
++  <flag name='usb-storage.removable'/>
++  <flag name='virtio-mmio'/>
++  <flag name='ich9-intel-hda'/>
++  <flag name='boot-strict'/>
++  <flag name='usb-kbd'/>
++  <flag name='msg-timestamp'/>
++  <flag name='active-commit'/>
++  <flag name='change-backing-file'/>
++  <flag name='memory-backend-ram'/>
++  <flag name='numa'/>
++  <flag name='memory-backend-file'/>
++  <flag name='usb-audio'/>
++  <flag name='splash-timeout'/>
++  <flag name='iothread'/>
++  <flag name='migrate-rdma'/>
++  <flag name='drive-iotune-max'/>
++  <flag name='VGA.vgamem_mb'/>
++  <flag name='vmware-svga.vgamem_mb'/>
++  <flag name='pc-dimm'/>
++  <flag name='machine-vmport-opt'/>
++  <flag name='aes-key-wrap'/>
++  <flag name='dea-key-wrap'/>
++  <flag name='pci-serial'/>
++  <flag name='aarch64-off'/>
++  <flag name='vhost-user-multiqueue'/>
++  <flag name='migration-event'/>
++  <flag name='gpex-pcihost'/>
++  <flag name='ioh3420'/>
++  <flag name='x3130-upstream'/>
++  <flag name='xio3130-downstream'/>
++  <flag name='rtl8139'/>
++  <flag name='e1000'/>
++  <flag name='virtio-net'/>
++  <flag name='gic-version'/>
++  <flag name='incoming-defer'/>
++  <flag name='virtio-gpu'/>
++  <flag name='virtio-keyboard'/>
++  <flag name='virtio-mouse'/>
++  <flag name='virtio-tablet'/>
++  <flag name='virtio-input-host'/>
++  <flag name='chardev-file-append'/>
++  <flag name='vserport-change-event'/>
++  <flag name='virtio-balloon-pci.deflate-on-oom'/>
++  <flag name='mptsas1068'/>
++  <flag name='chardev-logfile'/>
++  <flag name='debug-threads'/>
++  <flag name='secret'/>
++  <flag name='nec-usb-xhci-ports'/>
++  <flag name='virtio-scsi-pci.iothread'/>
++  <flag name='name-guest'/>
++  <flag name='drive-detect-zeroes'/>
++  <flag name='tls-creds-x509'/>
++  <flag name='smm'/>
++  <flag name='virtio-pci-disable-legacy'/>
++  <flag name='query-hotpluggable-cpus'/>
++  <flag name='virtio-net.rx_queue_size'/>
++  <flag name='drive-iotune-max-length'/>
++  <flag name='ivshmem-plain'/>
++  <flag name='ivshmem-doorbell'/>
++  <flag name='query-qmp-schema'/>
++  <flag name='gluster.debug_level'/>
++  <flag name='vhost-scsi'/>
++  <flag name='drive-iotune-group'/>
++  <flag name='query-cpu-model-expansion'/>
++  <flag name='virtio-net.host_mtu'/>
++  <flag name='pcie-root-port'/>
++  <flag name='query-cpu-definitions'/>
++  <flag name='block-write-threshold'/>
++  <flag name='query-named-block-nodes'/>
++  <flag name='qemu-xhci'/>
++  <flag name='kernel-irqchip'/>
++  <flag name='kernel-irqchip.split'/>
++  <flag name='virtio.iommu_platform'/>
++  <flag name='virtio.ats'/>
++  <flag name='loadparm'/>
++  <flag name='vnc-multi-servers'/>
++  <flag name='virtio-net.tx_queue_size'/>
++  <flag name='chardev-reconnect'/>
++  <flag name='virtio-gpu.max_outputs'/>
++  <flag name='vxhs'/>
++  <flag name='virtio-blk.num-queues'/>
++  <flag name='vmcoreinfo'/>
++  <flag name='numa.dist'/>
++  <flag name='disk-share-rw'/>
++  <flag name='iscsi.password-secret'/>
++  <flag name='pl011'/>
++  <flag name='dump-completed'/>
++  <flag name='qcow2-luks'/>
++  <flag name='pcie-pci-bridge'/>
++  <flag name='seccomp-blacklist'/>
++  <flag name='query-cpus-fast'/>
++  <flag name='disk-write-cache'/>
++  <flag name='nbd-tls'/>
++  <flag name='pr-manager-helper'/>
++  <flag name='qom-list-properties'/>
++  <flag name='memory-backend-file.discard-data'/>
++  <flag name='sdl-gl'/>
++  <flag name='screendump_device'/>
++  <flag name='hda-output'/>
++  <flag name='blockdev-del'/>
++  <flag name='vhost-vsock'/>
++  <flag name='chardev-fd-pass'/>
++  <flag name='usb-storage.werror'/>
++  <flag name='egl-headless'/>
++  <flag name='vfio-pci.display'/>
++  <flag name='blockdev'/>
++  <flag name='memory-backend-memfd'/>
++  <flag name='memory-backend-memfd.hugetlb'/>
++  <flag name='iothread.poll-max-ns'/>
++  <flag name='egl-headless.rendernode'/>
++  <flag name='memory-backend-file.align'/>
++  <flag name='memory-backend-file.pmem'/>
++  <flag name='scsi-disk.device_id'/>
++  <flag name='virtio-pci-non-transitional'/>
++  <flag name='overcommit'/>
++  <flag name='query-current-machine'/>
++  <flag name='machine.virt.iommu'/>
++  <flag name='bitmap-merge'/>
++  <flag name='nbd-bitmap'/>
++  <flag name='bochs-display'/>
++  <flag name='migration-file-drop-cache'/>
++  <flag name='dbus-vmstate'/>
++  <flag name='vhost-user-gpu'/>
++  <flag name='ramfb'/>
++  <flag name='arm-max-cpu'/>
++  <flag name='blockdev-file-dynamic-auto-read-only'/>
++  <flag name='savevm-monitor-nodes'/>
++  <flag name='drive-nvme'/>
++  <flag name='smp-dies'/>
++  <flag name='virtio-net.failover'/>
++  <version>4002050</version>
++  <kvmVersion>0</kvmVersion>
++  <microcodeVersion>61700241</microcodeVersion>
++  <package>v4.2.0-1157-gadcd6e93b9</package>
++  <arch>aarch64</arch>
++  <hostCPU type='kvm' model='host' migratability='no'>
++    <property name='sve768' type='boolean' value='false'/>
++    <property name='sve128' type='boolean' value='false'/>
++    <property name='sve1024' type='boolean' value='false'/>
++    <property name='sve1280' type='boolean' value='false'/>
++    <property name='sve896' type='boolean' value='false'/>
++    <property name='sve256' type='boolean' value='false'/>
++    <property name='sve1536' type='boolean' value='false'/>
++    <property name='sve1792' type='boolean' value='false'/>
++    <property name='sve384' type='boolean' value='false'/>
++    <property name='sve' type='boolean' value='false'/>
++    <property name='sve2048' type='boolean' value='false'/>
++    <property name='kvm-no-adjvtime' type='boolean' value='false'/>
++    <property name='sve512' type='boolean' value='false'/>
++    <property name='aarch64' type='boolean' value='true'/>
++    <property name='pmu' type='boolean' value='true'/>
++    <property name='sve1920' type='boolean' value='false'/>
++    <property name='sve1152' type='boolean' value='false'/>
++    <property name='sve640' type='boolean' value='false'/>
++    <property name='sve1408' type='boolean' value='false'/>
++    <property name='sve1664' type='boolean' value='false'/>
++  </hostCPU>
++  <cpu type='kvm' name='pxa262' typename='pxa262-arm-cpu'/>
++  <cpu type='kvm' name='pxa270-a0' typename='pxa270-a0-arm-cpu'/>
++  <cpu type='kvm' name='arm1136' typename='arm1136-arm-cpu'/>
++  <cpu type='kvm' name='cortex-a15' typename='cortex-a15-arm-cpu'/>
++  <cpu type='kvm' name='pxa260' typename='pxa260-arm-cpu'/>
++  <cpu type='kvm' name='arm1136-r2' typename='arm1136-r2-arm-cpu'/>
++  <cpu type='kvm' name='pxa261' typename='pxa261-arm-cpu'/>
++  <cpu type='kvm' name='pxa255' typename='pxa255-arm-cpu'/>
++  <cpu type='kvm' name='cortex-a72' typename='cortex-a72-arm-cpu'/>
++  <cpu type='kvm' name='cortex-m33' typename='cortex-m33-arm-cpu'/>
++  <cpu type='kvm' name='arm926' typename='arm926-arm-cpu'/>
++  <cpu type='kvm' name='cortex-r5f' typename='cortex-r5f-arm-cpu'/>
++  <cpu type='kvm' name='arm11mpcore' typename='arm11mpcore-arm-cpu'/>
++  <cpu type='kvm' name='pxa250' typename='pxa250-arm-cpu'/>
++  <cpu type='kvm' name='ti925t' typename='ti925t-arm-cpu'/>
++  <cpu type='kvm' name='cortex-a57' typename='cortex-a57-arm-cpu'/>
++  <cpu type='kvm' name='sa1110' typename='sa1110-arm-cpu'/>
++  <cpu type='kvm' name='host' typename='host-arm-cpu'/>
++  <cpu type='kvm' name='arm1176' typename='arm1176-arm-cpu'/>
++  <cpu type='kvm' name='cortex-a53' typename='cortex-a53-arm-cpu'/>
++  <cpu type='kvm' name='sa1100' typename='sa1100-arm-cpu'/>
++  <cpu type='kvm' name='pxa270-c5' typename='pxa270-c5-arm-cpu'/>
++  <cpu type='kvm' name='cortex-a9' typename='cortex-a9-arm-cpu'/>
++  <cpu type='kvm' name='cortex-m7' typename='cortex-m7-arm-cpu'/>
++  <cpu type='kvm' name='cortex-a8' typename='cortex-a8-arm-cpu'/>
++  <cpu type='kvm' name='cortex-a7' typename='cortex-a7-arm-cpu'/>
++  <cpu type='kvm' name='pxa270-c0' typename='pxa270-c0-arm-cpu'/>
++  <cpu type='kvm' name='arm1026' typename='arm1026-arm-cpu'/>
++  <cpu type='kvm' name='pxa270-b1' typename='pxa270-b1-arm-cpu'/>
++  <cpu type='kvm' name='cortex-m3' typename='cortex-m3-arm-cpu'/>
++  <cpu type='kvm' name='max' typename='max-arm-cpu'/>
++  <cpu type='kvm' name='cortex-m4' typename='cortex-m4-arm-cpu'/>
++  <cpu type='kvm' name='pxa270-b0' typename='pxa270-b0-arm-cpu'/>
++  <cpu type='kvm' name='arm946' typename='arm946-arm-cpu'/>
++  <cpu type='kvm' name='cortex-m0' typename='cortex-m0-arm-cpu'/>
++  <cpu type='kvm' name='cortex-r5' typename='cortex-r5-arm-cpu'/>
++  <cpu type='kvm' name='pxa270-a1' typename='pxa270-a1-arm-cpu'/>
++  <cpu type='kvm' name='pxa270' typename='pxa270-arm-cpu'/>
++  <machine type='kvm' name='integratorcp' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='kvm' name='nuri' maxCpus='2'/>
++  <machine type='kvm' name='mps2-an511' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='kvm' name='mps2-an505' maxCpus='1' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='kvm' name='verdex' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='kvm' name='virt-3.0' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='ast2500-evb' maxCpus='2'/>
++  <machine type='kvm' name='smdkc210' maxCpus='2'/>
++  <machine type='kvm' name='collie' maxCpus='1' defaultCPU='sa1110-arm-cpu'/>
++  <machine type='kvm' name='xlnx-versal-virt' maxCpus='2'/>
++  <machine type='kvm' name='imx25-pdk' maxCpus='1'/>
++  <machine type='kvm' name='spitz' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='kvm' name='musca-b1' maxCpus='2' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='kvm' name='realview-pbx-a9' maxCpus='4' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='kvm' name='realview-eb' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='kvm' name='versatilepb' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='kvm' name='realview-pb-a8' maxCpus='1' defaultCPU='cortex-a8-arm-cpu'/>
++  <machine type='kvm' name='emcraft-sf2' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='kvm' name='virt-2.9' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='musicpal' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='kvm' name='sbsa-ref' maxCpus='512' defaultCPU='cortex-a57-arm-cpu'/>
++  <machine type='kvm' name='z2' maxCpus='1' defaultCPU='pxa270-c5-arm-cpu'/>
++  <machine type='kvm' name='akita' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='kvm' name='virt-2.7' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='kzm' maxCpus='1'/>
++  <machine type='kvm' name='swift-bmc' maxCpus='2'/>
++  <machine type='kvm' name='virt-2.8' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='realview-eb-mpcore' maxCpus='4' defaultCPU='arm11mpcore-arm-cpu'/>
++  <machine type='kvm' name='musca-a' maxCpus='2' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='kvm' name='mcimx7d-sabre' maxCpus='2'/>
++  <machine type='kvm' name='sx1' maxCpus='1' defaultCPU='ti925t-arm-cpu'/>
++  <machine type='kvm' name='virt-4.2' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='sx1-v1' maxCpus='1' defaultCPU='ti925t-arm-cpu'/>
++  <machine type='kvm' name='virt-2.6' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='cubieboard' maxCpus='1' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='kvm' name='virt-4.0' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='highbank' maxCpus='4'/>
++  <machine type='kvm' name='virt-4.1' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='raspi2' maxCpus='4'/>
++  <machine type='kvm' name='raspi3' maxCpus='4'/>
++  <machine type='kvm' name='netduino2' maxCpus='1'/>
++  <machine type='kvm' name='terrier' maxCpus='1' defaultCPU='pxa270-c5-arm-cpu'/>
++  <machine type='kvm' name='n810' maxCpus='1' defaultCPU='arm1136-r2-arm-cpu'/>
++  <machine type='kvm' name='mainstone' maxCpus='1' defaultCPU='pxa270-c5-arm-cpu'/>
++  <machine type='kvm' name='palmetto-bmc' maxCpus='2'/>
++  <machine type='kvm' name='tacoma-bmc' maxCpus='2'/>
++  <machine type='kvm' name='sabrelite' maxCpus='4'/>
++  <machine type='kvm' name='netduinoplus2' maxCpus='1'/>
++  <machine type='kvm' name='midway' maxCpus='4'/>
++  <machine type='kvm' name='romulus-bmc' maxCpus='2'/>
++  <machine type='kvm' name='cheetah' maxCpus='1' defaultCPU='ti925t-arm-cpu'/>
++  <machine type='kvm' name='tosa' maxCpus='1'/>
++  <machine type='kvm' name='borzoi' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='kvm' name='versatileab' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='kvm' name='lm3s6965evb' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='kvm' name='n800' maxCpus='1' defaultCPU='arm1136-r2-arm-cpu'/>
++  <machine type='kvm' name='virt-2.10' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='virt-2.11' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='connex' maxCpus='1'/>
++  <machine type='kvm' name='virt-2.12' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='microbit' maxCpus='1'/>
++  <machine type='kvm' name='witherspoon-bmc' maxCpus='2'/>
++  <machine type='kvm' name='xilinx-zynq-a9' maxCpus='1' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='kvm' name='mps2-an385' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='kvm' name='ast2600-evb' maxCpus='2'/>
++  <machine type='kvm' name='vexpress-a9' maxCpus='4' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='kvm' name='mps2-an521' maxCpus='2' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='kvm' name='mcimx6ul-evk' maxCpus='1'/>
++  <machine type='kvm' name='vexpress-a15' maxCpus='4' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='xlnx-zcu102' maxCpus='6'/>
++  <machine type='kvm' name='virt-5.0' alias='virt' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='virt-3.1' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='kvm' name='canon-a1100' maxCpus='1'/>
++  <machine type='kvm' name='lm3s811evb' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <hostCPU type='tcg' model='max' migratability='no'>
++    <property name='sve768' type='boolean' value='true'/>
++    <property name='sve128' type='boolean' value='true'/>
++    <property name='sve1024' type='boolean' value='true'/>
++    <property name='sve1280' type='boolean' value='true'/>
++    <property name='sve896' type='boolean' value='true'/>
++    <property name='sve256' type='boolean' value='true'/>
++    <property name='sve1536' type='boolean' value='true'/>
++    <property name='sve1792' type='boolean' value='true'/>
++    <property name='sve384' type='boolean' value='true'/>
++    <property name='sve' type='boolean' value='true'/>
++    <property name='sve2048' type='boolean' value='true'/>
++    <property name='sve512' type='boolean' value='true'/>
++    <property name='aarch64' type='boolean' value='true'/>
++    <property name='pmu' type='boolean' value='true'/>
++    <property name='sve1920' type='boolean' value='true'/>
++    <property name='sve1152' type='boolean' value='true'/>
++    <property name='sve640' type='boolean' value='true'/>
++    <property name='sve1408' type='boolean' value='true'/>
++    <property name='sve1664' type='boolean' value='true'/>
++  </hostCPU>
++  <cpu type='tcg' name='pxa262' typename='pxa262-arm-cpu'/>
++  <cpu type='tcg' name='pxa270-a0' typename='pxa270-a0-arm-cpu'/>
++  <cpu type='tcg' name='arm1136' typename='arm1136-arm-cpu'/>
++  <cpu type='tcg' name='cortex-a15' typename='cortex-a15-arm-cpu'/>
++  <cpu type='tcg' name='pxa260' typename='pxa260-arm-cpu'/>
++  <cpu type='tcg' name='arm1136-r2' typename='arm1136-r2-arm-cpu'/>
++  <cpu type='tcg' name='pxa261' typename='pxa261-arm-cpu'/>
++  <cpu type='tcg' name='pxa255' typename='pxa255-arm-cpu'/>
++  <cpu type='tcg' name='cortex-a72' typename='cortex-a72-arm-cpu'/>
++  <cpu type='tcg' name='cortex-m33' typename='cortex-m33-arm-cpu'/>
++  <cpu type='tcg' name='arm926' typename='arm926-arm-cpu'/>
++  <cpu type='tcg' name='cortex-r5f' typename='cortex-r5f-arm-cpu'/>
++  <cpu type='tcg' name='arm11mpcore' typename='arm11mpcore-arm-cpu'/>
++  <cpu type='tcg' name='pxa250' typename='pxa250-arm-cpu'/>
++  <cpu type='tcg' name='ti925t' typename='ti925t-arm-cpu'/>
++  <cpu type='tcg' name='cortex-a57' typename='cortex-a57-arm-cpu'/>
++  <cpu type='tcg' name='sa1110' typename='sa1110-arm-cpu'/>
++  <cpu type='tcg' name='host' typename='host-arm-cpu'/>
++  <cpu type='tcg' name='arm1176' typename='arm1176-arm-cpu'/>
++  <cpu type='tcg' name='cortex-a53' typename='cortex-a53-arm-cpu'/>
++  <cpu type='tcg' name='sa1100' typename='sa1100-arm-cpu'/>
++  <cpu type='tcg' name='pxa270-c5' typename='pxa270-c5-arm-cpu'/>
++  <cpu type='tcg' name='cortex-a9' typename='cortex-a9-arm-cpu'/>
++  <cpu type='tcg' name='cortex-m7' typename='cortex-m7-arm-cpu'/>
++  <cpu type='tcg' name='cortex-a8' typename='cortex-a8-arm-cpu'/>
++  <cpu type='tcg' name='cortex-a7' typename='cortex-a7-arm-cpu'/>
++  <cpu type='tcg' name='pxa270-c0' typename='pxa270-c0-arm-cpu'/>
++  <cpu type='tcg' name='arm1026' typename='arm1026-arm-cpu'/>
++  <cpu type='tcg' name='pxa270-b1' typename='pxa270-b1-arm-cpu'/>
++  <cpu type='tcg' name='cortex-m3' typename='cortex-m3-arm-cpu'/>
++  <cpu type='tcg' name='max' typename='max-arm-cpu'/>
++  <cpu type='tcg' name='cortex-m4' typename='cortex-m4-arm-cpu'/>
++  <cpu type='tcg' name='pxa270-b0' typename='pxa270-b0-arm-cpu'/>
++  <cpu type='tcg' name='arm946' typename='arm946-arm-cpu'/>
++  <cpu type='tcg' name='cortex-m0' typename='cortex-m0-arm-cpu'/>
++  <cpu type='tcg' name='cortex-r5' typename='cortex-r5-arm-cpu'/>
++  <cpu type='tcg' name='pxa270-a1' typename='pxa270-a1-arm-cpu'/>
++  <cpu type='tcg' name='pxa270' typename='pxa270-arm-cpu'/>
++  <machine type='tcg' name='integratorcp' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='tcg' name='nuri' maxCpus='2'/>
++  <machine type='tcg' name='mps2-an511' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='tcg' name='mps2-an505' maxCpus='1' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='tcg' name='verdex' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='tcg' name='virt-3.0' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='ast2500-evb' maxCpus='2'/>
++  <machine type='tcg' name='smdkc210' maxCpus='2'/>
++  <machine type='tcg' name='collie' maxCpus='1' defaultCPU='sa1110-arm-cpu'/>
++  <machine type='tcg' name='xlnx-versal-virt' maxCpus='2'/>
++  <machine type='tcg' name='imx25-pdk' maxCpus='1'/>
++  <machine type='tcg' name='spitz' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='tcg' name='musca-b1' maxCpus='2' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='tcg' name='realview-pbx-a9' maxCpus='4' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='tcg' name='realview-eb' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='tcg' name='versatilepb' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='tcg' name='realview-pb-a8' maxCpus='1' defaultCPU='cortex-a8-arm-cpu'/>
++  <machine type='tcg' name='emcraft-sf2' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='tcg' name='virt-2.9' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='musicpal' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='tcg' name='sbsa-ref' maxCpus='512' defaultCPU='cortex-a57-arm-cpu'/>
++  <machine type='tcg' name='z2' maxCpus='1' defaultCPU='pxa270-c5-arm-cpu'/>
++  <machine type='tcg' name='akita' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='tcg' name='virt-2.7' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='kzm' maxCpus='1'/>
++  <machine type='tcg' name='swift-bmc' maxCpus='2'/>
++  <machine type='tcg' name='virt-2.8' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='realview-eb-mpcore' maxCpus='4' defaultCPU='arm11mpcore-arm-cpu'/>
++  <machine type='tcg' name='musca-a' maxCpus='2' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='tcg' name='mcimx7d-sabre' maxCpus='2'/>
++  <machine type='tcg' name='sx1' maxCpus='1' defaultCPU='ti925t-arm-cpu'/>
++  <machine type='tcg' name='virt-4.2' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='sx1-v1' maxCpus='1' defaultCPU='ti925t-arm-cpu'/>
++  <machine type='tcg' name='virt-2.6' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='cubieboard' maxCpus='1' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='tcg' name='virt-4.0' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='highbank' maxCpus='4'/>
++  <machine type='tcg' name='virt-4.1' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='raspi2' maxCpus='4'/>
++  <machine type='tcg' name='raspi3' maxCpus='4'/>
++  <machine type='tcg' name='netduino2' maxCpus='1'/>
++  <machine type='tcg' name='terrier' maxCpus='1' defaultCPU='pxa270-c5-arm-cpu'/>
++  <machine type='tcg' name='n810' maxCpus='1' defaultCPU='arm1136-r2-arm-cpu'/>
++  <machine type='tcg' name='mainstone' maxCpus='1' defaultCPU='pxa270-c5-arm-cpu'/>
++  <machine type='tcg' name='palmetto-bmc' maxCpus='2'/>
++  <machine type='tcg' name='tacoma-bmc' maxCpus='2'/>
++  <machine type='tcg' name='sabrelite' maxCpus='4'/>
++  <machine type='tcg' name='netduinoplus2' maxCpus='1'/>
++  <machine type='tcg' name='midway' maxCpus='4'/>
++  <machine type='tcg' name='romulus-bmc' maxCpus='2'/>
++  <machine type='tcg' name='cheetah' maxCpus='1' defaultCPU='ti925t-arm-cpu'/>
++  <machine type='tcg' name='tosa' maxCpus='1'/>
++  <machine type='tcg' name='borzoi' maxCpus='1' defaultCPU='pxa270-c0-arm-cpu'/>
++  <machine type='tcg' name='versatileab' maxCpus='1' defaultCPU='arm926-arm-cpu'/>
++  <machine type='tcg' name='lm3s6965evb' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='tcg' name='n800' maxCpus='1' defaultCPU='arm1136-r2-arm-cpu'/>
++  <machine type='tcg' name='virt-2.10' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='virt-2.11' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='connex' maxCpus='1'/>
++  <machine type='tcg' name='virt-2.12' maxCpus='255' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='microbit' maxCpus='1'/>
++  <machine type='tcg' name='witherspoon-bmc' maxCpus='2'/>
++  <machine type='tcg' name='xilinx-zynq-a9' maxCpus='1' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='tcg' name='mps2-an385' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <machine type='tcg' name='ast2600-evb' maxCpus='2'/>
++  <machine type='tcg' name='vexpress-a9' maxCpus='4' defaultCPU='cortex-a9-arm-cpu'/>
++  <machine type='tcg' name='mps2-an521' maxCpus='2' defaultCPU='cortex-m33-arm-cpu'/>
++  <machine type='tcg' name='mcimx6ul-evk' maxCpus='1'/>
++  <machine type='tcg' name='vexpress-a15' maxCpus='4' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='xlnx-zcu102' maxCpus='6'/>
++  <machine type='tcg' name='virt-5.0' alias='virt' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='virt-3.1' maxCpus='512' defaultCPU='cortex-a15-arm-cpu'/>
++  <machine type='tcg' name='canon-a1100' maxCpus='1'/>
++  <machine type='tcg' name='lm3s811evb' maxCpus='1' defaultCPU='cortex-m3-arm-cpu'/>
++  <gic version='3' kernel='yes' emulated='yes'/>
++  <gic version='2' kernel='no' emulated='yes'/>
++</qemuCaps>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-Add-test-case-for-the-armvtimer-timer.patch b/SOURCES/libvirt-tests-Add-test-case-for-the-armvtimer-timer.patch
new file mode 100644
index 0000000..4144d71
--- /dev/null
+++ b/SOURCES/libvirt-tests-Add-test-case-for-the-armvtimer-timer.patch
@@ -0,0 +1,136 @@
+From 18f28324129e34a486c5df049785d7ee04960f1d Mon Sep 17 00:00:00 2001
+Message-Id: <18f28324129e34a486c5df049785d7ee04960f1d@dist-git>
+From: Andrea Bolognani <abologna@redhat.com>
+Date: Fri, 14 Feb 2020 14:14:51 +0100
+Subject: [PATCH] tests: Add test case for the armvtimer timer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 76121fc9c49d26c1ca4f596c3cac5c05eb02fc76)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1762634
+
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200214131451.707092-1-abologna@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ .../clock-timer-armvtimer.aarch64-latest.args | 32 +++++++++++++++++++
+ .../clock-timer-armvtimer.xml                 | 27 ++++++++++++++++
+ tests/qemuxml2argvtest.c                      |  2 ++
+ .../clock-timer-armvtimer.aarch64-latest.xml  |  1 +
+ tests/qemuxml2xmltest.c                       |  1 +
+ 5 files changed, 63 insertions(+)
+ create mode 100644 tests/qemuxml2argvdata/clock-timer-armvtimer.aarch64-latest.args
+ create mode 100644 tests/qemuxml2argvdata/clock-timer-armvtimer.xml
+ create mode 120000 tests/qemuxml2xmloutdata/clock-timer-armvtimer.aarch64-latest.xml
+
+diff --git a/tests/qemuxml2argvdata/clock-timer-armvtimer.aarch64-latest.args b/tests/qemuxml2argvdata/clock-timer-armvtimer.aarch64-latest.args
+new file mode 100644
+index 0000000000..a1faa97b9f
+--- /dev/null
++++ b/tests/qemuxml2argvdata/clock-timer-armvtimer.aarch64-latest.args
+@@ -0,0 +1,32 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-guest \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-aarch64 \
++-name guest=guest,debug-threads=on \
++-S \
++-object secret,id=masterKey0,format=raw,\
++file=/tmp/lib/domain--1-guest/master-key.aes \
++-machine virt,accel=kvm,usb=off,dump-guest-core=off,gic-version=3 \
++-cpu host,kvm-no-adjvtime=on \
++-m 4096 \
++-overcommit mem-lock=off \
++-smp 4,sockets=4,cores=1,threads=1 \
++-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,fd=1729,server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-no-acpi \
++-boot strict=on \
++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
++resourcecontrol=deny \
++-msg timestamp=on
+diff --git a/tests/qemuxml2argvdata/clock-timer-armvtimer.xml b/tests/qemuxml2argvdata/clock-timer-armvtimer.xml
+new file mode 100644
+index 0000000000..295ab64d75
+--- /dev/null
++++ b/tests/qemuxml2argvdata/clock-timer-armvtimer.xml
+@@ -0,0 +1,27 @@
++<domain type='kvm'>
++  <name>guest</name>
++  <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid>
++  <memory unit='KiB'>4194304</memory>
++  <currentMemory unit='KiB'>4194304</currentMemory>
++  <vcpu placement='static'>4</vcpu>
++  <os>
++    <type arch='aarch64' machine='virt'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <features>
++    <gic version='3'/>
++  </features>
++  <cpu mode='host-passthrough' check='none'/>
++  <clock offset='utc'>
++    <timer name='armvtimer' tickpolicy='discard'/>
++  </clock>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-aarch64</emulator>
++    <controller type='usb' index='0' model='none'/>
++    <controller type='pci' index='0' model='pcie-root'/>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index 4d26fe0b55..508dfee3fb 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -2721,6 +2721,8 @@ mymain(void)
+     /* SVE aarch64 CPU features work on modern QEMU */
+     DO_TEST_CAPS_ARCH_LATEST("aarch64-features-sve", "aarch64");
+ 
++    DO_TEST_CAPS_ARCH_LATEST("clock-timer-armvtimer", "aarch64");
++
+     qemuTestSetHostArch(&driver, VIR_ARCH_NONE);
+ 
+     DO_TEST("kvm-pit-delay", QEMU_CAPS_KVM_PIT_TICK_POLICY);
+diff --git a/tests/qemuxml2xmloutdata/clock-timer-armvtimer.aarch64-latest.xml b/tests/qemuxml2xmloutdata/clock-timer-armvtimer.aarch64-latest.xml
+new file mode 120000
+index 0000000000..4bfddd6573
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/clock-timer-armvtimer.aarch64-latest.xml
+@@ -0,0 +1 @@
++../qemuxml2argvdata/clock-timer-armvtimer.xml
+\ No newline at end of file
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index e54c540ef6..6a8ae9f7eb 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -269,6 +269,7 @@ mymain(void)
+     DO_TEST("clock-catchup", QEMU_CAPS_KVM_PIT_TICK_POLICY);
+     DO_TEST("kvmclock", NONE);
+     DO_TEST("clock-timer-hyperv-rtc", NONE);
++    DO_TEST_CAPS_ARCH_LATEST("clock-timer-armvtimer", "aarch64");
+ 
+     DO_TEST("cpu-eoi-disabled", NONE);
+     DO_TEST("cpu-eoi-enabled", NONE);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-add-host-CPU-data-files-for-validating-die_id.patch b/SOURCES/libvirt-tests-add-host-CPU-data-files-for-validating-die_id.patch
new file mode 100644
index 0000000..89c2fcb
--- /dev/null
+++ b/SOURCES/libvirt-tests-add-host-CPU-data-files-for-validating-die_id.patch
@@ -0,0 +1,2131 @@
+From a3d3caef97d7f052187fce8f81527f9a9f1ae74f Mon Sep 17 00:00:00 2001
+Message-Id: <a3d3caef97d7f052187fce8f81527f9a9f1ae74f@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
+Date: Mon, 3 Feb 2020 18:07:26 +0000
+Subject: [PATCH] tests: add host CPU data files for validating die_id
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Only Cascadelake-AP CPUs appear to report "die_id" values != 0 on Linux
+right now - AMD EPYC's don't report "die_id" (at least with Fedora 31
+kernel). Lacking access to Cascadelake-AP CPUs, this test data was from
+a Fedora 31 QEMU guest launched with
+
+ -cpu qemu64 -smp sockets=2,dies=3,cores=2,threads=1
+
+Ideally we'd replace this data with some from a real machine reporting
+"die_id", to ensure we're not mislead by QEMU's impl.
+
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 0169f5ecdeefb91463b07a2e6f3f3b40c84323e9)
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785207
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1785211
+Message-Id: <20200203180726.2203691-6-berrange@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ .../linux-basic-dies/system/cpu               |   1 +
+ .../linux-basic-dies/system/node              |   1 +
+ .../vircaps-x86_64-basic-dies.xml             |  35 ++
+ tests/vircaps2xmltest.c                       |   1 +
+ .../cpu/cpu0/topology/core_cpus               |   1 +
+ .../cpu/cpu0/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu0/topology/core_id  |   1 +
+ .../cpu/cpu0/topology/core_siblings           |   1 +
+ .../cpu/cpu0/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu0/topology/die_cpus |   1 +
+ .../cpu/cpu0/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu0/topology/die_id   |   1 +
+ .../cpu/cpu0/topology/package_cpus            |   1 +
+ .../cpu/cpu0/topology/package_cpus_list       |   1 +
+ .../cpu/cpu0/topology/physical_package_id     |   1 +
+ .../cpu/cpu0/topology/thread_siblings         |   1 +
+ .../cpu/cpu0/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu1/online            |   1 +
+ .../cpu/cpu1/topology/core_cpus               |   1 +
+ .../cpu/cpu1/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu1/topology/core_id  |   1 +
+ .../cpu/cpu1/topology/core_siblings           |   1 +
+ .../cpu/cpu1/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu1/topology/die_cpus |   1 +
+ .../cpu/cpu1/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu1/topology/die_id   |   1 +
+ .../cpu/cpu1/topology/package_cpus            |   1 +
+ .../cpu/cpu1/topology/package_cpus_list       |   1 +
+ .../cpu/cpu1/topology/physical_package_id     |   1 +
+ .../cpu/cpu1/topology/thread_siblings         |   1 +
+ .../cpu/cpu1/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu10/online           |   1 +
+ .../cpu/cpu10/topology/core_cpus              |   1 +
+ .../cpu/cpu10/topology/core_cpus_list         |   1 +
+ .../linux-with-die/cpu/cpu10/topology/core_id |   1 +
+ .../cpu/cpu10/topology/core_siblings          |   1 +
+ .../cpu/cpu10/topology/core_siblings_list     |   1 +
+ .../cpu/cpu10/topology/die_cpus               |   1 +
+ .../cpu/cpu10/topology/die_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu10/topology/die_id  |   1 +
+ .../cpu/cpu10/topology/package_cpus           |   1 +
+ .../cpu/cpu10/topology/package_cpus_list      |   1 +
+ .../cpu/cpu10/topology/physical_package_id    |   1 +
+ .../cpu/cpu10/topology/thread_siblings        |   1 +
+ .../cpu/cpu10/topology/thread_siblings_list   |   1 +
+ .../linux-with-die/cpu/cpu11/online           |   1 +
+ .../cpu/cpu11/topology/core_cpus              |   1 +
+ .../cpu/cpu11/topology/core_cpus_list         |   1 +
+ .../linux-with-die/cpu/cpu11/topology/core_id |   1 +
+ .../cpu/cpu11/topology/core_siblings          |   1 +
+ .../cpu/cpu11/topology/core_siblings_list     |   1 +
+ .../cpu/cpu11/topology/die_cpus               |   1 +
+ .../cpu/cpu11/topology/die_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu11/topology/die_id  |   1 +
+ .../cpu/cpu11/topology/package_cpus           |   1 +
+ .../cpu/cpu11/topology/package_cpus_list      |   1 +
+ .../cpu/cpu11/topology/physical_package_id    |   1 +
+ .../cpu/cpu11/topology/thread_siblings        |   1 +
+ .../cpu/cpu11/topology/thread_siblings_list   |   1 +
+ .../linux-with-die/cpu/cpu2/online            |   1 +
+ .../cpu/cpu2/topology/core_cpus               |   1 +
+ .../cpu/cpu2/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu2/topology/core_id  |   1 +
+ .../cpu/cpu2/topology/core_siblings           |   1 +
+ .../cpu/cpu2/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu2/topology/die_cpus |   1 +
+ .../cpu/cpu2/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu2/topology/die_id   |   1 +
+ .../cpu/cpu2/topology/package_cpus            |   1 +
+ .../cpu/cpu2/topology/package_cpus_list       |   1 +
+ .../cpu/cpu2/topology/physical_package_id     |   1 +
+ .../cpu/cpu2/topology/thread_siblings         |   1 +
+ .../cpu/cpu2/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu3/online            |   1 +
+ .../cpu/cpu3/topology/core_cpus               |   1 +
+ .../cpu/cpu3/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu3/topology/core_id  |   1 +
+ .../cpu/cpu3/topology/core_siblings           |   1 +
+ .../cpu/cpu3/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu3/topology/die_cpus |   1 +
+ .../cpu/cpu3/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu3/topology/die_id   |   1 +
+ .../cpu/cpu3/topology/package_cpus            |   1 +
+ .../cpu/cpu3/topology/package_cpus_list       |   1 +
+ .../cpu/cpu3/topology/physical_package_id     |   1 +
+ .../cpu/cpu3/topology/thread_siblings         |   1 +
+ .../cpu/cpu3/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu4/online            |   1 +
+ .../cpu/cpu4/topology/core_cpus               |   1 +
+ .../cpu/cpu4/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu4/topology/core_id  |   1 +
+ .../cpu/cpu4/topology/core_siblings           |   1 +
+ .../cpu/cpu4/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu4/topology/die_cpus |   1 +
+ .../cpu/cpu4/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu4/topology/die_id   |   1 +
+ .../cpu/cpu4/topology/package_cpus            |   1 +
+ .../cpu/cpu4/topology/package_cpus_list       |   1 +
+ .../cpu/cpu4/topology/physical_package_id     |   1 +
+ .../cpu/cpu4/topology/thread_siblings         |   1 +
+ .../cpu/cpu4/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu5/online            |   1 +
+ .../cpu/cpu5/topology/core_cpus               |   1 +
+ .../cpu/cpu5/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu5/topology/core_id  |   1 +
+ .../cpu/cpu5/topology/core_siblings           |   1 +
+ .../cpu/cpu5/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu5/topology/die_cpus |   1 +
+ .../cpu/cpu5/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu5/topology/die_id   |   1 +
+ .../cpu/cpu5/topology/package_cpus            |   1 +
+ .../cpu/cpu5/topology/package_cpus_list       |   1 +
+ .../cpu/cpu5/topology/physical_package_id     |   1 +
+ .../cpu/cpu5/topology/thread_siblings         |   1 +
+ .../cpu/cpu5/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu6/online            |   1 +
+ .../cpu/cpu6/topology/core_cpus               |   1 +
+ .../cpu/cpu6/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu6/topology/core_id  |   1 +
+ .../cpu/cpu6/topology/core_siblings           |   1 +
+ .../cpu/cpu6/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu6/topology/die_cpus |   1 +
+ .../cpu/cpu6/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu6/topology/die_id   |   1 +
+ .../cpu/cpu6/topology/package_cpus            |   1 +
+ .../cpu/cpu6/topology/package_cpus_list       |   1 +
+ .../cpu/cpu6/topology/physical_package_id     |   1 +
+ .../cpu/cpu6/topology/thread_siblings         |   1 +
+ .../cpu/cpu6/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu7/online            |   1 +
+ .../cpu/cpu7/topology/core_cpus               |   1 +
+ .../cpu/cpu7/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu7/topology/core_id  |   1 +
+ .../cpu/cpu7/topology/core_siblings           |   1 +
+ .../cpu/cpu7/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu7/topology/die_cpus |   1 +
+ .../cpu/cpu7/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu7/topology/die_id   |   1 +
+ .../cpu/cpu7/topology/package_cpus            |   1 +
+ .../cpu/cpu7/topology/package_cpus_list       |   1 +
+ .../cpu/cpu7/topology/physical_package_id     |   1 +
+ .../cpu/cpu7/topology/thread_siblings         |   1 +
+ .../cpu/cpu7/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu8/online            |   1 +
+ .../cpu/cpu8/topology/core_cpus               |   1 +
+ .../cpu/cpu8/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu8/topology/core_id  |   1 +
+ .../cpu/cpu8/topology/core_siblings           |   1 +
+ .../cpu/cpu8/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu8/topology/die_cpus |   1 +
+ .../cpu/cpu8/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu8/topology/die_id   |   1 +
+ .../cpu/cpu8/topology/package_cpus            |   1 +
+ .../cpu/cpu8/topology/package_cpus_list       |   1 +
+ .../cpu/cpu8/topology/physical_package_id     |   1 +
+ .../cpu/cpu8/topology/thread_siblings         |   1 +
+ .../cpu/cpu8/topology/thread_siblings_list    |   1 +
+ .../linux-with-die/cpu/cpu9/online            |   1 +
+ .../cpu/cpu9/topology/core_cpus               |   1 +
+ .../cpu/cpu9/topology/core_cpus_list          |   1 +
+ .../linux-with-die/cpu/cpu9/topology/core_id  |   1 +
+ .../cpu/cpu9/topology/core_siblings           |   1 +
+ .../cpu/cpu9/topology/core_siblings_list      |   1 +
+ .../linux-with-die/cpu/cpu9/topology/die_cpus |   1 +
+ .../cpu/cpu9/topology/die_cpus_list           |   1 +
+ .../linux-with-die/cpu/cpu9/topology/die_id   |   1 +
+ .../cpu/cpu9/topology/package_cpus            |   1 +
+ .../cpu/cpu9/topology/package_cpus_list       |   1 +
+ .../cpu/cpu9/topology/physical_package_id     |   1 +
+ .../cpu/cpu9/topology/thread_siblings         |   1 +
+ .../cpu/cpu9/topology/thread_siblings_list    |   1 +
+ .../virhostcpudata/linux-with-die/cpu/online  |   1 +
+ .../virhostcpudata/linux-with-die/cpu/present |   1 +
+ .../linux-with-die/node/node0/cpu0            |   1 +
+ .../linux-with-die/node/node0/cpu1            |   1 +
+ .../linux-with-die/node/node0/cpu10           |   1 +
+ .../linux-with-die/node/node0/cpu11           |   1 +
+ .../linux-with-die/node/node0/cpu2            |   1 +
+ .../linux-with-die/node/node0/cpu3            |   1 +
+ .../linux-with-die/node/node0/cpu4            |   1 +
+ .../linux-with-die/node/node0/cpu5            |   1 +
+ .../linux-with-die/node/node0/cpu6            |   1 +
+ .../linux-with-die/node/node0/cpu7            |   1 +
+ .../linux-with-die/node/node0/cpu8            |   1 +
+ .../linux-with-die/node/node0/cpu9            |   1 +
+ .../linux-with-die/node/node0/cpulist         |   1 +
+ .../virhostcpudata/linux-with-die/node/online |   1 +
+ .../linux-with-die/node/possible              |   1 +
+ .../linux-x86_64-with-die.cpuinfo             | 323 ++++++++++++++++++
+ .../linux-x86_64-with-die.expected            |   1 +
+ tests/virhostcputest.c                        |   1 +
+ 191 files changed, 547 insertions(+)
+ create mode 120000 tests/vircaps2xmldata/linux-basic-dies/system/cpu
+ create mode 120000 tests/vircaps2xmldata/linux-basic-dies/system/node
+ create mode 100644 tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/physical_package_id
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings_list
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/cpu/present
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu0
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu1
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu10
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu11
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu2
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu3
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu4
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu5
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu6
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu7
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu8
+ create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu9
+ create mode 100644 tests/virhostcpudata/linux-with-die/node/node0/cpulist
+ create mode 100644 tests/virhostcpudata/linux-with-die/node/online
+ create mode 100644 tests/virhostcpudata/linux-with-die/node/possible
+ create mode 100644 tests/virhostcpudata/linux-x86_64-with-die.cpuinfo
+ create mode 100644 tests/virhostcpudata/linux-x86_64-with-die.expected
+
+diff --git a/tests/vircaps2xmldata/linux-basic-dies/system/cpu b/tests/vircaps2xmldata/linux-basic-dies/system/cpu
+new file mode 120000
+index 0000000000..af158a7097
+--- /dev/null
++++ b/tests/vircaps2xmldata/linux-basic-dies/system/cpu
+@@ -0,0 +1 @@
++../../../virhostcpudata/linux-with-die/cpu
+\ No newline at end of file
+diff --git a/tests/vircaps2xmldata/linux-basic-dies/system/node b/tests/vircaps2xmldata/linux-basic-dies/system/node
+new file mode 120000
+index 0000000000..68bc88ea14
+--- /dev/null
++++ b/tests/vircaps2xmldata/linux-basic-dies/system/node
+@@ -0,0 +1 @@
++../../../virhostcpudata/linux-with-die/node
+\ No newline at end of file
+diff --git a/tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml b/tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml
+new file mode 100644
+index 0000000000..8a3ca2d13c
+--- /dev/null
++++ b/tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml
+@@ -0,0 +1,35 @@
++<capabilities>
++
++  <host>
++    <cpu>
++      <arch>x86_64</arch>
++    </cpu>
++    <power_management/>
++    <iommu support='no'/>
++    <topology>
++      <cells num='1'>
++        <cell id='0'>
++          <memory unit='KiB'>1048576</memory>
++          <pages unit='KiB' size='4'>2048</pages>
++          <pages unit='KiB' size='2048'>4096</pages>
++          <pages unit='KiB' size='1048576'>6144</pages>
++          <cpus num='12'>
++            <cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
++            <cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
++            <cpu id='2' socket_id='0' die_id='1' core_id='0' siblings='2'/>
++            <cpu id='3' socket_id='0' die_id='1' core_id='1' siblings='3'/>
++            <cpu id='4' socket_id='0' die_id='2' core_id='0' siblings='4'/>
++            <cpu id='5' socket_id='0' die_id='2' core_id='1' siblings='5'/>
++            <cpu id='6' socket_id='1' die_id='0' core_id='0' siblings='6'/>
++            <cpu id='7' socket_id='1' die_id='0' core_id='1' siblings='7'/>
++            <cpu id='8' socket_id='1' die_id='1' core_id='0' siblings='8'/>
++            <cpu id='9' socket_id='1' die_id='1' core_id='1' siblings='9'/>
++            <cpu id='10' socket_id='1' die_id='2' core_id='0' siblings='10'/>
++            <cpu id='11' socket_id='1' die_id='2' core_id='1' siblings='11'/>
++          </cpus>
++        </cell>
++      </cells>
++    </topology>
++  </host>
++
++</capabilities>
+diff --git a/tests/vircaps2xmltest.c b/tests/vircaps2xmltest.c
+index 6c08a26ec4..17cd600a7a 100644
+--- a/tests/vircaps2xmltest.c
++++ b/tests/vircaps2xmltest.c
+@@ -102,6 +102,7 @@ mymain(void)
+ 
+     DO_TEST_FULL("basic", VIR_ARCH_X86_64, false, false);
+     DO_TEST_FULL("basic", VIR_ARCH_AARCH64, true, false);
++    DO_TEST_FULL("basic-dies", VIR_ARCH_X86_64, false, false);
+ 
+     DO_TEST_FULL("caches", VIR_ARCH_X86_64, true, true);
+ 
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus
+new file mode 100644
+index 0000000000..5325a8dff7
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus
+@@ -0,0 +1 @@
++001
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus_list
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus_list
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus
+new file mode 100644
+index 0000000000..d7887218f9
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus
+@@ -0,0 +1 @@
++003
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus_list
+new file mode 100644
+index 0000000000..8b0fab869c
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus_list
+@@ -0,0 +1 @@
++0-1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/physical_package_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/physical_package_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings
+new file mode 100644
+index 0000000000..5325a8dff7
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings
+@@ -0,0 +1 @@
++001
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings_list
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/online b/tests/virhostcpudata/linux-with-die/cpu/cpu1/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus
+new file mode 100644
+index 0000000000..5902f77e7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus
+@@ -0,0 +1 @@
++002
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus_list
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus_list
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus
+new file mode 100644
+index 0000000000..d7887218f9
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus
+@@ -0,0 +1 @@
++003
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus_list
+new file mode 100644
+index 0000000000..8b0fab869c
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus_list
+@@ -0,0 +1 @@
++0-1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/physical_package_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/physical_package_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings
+new file mode 100644
+index 0000000000..5902f77e7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings
+@@ -0,0 +1 @@
++002
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings_list
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/online b/tests/virhostcpudata/linux-with-die/cpu/cpu10/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus
+new file mode 100644
+index 0000000000..d411bb7c1a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus
+@@ -0,0 +1 @@
++400
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus_list
+new file mode 100644
+index 0000000000..f599e28b8a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus_list
+@@ -0,0 +1 @@
++10
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus
+new file mode 100644
+index 0000000000..a94266dd91
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus
+@@ -0,0 +1 @@
++c00
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus_list
+new file mode 100644
+index 0000000000..ac93dc4496
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus_list
+@@ -0,0 +1 @@
++10-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_id
+new file mode 100644
+index 0000000000..0cfbf08886
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_id
+@@ -0,0 +1 @@
++2
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/physical_package_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/physical_package_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings
+new file mode 100644
+index 0000000000..d411bb7c1a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings
+@@ -0,0 +1 @@
++400
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..f599e28b8a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings_list
+@@ -0,0 +1 @@
++10
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/online b/tests/virhostcpudata/linux-with-die/cpu/cpu11/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus
+new file mode 100644
+index 0000000000..5ae5aef844
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus
+@@ -0,0 +1 @@
++800
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus_list
+new file mode 100644
+index 0000000000..b4de394767
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus_list
+@@ -0,0 +1 @@
++11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus
+new file mode 100644
+index 0000000000..a94266dd91
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus
+@@ -0,0 +1 @@
++c00
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus_list
+new file mode 100644
+index 0000000000..ac93dc4496
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus_list
+@@ -0,0 +1 @@
++10-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_id
+new file mode 100644
+index 0000000000..0cfbf08886
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_id
+@@ -0,0 +1 @@
++2
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/physical_package_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/physical_package_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings
+new file mode 100644
+index 0000000000..5ae5aef844
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings
+@@ -0,0 +1 @@
++800
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..b4de394767
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings_list
+@@ -0,0 +1 @@
++11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/online b/tests/virhostcpudata/linux-with-die/cpu/cpu2/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus
+new file mode 100644
+index 0000000000..8f3cca4f01
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus
+@@ -0,0 +1 @@
++004
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus_list
+new file mode 100644
+index 0000000000..0cfbf08886
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus_list
+@@ -0,0 +1 @@
++2
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus
+new file mode 100644
+index 0000000000..3138e83a00
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus
+@@ -0,0 +1 @@
++00c
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus_list
+new file mode 100644
+index 0000000000..7a9857542a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus_list
+@@ -0,0 +1 @@
++2-3
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/physical_package_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/physical_package_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings
+new file mode 100644
+index 0000000000..8f3cca4f01
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings
+@@ -0,0 +1 @@
++004
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..0cfbf08886
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings_list
+@@ -0,0 +1 @@
++2
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/online b/tests/virhostcpudata/linux-with-die/cpu/cpu3/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus
+new file mode 100644
+index 0000000000..e195199bee
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus
+@@ -0,0 +1 @@
++008
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus_list
+new file mode 100644
+index 0000000000..00750edc07
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus_list
+@@ -0,0 +1 @@
++3
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus
+new file mode 100644
+index 0000000000..3138e83a00
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus
+@@ -0,0 +1 @@
++00c
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus_list
+new file mode 100644
+index 0000000000..7a9857542a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus_list
+@@ -0,0 +1 @@
++2-3
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/physical_package_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/physical_package_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings
+new file mode 100644
+index 0000000000..e195199bee
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings
+@@ -0,0 +1 @@
++008
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..00750edc07
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings_list
+@@ -0,0 +1 @@
++3
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/online b/tests/virhostcpudata/linux-with-die/cpu/cpu4/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus
+new file mode 100644
+index 0000000000..9e8493eaee
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus
+@@ -0,0 +1 @@
++010
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus_list
+new file mode 100644
+index 0000000000..b8626c4cff
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus_list
+@@ -0,0 +1 @@
++4
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus
+new file mode 100644
+index 0000000000..cadb715e0d
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus
+@@ -0,0 +1 @@
++030
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus_list
+new file mode 100644
+index 0000000000..e66d883ade
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus_list
+@@ -0,0 +1 @@
++4-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_id
+new file mode 100644
+index 0000000000..0cfbf08886
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_id
+@@ -0,0 +1 @@
++2
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/physical_package_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/physical_package_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings
+new file mode 100644
+index 0000000000..9e8493eaee
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings
+@@ -0,0 +1 @@
++010
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..b8626c4cff
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings_list
+@@ -0,0 +1 @@
++4
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/online b/tests/virhostcpudata/linux-with-die/cpu/cpu5/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus
+new file mode 100644
+index 0000000000..fb6187e9e0
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus
+@@ -0,0 +1 @@
++020
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus_list
+new file mode 100644
+index 0000000000..7ed6ff82de
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus_list
+@@ -0,0 +1 @@
++5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus
+new file mode 100644
+index 0000000000..cadb715e0d
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus
+@@ -0,0 +1 @@
++030
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus_list
+new file mode 100644
+index 0000000000..e66d883ade
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus_list
+@@ -0,0 +1 @@
++4-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_id
+new file mode 100644
+index 0000000000..0cfbf08886
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_id
+@@ -0,0 +1 @@
++2
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus
+new file mode 100644
+index 0000000000..d37ac748bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus
+@@ -0,0 +1 @@
++03f
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus_list
+new file mode 100644
+index 0000000000..82a99f2907
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus_list
+@@ -0,0 +1 @@
++0-5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/physical_package_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/physical_package_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings
+new file mode 100644
+index 0000000000..fb6187e9e0
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings
+@@ -0,0 +1 @@
++020
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..7ed6ff82de
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings_list
+@@ -0,0 +1 @@
++5
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/online b/tests/virhostcpudata/linux-with-die/cpu/cpu6/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus
+new file mode 100644
+index 0000000000..9070bc3017
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus
+@@ -0,0 +1 @@
++040
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus_list
+new file mode 100644
+index 0000000000..1e8b314962
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus_list
+@@ -0,0 +1 @@
++6
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus
+new file mode 100644
+index 0000000000..8f0552ead0
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus
+@@ -0,0 +1 @@
++0c0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus_list
+new file mode 100644
+index 0000000000..fdd9f37517
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus_list
+@@ -0,0 +1 @@
++6-7
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/physical_package_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/physical_package_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings
+new file mode 100644
+index 0000000000..9070bc3017
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings
+@@ -0,0 +1 @@
++040
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..1e8b314962
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings_list
+@@ -0,0 +1 @@
++6
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/online b/tests/virhostcpudata/linux-with-die/cpu/cpu7/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus
+new file mode 100644
+index 0000000000..fa5c7835bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus
+@@ -0,0 +1 @@
++080
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus_list
+new file mode 100644
+index 0000000000..7f8f011eb7
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus_list
+@@ -0,0 +1 @@
++7
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus
+new file mode 100644
+index 0000000000..8f0552ead0
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus
+@@ -0,0 +1 @@
++0c0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus_list
+new file mode 100644
+index 0000000000..fdd9f37517
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus_list
+@@ -0,0 +1 @@
++6-7
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/physical_package_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/physical_package_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings
+new file mode 100644
+index 0000000000..fa5c7835bd
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings
+@@ -0,0 +1 @@
++080
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..7f8f011eb7
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings_list
+@@ -0,0 +1 @@
++7
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/online b/tests/virhostcpudata/linux-with-die/cpu/cpu8/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus
+new file mode 100644
+index 0000000000..29d6383b52
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus
+@@ -0,0 +1 @@
++100
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus_list
+new file mode 100644
+index 0000000000..45a4fb75db
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus_list
+@@ -0,0 +1 @@
++8
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_id
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_id
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus
+new file mode 100644
+index 0000000000..697cb3a26d
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus
+@@ -0,0 +1 @@
++300
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus_list
+new file mode 100644
+index 0000000000..63edceec1e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus_list
+@@ -0,0 +1 @@
++8-9
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/physical_package_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/physical_package_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings
+new file mode 100644
+index 0000000000..29d6383b52
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings
+@@ -0,0 +1 @@
++100
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..45a4fb75db
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings_list
+@@ -0,0 +1 @@
++8
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/online b/tests/virhostcpudata/linux-with-die/cpu/cpu9/online
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/online
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus
+new file mode 100644
+index 0000000000..08839f6bb2
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus
+@@ -0,0 +1 @@
++200
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus_list
+new file mode 100644
+index 0000000000..ec635144f6
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus_list
+@@ -0,0 +1 @@
++9
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_id b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus
+new file mode 100644
+index 0000000000..697cb3a26d
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus
+@@ -0,0 +1 @@
++300
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus_list
+new file mode 100644
+index 0000000000..63edceec1e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus_list
+@@ -0,0 +1 @@
++8-9
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_id b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus
+new file mode 100644
+index 0000000000..6c3274debe
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus
+@@ -0,0 +1 @@
++fc0
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus_list b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus_list
+new file mode 100644
+index 0000000000..fd6c445982
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus_list
+@@ -0,0 +1 @@
++6-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/physical_package_id b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/physical_package_id
+new file mode 100644
+index 0000000000..d00491fd7e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/physical_package_id
+@@ -0,0 +1 @@
++1
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings
+new file mode 100644
+index 0000000000..08839f6bb2
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings
+@@ -0,0 +1 @@
++200
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings_list b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings_list
+new file mode 100644
+index 0000000000..ec635144f6
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings_list
+@@ -0,0 +1 @@
++9
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/online b/tests/virhostcpudata/linux-with-die/cpu/online
+new file mode 100644
+index 0000000000..536e621dcc
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/online
+@@ -0,0 +1 @@
++0-11
+diff --git a/tests/virhostcpudata/linux-with-die/cpu/present b/tests/virhostcpudata/linux-with-die/cpu/present
+new file mode 100644
+index 0000000000..536e621dcc
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/cpu/present
+@@ -0,0 +1 @@
++0-11
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu0 b/tests/virhostcpudata/linux-with-die/node/node0/cpu0
+new file mode 120000
+index 0000000000..c841bea28b
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu0
+@@ -0,0 +1 @@
++../../cpu/cpu0
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu1 b/tests/virhostcpudata/linux-with-die/node/node0/cpu1
+new file mode 120000
+index 0000000000..5f4536279e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu1
+@@ -0,0 +1 @@
++../../cpu/cpu1
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu10 b/tests/virhostcpudata/linux-with-die/node/node0/cpu10
+new file mode 120000
+index 0000000000..a6dc6bb10e
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu10
+@@ -0,0 +1 @@
++../../cpu/cpu10
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu11 b/tests/virhostcpudata/linux-with-die/node/node0/cpu11
+new file mode 120000
+index 0000000000..e29d898284
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu11
+@@ -0,0 +1 @@
++../../cpu/cpu11
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu2 b/tests/virhostcpudata/linux-with-die/node/node0/cpu2
+new file mode 120000
+index 0000000000..2dcca332ce
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu2
+@@ -0,0 +1 @@
++../../cpu/cpu2
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu3 b/tests/virhostcpudata/linux-with-die/node/node0/cpu3
+new file mode 120000
+index 0000000000..c7690e5aa6
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu3
+@@ -0,0 +1 @@
++../../cpu/cpu3
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu4 b/tests/virhostcpudata/linux-with-die/node/node0/cpu4
+new file mode 120000
+index 0000000000..9e77a64eb4
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu4
+@@ -0,0 +1 @@
++../../cpu/cpu4
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu5 b/tests/virhostcpudata/linux-with-die/node/node0/cpu5
+new file mode 120000
+index 0000000000..cc07c3b97b
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu5
+@@ -0,0 +1 @@
++../../cpu/cpu5
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu6 b/tests/virhostcpudata/linux-with-die/node/node0/cpu6
+new file mode 120000
+index 0000000000..2e7576354f
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu6
+@@ -0,0 +1 @@
++../../cpu/cpu6
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu7 b/tests/virhostcpudata/linux-with-die/node/node0/cpu7
+new file mode 120000
+index 0000000000..09e3f79b43
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu7
+@@ -0,0 +1 @@
++../../cpu/cpu7
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu8 b/tests/virhostcpudata/linux-with-die/node/node0/cpu8
+new file mode 120000
+index 0000000000..bda10cc343
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu8
+@@ -0,0 +1 @@
++../../cpu/cpu8
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpu9 b/tests/virhostcpudata/linux-with-die/node/node0/cpu9
+new file mode 120000
+index 0000000000..1ec1db255a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpu9
+@@ -0,0 +1 @@
++../../cpu/cpu9
+\ No newline at end of file
+diff --git a/tests/virhostcpudata/linux-with-die/node/node0/cpulist b/tests/virhostcpudata/linux-with-die/node/node0/cpulist
+new file mode 100644
+index 0000000000..536e621dcc
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/node0/cpulist
+@@ -0,0 +1 @@
++0-11
+diff --git a/tests/virhostcpudata/linux-with-die/node/online b/tests/virhostcpudata/linux-with-die/node/online
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/online
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-with-die/node/possible b/tests/virhostcpudata/linux-with-die/node/possible
+new file mode 100644
+index 0000000000..573541ac97
+--- /dev/null
++++ b/tests/virhostcpudata/linux-with-die/node/possible
+@@ -0,0 +1 @@
++0
+diff --git a/tests/virhostcpudata/linux-x86_64-with-die.cpuinfo b/tests/virhostcpudata/linux-x86_64-with-die.cpuinfo
+new file mode 100644
+index 0000000000..f57be77f0c
+--- /dev/null
++++ b/tests/virhostcpudata/linux-x86_64-with-die.cpuinfo
+@@ -0,0 +1,323 @@
++processor	: 0
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 0
++siblings	: 6
++core id		: 0
++cpu cores	: 6
++apicid		: 0
++initial apicid	: 0
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 1
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 0
++siblings	: 6
++core id		: 1
++cpu cores	: 6
++apicid		: 1
++initial apicid	: 1
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 2
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 0
++siblings	: 6
++core id		: 0
++cpu cores	: 6
++apicid		: 2
++initial apicid	: 2
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 3
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 0
++siblings	: 6
++core id		: 1
++cpu cores	: 6
++apicid		: 3
++initial apicid	: 3
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 4
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 0
++siblings	: 6
++core id		: 0
++cpu cores	: 6
++apicid		: 4
++initial apicid	: 4
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 5
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 0
++siblings	: 6
++core id		: 1
++cpu cores	: 6
++apicid		: 5
++initial apicid	: 5
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 6
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 1
++siblings	: 6
++core id		: 0
++cpu cores	: 6
++apicid		: 8
++initial apicid	: 8
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 7
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 1
++siblings	: 6
++core id		: 1
++cpu cores	: 6
++apicid		: 9
++initial apicid	: 9
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 8
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 1
++siblings	: 6
++core id		: 0
++cpu cores	: 6
++apicid		: 10
++initial apicid	: 10
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 9
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 1
++siblings	: 6
++core id		: 1
++cpu cores	: 6
++apicid		: 11
++initial apicid	: 11
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 10
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 1
++siblings	: 6
++core id		: 0
++cpu cores	: 6
++apicid		: 12
++initial apicid	: 12
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
++
++processor	: 11
++vendor_id	: GenuineIntel
++cpu family	: 6
++model		: 6
++model name	: QEMU Virtual CPU version 2.5+
++stepping	: 3
++microcode	: 0x1
++cpu MHz		: 1897.801
++cache size	: 16384 KB
++physical id	: 1
++siblings	: 6
++core id		: 1
++cpu cores	: 6
++apicid		: 13
++initial apicid	: 13
++fpu		: yes
++fpu_exception	: yes
++cpuid level	: 31
++wp		: yes
++flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology cpuid tsc_known_freq pni cx16 x2apic hypervisor lahf_lm cpuid_fault pti
++bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs
++bogomips	: 3795.60
++clflush size	: 64
++cache_alignment	: 64
++address sizes	: 40 bits physical, 48 bits virtual
++power management:
+diff --git a/tests/virhostcpudata/linux-x86_64-with-die.expected b/tests/virhostcpudata/linux-x86_64-with-die.expected
+new file mode 100644
+index 0000000000..3c045f483a
+--- /dev/null
++++ b/tests/virhostcpudata/linux-x86_64-with-die.expected
+@@ -0,0 +1 @@
++CPUs: 12/12, MHz: 1897, Nodes: 1, Sockets: 1, Cores: 12, Threads: 1
+diff --git a/tests/virhostcputest.c b/tests/virhostcputest.c
+index 05c6f5acfb..7865b61578 100644
+--- a/tests/virhostcputest.c
++++ b/tests/virhostcputest.c
+@@ -248,6 +248,7 @@ mymain(void)
+         /* subcores, invalid configuration */
+         {"subcores3", VIR_ARCH_PPC64},
+         {"with-frequency", VIR_ARCH_S390X},
++        {"with-die", VIR_ARCH_X86_64},
+     };
+ 
+     if (virInitialize() < 0)
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-hash-Test-case-for-adding-duplicate-hash-entry.patch b/SOURCES/libvirt-tests-hash-Test-case-for-adding-duplicate-hash-entry.patch
new file mode 100644
index 0000000..53106c2
--- /dev/null
+++ b/SOURCES/libvirt-tests-hash-Test-case-for-adding-duplicate-hash-entry.patch
@@ -0,0 +1,68 @@
+From cbdb97e438e9e45b4c0219e95a1d638d03faa8ae Mon Sep 17 00:00:00 2001
+Message-Id: <cbdb97e438e9e45b4c0219e95a1d638d03faa8ae@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:44 +0100
+Subject: [PATCH] tests: hash: Test case for adding duplicate hash entry
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Test that adding a duplicate entry is rejected properly. This also
+allows to see the error message of the duplicate key addition in verbose
+mode.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 7134f26b73162536b8bea2af860b32bad6a7f965)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <9bec2f7b4dc1be3ec963efa667c93ff225e9a0b6.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virhashtest.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/tests/virhashtest.c b/tests/virhashtest.c
+index 66fa3a428e..4d05cbb0f8 100644
+--- a/tests/virhashtest.c
++++ b/tests/virhashtest.c
+@@ -510,6 +510,28 @@ testHashEqual(const void *data G_GNUC_UNUSED)
+ }
+ 
+ 
++static int
++testHashDuplicate(const void *data G_GNUC_UNUSED)
++{
++    g_autoptr(virHashTable) hash = NULL;
++
++    if (!(hash = virHashCreate(0, NULL)))
++        return -1;
++
++    if (virHashAddEntry(hash, "a", NULL) < 0) {
++        VIR_TEST_VERBOSE("\nfailed to add key 'a' to hash");
++        return -1;
++    }
++
++    if (virHashAddEntry(hash, "a", NULL) >= 0) {
++        VIR_TEST_VERBOSE("\nadding of key 'a' should have failed");
++        return -1;
++    }
++
++    return 0;
++}
++
++
+ static int
+ mymain(void)
+ {
+@@ -546,6 +568,7 @@ mymain(void)
+     DO_TEST("Search", Search);
+     DO_TEST("GetItems", GetItems);
+     DO_TEST("Equal", Equal);
++    DO_TEST("Duplicate entry", Duplicate);
+ 
+     return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemu-Add-test-data-for-the-new-slice-element.patch b/SOURCES/libvirt-tests-qemu-Add-test-data-for-the-new-slice-element.patch
new file mode 100644
index 0000000..2666454
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemu-Add-test-data-for-the-new-slice-element.patch
@@ -0,0 +1,232 @@
+From 6e2efb5b67a6d1a65c4e4facb7013f5e24622591 Mon Sep 17 00:00:00 2001
+Message-Id: <6e2efb5b67a6d1a65c4e4facb7013f5e24622591@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:25 +0100
+Subject: [PATCH] tests: qemu: Add test data for the new <slice> element
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 293e7750c9c26ac19ed4fafa9c9f1fe3e90d5078)
+
+ Changes:
+  tests/qemuxml2argvdata/disk-slices.x86_64-latest.args
+  tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml
+
+ Due to missing backport of changes related to CPU detection there is
+ difference in the XML files in unrelated parts.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Message-Id: <21b28fdf8e4fc8aaf9a68b8c32be5d5a1fdedacc.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ .../disk-slices.x86_64-latest.args            | 52 ++++++++++++++++++
+ tests/qemuxml2argvdata/disk-slices.xml        | 45 ++++++++++++++++
+ tests/qemuxml2argvtest.c                      |  2 +
+ .../disk-slices.x86_64-latest.xml             | 53 +++++++++++++++++++
+ tests/qemuxml2xmltest.c                       |  2 +
+ 5 files changed, 154 insertions(+)
+ create mode 100644 tests/qemuxml2argvdata/disk-slices.x86_64-latest.args
+ create mode 100644 tests/qemuxml2argvdata/disk-slices.xml
+ create mode 100644 tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml
+
+diff --git a/tests/qemuxml2argvdata/disk-slices.x86_64-latest.args b/tests/qemuxml2argvdata/disk-slices.x86_64-latest.args
+new file mode 100644
+index 0000000000..661b3f7ea1
+--- /dev/null
++++ b/tests/qemuxml2argvdata/disk-slices.x86_64-latest.args
+@@ -0,0 +1,52 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-QEMUGuest1 \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-i386 \
++-name guest=QEMUGuest1,debug-threads=on \
++-S \
++-object secret,id=masterKey0,format=raw,\
++file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
++-machine pc,accel=tcg,usb=off,dump-guest-core=off \
++-m 214 \
++-overcommit mem-lock=off \
++-smp 1,sockets=1,cores=1,threads=1 \
++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,fd=1729,server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-no-acpi \
++-boot strict=on \
++-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
++-blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/raw.img",\
++"node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-3-format","read-only":false,"driver":"raw",\
++"offset":1234,"size":321,"file":"libvirt-3-storage"}' \
++-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x2,drive=libvirt-3-format,\
++id=virtio-disk0,bootindex=1 \
++-blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/raw.img",\
++"node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"driver":"raw","node-name":"libvirt-2-slice-sto","offset":9876,\
++"size":123456789,"file":"libvirt-2-storage","auto-read-only":true,\
++"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-2-format","read-only":true,"driver":"qcow2",\
++"file":"libvirt-2-slice-sto","backing":null}' \
++-blockdev '{"driver":"file","filename":"/var/lib/libvirt/images/overlay.qcow2",\
++"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
++-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2",\
++"file":"libvirt-1-storage","backing":"libvirt-2-format"}' \
++-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=libvirt-1-format,\
++id=virtio-disk1 \
++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 \
++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
++resourcecontrol=deny \
++-msg timestamp=on
+diff --git a/tests/qemuxml2argvdata/disk-slices.xml b/tests/qemuxml2argvdata/disk-slices.xml
+new file mode 100644
+index 0000000000..cff7cc7ee4
+--- /dev/null
++++ b/tests/qemuxml2argvdata/disk-slices.xml
+@@ -0,0 +1,45 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='i686' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <disk type='file' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source file='/var/lib/libvirt/images/raw.img'>
++        <slices>
++          <slice type='storage' offset='1234' size='321'/>
++        </slices>
++      </source>
++      <backingStore/>
++      <target dev='vda' bus='virtio'/>
++    </disk>
++    <disk type='file' device='disk'>
++      <driver name='qemu' type='qcow2'/>
++      <source file='/var/lib/libvirt/images/overlay.qcow2'/>
++      <backingStore type='file'>
++        <format type='qcow2'/>
++        <source file='/var/lib/libvirt/images/raw.img'>
++          <slices>
++            <slice type='storage' offset='9876' size='123456789'/>
++          </slices>
++        </source>
++        <backingStore/>
++      </backingStore>
++      <target dev='vdb' bus='virtio'/>
++    </disk>
++    <controller type='usb'/>
++    <controller type='pci' model='pci-root'/>
++    <memballoon model='virtio'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index 508dfee3fb..8215935bab 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1162,6 +1162,8 @@ mymain(void)
+     DO_TEST_CAPS_VER("disk-backing-chains-noindex", "2.12.0");
+     DO_TEST_CAPS_LATEST("disk-backing-chains-noindex");
+ 
++    DO_TEST_CAPS_LATEST("disk-slices");
++
+     DO_TEST("graphics-egl-headless",
+             QEMU_CAPS_EGL_HEADLESS,
+             QEMU_CAPS_DEVICE_CIRRUS_VGA);
+diff --git a/tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml
+new file mode 100644
+index 0000000000..8a56936910
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/disk-slices.x86_64-latest.xml
+@@ -0,0 +1,53 @@
++<domain type='qemu'>
++  <name>QEMUGuest1</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='i686' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <disk type='file' device='disk'>
++      <driver name='qemu' type='raw'/>
++      <source file='/var/lib/libvirt/images/raw.img'>
++        <slices>
++          <slice type='storage' offset='1234' size='321'/>
++        </slices>
++      </source>
++      <backingStore/>
++      <target dev='vda' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
++    </disk>
++    <disk type='file' device='disk'>
++      <driver name='qemu' type='qcow2'/>
++      <source file='/var/lib/libvirt/images/overlay.qcow2'/>
++      <backingStore type='file'>
++        <format type='qcow2'/>
++        <source file='/var/lib/libvirt/images/raw.img'>
++          <slices>
++            <slice type='storage' offset='9876' size='123456789'/>
++          </slices>
++        </source>
++        <backingStore/>
++      </backingStore>
++      <target dev='vdb' bus='virtio'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </disk>
++    <controller type='usb' index='0' model='piix3-uhci'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='virtio'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
++    </memballoon>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index 6a8ae9f7eb..a3c7f8fd47 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -527,6 +527,8 @@ mymain(void)
+     DO_TEST("pci-rom-disabled-invalid", NONE);
+     DO_TEST("pci-serial-dev-chardev", NONE);
+ 
++    DO_TEST_CAPS_LATEST("disk-slices");
++
+     DO_TEST("encrypted-disk", QEMU_CAPS_QCOW2_LUKS);
+     DO_TEST("encrypted-disk-usage", QEMU_CAPS_QCOW2_LUKS);
+     DO_TEST("luks-disks", NONE);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublock-Add-cases-for-creating-image-overlays-on-top-of-disks-with-slice.patch b/SOURCES/libvirt-tests-qemublock-Add-cases-for-creating-image-overlays-on-top-of-disks-with-slice.patch
new file mode 100644
index 0000000..a678628
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublock-Add-cases-for-creating-image-overlays-on-top-of-disks-with-slice.patch
@@ -0,0 +1,151 @@
+From 54c8ab3178409f52113c99dca660c1024573ef7e Mon Sep 17 00:00:00 2001
+Message-Id: <54c8ab3178409f52113c99dca660c1024573ef7e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:23 +0100
+Subject: [PATCH] tests: qemublock: Add cases for creating image overlays on
+ top of disks with <slice>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a set of test data to see whether the backing store strings are
+formatted reasonably. Note that we don't support direct creation of such
+images so those tests are not enabled.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 9b804ef5efcd3b1e91bbf75f4e94a35630c062c5)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <6639bab2e1e9dbdf13471057a1cb3accd1c30549.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                             |  2 ++
+ .../imagecreate/qcow2-backing-qcow2-slice.json    | 15 +++++++++++++++
+ .../imagecreate/qcow2-backing-qcow2-slice.xml     |  1 +
+ .../imagecreate/qcow2-backing-raw-slice.json      | 15 +++++++++++++++
+ .../imagecreate/qcow2-backing-raw-slice.xml       |  1 +
+ .../qemublocktestdata/imagecreate/qcow2-slice.xml | 14 ++++++++++++++
+ tests/qemublocktestdata/imagecreate/raw-slice.xml | 14 ++++++++++++++
+ 7 files changed, 62 insertions(+)
+ create mode 100644 tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json
+ create mode 120000 tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.xml
+ create mode 100644 tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json
+ create mode 120000 tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.xml
+ create mode 100644 tests/qemublocktestdata/imagecreate/qcow2-slice.xml
+ create mode 100644 tests/qemublocktestdata/imagecreate/raw-slice.xml
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index f66d894aed..29af0781fc 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1060,6 +1060,8 @@ mymain(void)
+     TEST_IMAGE_CREATE("qcow2-backing-raw-nbd", "raw-nbd");
+     TEST_IMAGE_CREATE("qcow2-backing-luks", "luks-noopts");
+     TEST_IMAGE_CREATE("qcow2-luks-encopts-backing", "qcow2");
++    TEST_IMAGE_CREATE("qcow2-backing-raw-slice", "raw-slice");
++    TEST_IMAGE_CREATE("qcow2-backing-qcow2-slice", "qcow2-slice");
+ 
+     TEST_IMAGE_CREATE("network-gluster-qcow2", NULL);
+     TEST_IMAGE_CREATE("network-rbd-qcow2", NULL);
+diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json
+new file mode 100644
+index 0000000000..2fa27c1933
+--- /dev/null
++++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json
+@@ -0,0 +1,15 @@
++protocol:
++{
++  "driver": "file",
++  "filename": "/var/lib/libvirt/images/i.qcow2",
++  "size": 4294967296
++}
++
++format:
++{
++  "driver": "qcow2",
++  "file": "0123456789ABCDEF0123456789ABCDE",
++  "size": 8589934590,
++  "backing-file": "json:{\"driver\":\"raw\",\"offset\":1234,\"size\":5768,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.qcow2\"}}",
++  "backing-fmt": "qcow2"
++}
+diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.xml b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.xml
+new file mode 120000
+index 0000000000..5769c2c866
+--- /dev/null
++++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.xml
+@@ -0,0 +1 @@
++qcow2.xml
+\ No newline at end of file
+diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json
+new file mode 100644
+index 0000000000..761002afd9
+--- /dev/null
++++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json
+@@ -0,0 +1,15 @@
++protocol:
++{
++  "driver": "file",
++  "filename": "/var/lib/libvirt/images/i.qcow2",
++  "size": 4294967296
++}
++
++format:
++{
++  "driver": "qcow2",
++  "file": "0123456789ABCDEF0123456789ABCDE",
++  "size": 8589934590,
++  "backing-file": "json:{\"driver\":\"raw\",\"offset\":9876,\"size\":54321,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.img\"}}",
++  "backing-fmt": "raw"
++}
+diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.xml b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.xml
+new file mode 120000
+index 0000000000..5769c2c866
+--- /dev/null
++++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.xml
+@@ -0,0 +1 @@
++qcow2.xml
+\ No newline at end of file
+diff --git a/tests/qemublocktestdata/imagecreate/qcow2-slice.xml b/tests/qemublocktestdata/imagecreate/qcow2-slice.xml
+new file mode 100644
+index 0000000000..6c5ae3107b
+--- /dev/null
++++ b/tests/qemublocktestdata/imagecreate/qcow2-slice.xml
+@@ -0,0 +1,14 @@
++<disk device='disk' name='vda'>
++  <driver type='qcow2'/>
++  <source file='/var/lib/libvirt/images/i.qcow2'>
++    <slices>
++      <slice type='storage' offset='1234' size='5768'/>
++    </slices>
++    <privateData>
++      <nodenames>
++        <nodename type='storage' name='0123456789ABCDEF0123456789ABCDE'/>
++        <nodename type='format' name='0123456789ABCDEF0123456789ABCDE'/>
++      </nodenames>
++    </privateData>
++  </source>
++</disk>
+diff --git a/tests/qemublocktestdata/imagecreate/raw-slice.xml b/tests/qemublocktestdata/imagecreate/raw-slice.xml
+new file mode 100644
+index 0000000000..adc7a175ce
+--- /dev/null
++++ b/tests/qemublocktestdata/imagecreate/raw-slice.xml
+@@ -0,0 +1,14 @@
++<disk device='disk' name='vda'>
++  <driver type='raw'/>
++  <source file='/var/lib/libvirt/images/i.img'>
++    <slices>
++      <slice type='storage' offset='9876' size='54321'/>
++    </slices>
++    <privateData>
++      <nodenames>
++        <nodename type='storage' name='0123456789ABCDEF0123456789ABCDE'/>
++        <nodename type='format' name='0123456789ABCDEF0123456789ABCDE'/>
++      </nodenames>
++    </privateData>
++  </source>
++</disk>
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublock-Add-checkpoint-deletion-test-for-deep-backing-chain.patch b/SOURCES/libvirt-tests-qemublock-Add-checkpoint-deletion-test-for-deep-backing-chain.patch
new file mode 100644
index 0000000..cdbf03f
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublock-Add-checkpoint-deletion-test-for-deep-backing-chain.patch
@@ -0,0 +1,276 @@
+From 5694a24b527b812e7236a7316271f4ae316e4caa Mon Sep 17 00:00:00 2001
+Message-Id: <5694a24b527b812e7236a7316271f4ae316e4caa@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:13 +0100
+Subject: [PATCH] tests: qemublock: Add checkpoint deletion test for deep
+ backing chain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add test cases for merging various pairs of bitmaps when snapshots were
+created together with checkpoints.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 3c1c35bada75052b73d224d80fb5c3747a664823)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <06d3c8ebd023583de6c9d5033fc38a2757ecf8e2.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |  6 ++
+ .../snapshots-current-out.json                | 29 +++++++++
+ .../snapshots-intermediate1-out.json          | 22 +++++++
+ .../snapshots-intermediate2-out.json          | 59 +++++++++++++++++++
+ .../snapshots-intermediate3-out.json          | 59 +++++++++++++++++++
+ .../snapshots-noparent-out.json               | 23 ++++++++
+ 6 files changed, 198 insertions(+)
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index e56f813424..897b86f970 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1015,6 +1015,12 @@ mymain(void)
+     TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate3", "d", "c", "basic");
+     TEST_CHECKPOINT_DELETE_MERGE("basic-current", "current", "d", "basic");
+ 
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-noparent", "a", NULL, "snapshots");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-intermediate1", "b", "a", "snapshots");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-intermediate2", "c", "b", "snapshots");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-intermediate3", "d", "c", "snapshots");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-current", "current", "d", "snapshots");
++
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+     qemuTestDriverFree(&driver);
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json
+new file mode 100644
+index 0000000000..1b607567e8
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-current-out.json
+@@ -0,0 +1,29 @@
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "d"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "current"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
+new file mode 100644
+index 0000000000..29fefeea63
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate1-out.json
+@@ -0,0 +1,22 @@
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
+new file mode 100644
+index 0000000000..4da21a9df7
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate2-out.json
+@@ -0,0 +1,59 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "c"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "c"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
+new file mode 100644
+index 0000000000..dc87dd60b8
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-intermediate3-out.json
+@@ -0,0 +1,59 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "d"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "c"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "d"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
+new file mode 100644
+index 0000000000..45a84b47c2
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-noparent-out.json
+@@ -0,0 +1,23 @@
++[
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "a"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "a"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublock-Add-checkpoint-deletion-tests-for-some-special-cases.patch b/SOURCES/libvirt-tests-qemublock-Add-checkpoint-deletion-tests-for-some-special-cases.patch
new file mode 100644
index 0000000..354178a
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublock-Add-checkpoint-deletion-tests-for-some-special-cases.patch
@@ -0,0 +1,257 @@
+From 686c7592b99c1e2c4831f14c4e101a4ab039c45e Mon Sep 17 00:00:00 2001
+Message-Id: <686c7592b99c1e2c4831f14c4e101a4ab039c45e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:14 +0100
+Subject: [PATCH] tests: qemublock: Add checkpoint deletion tests for some
+ special cases
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use the synthetic test data to verify that the algorithm correctly picks
+bitmaps to merge when the bitmap is changed along with the image itself.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 065e548ebf0e39c8f9d30d0637ecfa84803d8f98)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <c34b7a28b9943b6cf7546eb2ac4d4bf95a164f11.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |  7 +++
+ ...hots-synthetic-checkpoint-current-out.json | 29 +++++++++
+ ...ynthetic-checkpoint-intermediate1-out.json | 29 +++++++++
+ ...ynthetic-checkpoint-intermediate2-out.json | 32 ++++++++++
+ ...ynthetic-checkpoint-intermediate3-out.json | 59 +++++++++++++++++++
+ ...ots-synthetic-checkpoint-noparent-out.json | 23 ++++++++
+ 6 files changed, 179 insertions(+)
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 897b86f970..2e5927f3c1 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1021,6 +1021,13 @@ mymain(void)
+     TEST_CHECKPOINT_DELETE_MERGE("snapshots-intermediate3", "d", "c", "snapshots");
+     TEST_CHECKPOINT_DELETE_MERGE("snapshots-current", "current", "d", "snapshots");
+ 
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-noparent", "a", NULL, "snapshots-synthetic-checkpoint");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-intermediate1", "b", "a", "snapshots-synthetic-checkpoint");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-intermediate2", "c", "b", "snapshots-synthetic-checkpoint");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-intermediate3", "d", "c", "snapshots-synthetic-checkpoint");
++    TEST_CHECKPOINT_DELETE_MERGE("snapshots-synthetic-checkpoint-current", "current", "d", "snapshots-synthetic-checkpoint");
++
++
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+     qemuTestDriverFree(&driver);
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json
+new file mode 100644
+index 0000000000..1b607567e8
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-current-out.json
+@@ -0,0 +1,29 @@
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "d"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "current"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
+new file mode 100644
+index 0000000000..e979691e6f
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate1-out.json
+@@ -0,0 +1,29 @@
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "a"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-3-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "b"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
+new file mode 100644
+index 0000000000..e82098918a
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate2-out.json
+@@ -0,0 +1,32 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "c"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
+new file mode 100644
+index 0000000000..dc87dd60b8
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-intermediate3-out.json
+@@ -0,0 +1,59 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "d"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "c"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-2-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-2-format",
++      "name": "d"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
+new file mode 100644
+index 0000000000..45a84b47c2
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/snapshots-synthetic-checkpoint-noparent-out.json
+@@ -0,0 +1,23 @@
++[
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-3-format",
++      "name": "a"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-4-format",
++      "name": "a"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-5-format",
++      "name": "a"
++    }
++  }
++]
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublock-Add-few-more-test-cases-for-checkpoint-deletion.patch b/SOURCES/libvirt-tests-qemublock-Add-few-more-test-cases-for-checkpoint-deletion.patch
new file mode 100644
index 0000000..3116da7
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublock-Add-few-more-test-cases-for-checkpoint-deletion.patch
@@ -0,0 +1,169 @@
+From 06865f5dd0f1616a7f3ac8bc8edd259b362718ce Mon Sep 17 00:00:00 2001
+Message-Id: <06865f5dd0f1616a7f3ac8bc8edd259b362718ce@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:10 +0100
+Subject: [PATCH] tests: qemublock: Add few more test cases for checkpoint
+ deletion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add all intermediate steps and deletion of the current checkpoint on a
+flat (single-image) disk image.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 0cf33ab8f178846c0b961fbc4cc6a4e92d351310)a
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <4b1466cba585cb4125ffda7fd2af4ab01d714f79.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |  4 +++
+ .../checkpointdelete/basic-current-out.json   | 29 +++++++++++++++++++
+ .../basic-intermediate1-out.json              | 22 ++++++++++++++
+ .../basic-intermediate2-out.json              | 22 ++++++++++++++
+ .../basic-intermediate3-out.json              | 22 ++++++++++++++
+ 5 files changed, 99 insertions(+)
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-current-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 80355d1340..f48e4ce4b2 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -999,6 +999,10 @@ mymain(void)
+     } while (0)
+ 
+     TEST_CHECKPOINT_DELETE_MERGE("basic-noparent", "a", NULL);
++    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate1", "b", "a");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate2", "c", "b");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-intermediate3", "d", "c");
++    TEST_CHECKPOINT_DELETE_MERGE("basic-current", "current", "d");
+ 
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+diff --git a/tests/qemublocktestdata/checkpointdelete/basic-current-out.json b/tests/qemublocktestdata/checkpointdelete/basic-current-out.json
+new file mode 100644
+index 0000000000..1b607567e8
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/basic-current-out.json
+@@ -0,0 +1,29 @@
++[
++  {
++    "type": "block-dirty-bitmap-enable",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "d"
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "current"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json
+new file mode 100644
+index 0000000000..eccb7ed15f
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/basic-intermediate1-out.json
+@@ -0,0 +1,22 @@
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "b"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json
+new file mode 100644
+index 0000000000..de40e4b5b0
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/basic-intermediate2-out.json
+@@ -0,0 +1,22 @@
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "c"
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json b/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json
+new file mode 100644
+index 0000000000..b5d85f43f0
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/basic-intermediate3-out.json
+@@ -0,0 +1,22 @@
++[
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "libvirt-1-format",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "d"
++    }
++  }
++]
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublock-Add-synthetic-snapshot-checkpoint-test-data.patch b/SOURCES/libvirt-tests-qemublock-Add-synthetic-snapshot-checkpoint-test-data.patch
new file mode 100644
index 0000000..1d03e68
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublock-Add-synthetic-snapshot-checkpoint-test-data.patch
@@ -0,0 +1,896 @@
+From e79ccc88c3668567bf656cd0113ca46058ef8f00 Mon Sep 17 00:00:00 2001
+Message-Id: <e79ccc88c3668567bf656cd0113ca46058ef8f00@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:11 +0100
+Subject: [PATCH] tests: qemublock: Add synthetic snapshot+checkpoint test data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a faked qemu output which would simulate scenario where libvirt
+would take a snapshot and checkpoint simultaneously. This is visible in
+libvirt-2-format node where bitmap 'c' appears, but bitmap 'b' which is
+active in the previous layer is not present.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit d7d97e87afe00b58e23291cafb0ddb8aec3894d6)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <16c6b0162647c59d81b2b0ceb5ebc5f03c029285.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |   1 +
+ .../snapshots-synthetic-checkpoint.json       | 827 ++++++++++++++++++
+ .../bitmap/snapshots-synthetic-checkpoint.out |  13 +
+ 3 files changed, 841 insertions(+)
+ create mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json
+ create mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index f48e4ce4b2..edaf82053d 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -966,6 +966,7 @@ mymain(void)
+     TEST_BITMAP_DETECT("basic");
+     TEST_BITMAP_DETECT("synthetic");
+     TEST_BITMAP_DETECT("snapshots");
++    TEST_BITMAP_DETECT("snapshots-synthetic-checkpoint");
+ 
+ #define TEST_BACKUP_BITMAP_CALCULATE(testname, source, incrbackup, named) \
+     do { \
+diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json b/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json
+new file mode 100644
+index 0000000000..25cc150d67
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.json
+@@ -0,0 +1,827 @@
++[
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "backing-image": {
++                    "backing-image": {
++                        "backing-image": {
++                            "virtual-size": 10485760,
++                            "filename": "/tmp/pull4.qcow2",
++                            "cluster-size": 65536,
++                            "format": "qcow2",
++                            "actual-size": 208896,
++                            "format-specific": {
++                                "type": "qcow2",
++                                "data": {
++                                    "compat": "1.1",
++                                    "lazy-refcounts": false,
++                                    "bitmaps": [
++                                        {
++                                            "flags": [
++                                                "auto"
++                                            ],
++                                            "name": "a",
++                                            "granularity": 65536
++                                        }
++                                    ],
++                                    "refcount-bits": 16,
++                                    "corrupt": false
++                                }
++                            },
++                            "dirty-flag": false
++                        },
++                        "backing-filename-format": "qcow2",
++                        "virtual-size": 10485760,
++                        "filename": "/tmp/pull4.1575911522",
++                        "cluster-size": 65536,
++                        "format": "qcow2",
++                        "actual-size": 208896,
++                        "format-specific": {
++                            "type": "qcow2",
++                            "data": {
++                                "compat": "1.1",
++                                "lazy-refcounts": false,
++                                "bitmaps": [
++                                    {
++                                        "flags": [
++                                            "auto"
++                                        ],
++                                        "name": "a",
++                                        "granularity": 65536
++                                    }
++                                ],
++                                "refcount-bits": 16,
++                                "corrupt": false
++                            }
++                        },
++                        "full-backing-filename": "/tmp/pull4.qcow2",
++                        "backing-filename": "/tmp/pull4.qcow2",
++                        "dirty-flag": false
++                    },
++                    "backing-filename-format": "qcow2",
++                    "virtual-size": 10485760,
++                    "filename": "/tmp/pull4.1575911527",
++                    "cluster-size": 65536,
++                    "format": "qcow2",
++                    "actual-size": 217088,
++                    "format-specific": {
++                        "type": "qcow2",
++                        "data": {
++                            "compat": "1.1",
++                            "lazy-refcounts": false,
++                            "bitmaps": [
++                                {
++                                    "flags": [
++                                        "auto"
++                                    ],
++                                    "name": "c",
++                                    "granularity": 65536
++                                },
++                                {
++                                    "flags": [
++
++                                    ],
++                                    "name": "b",
++                                    "granularity": 65536
++                                },
++                                {
++                                    "flags": [
++
++                                    ],
++                                    "name": "a",
++                                    "granularity": 65536
++                                }
++                            ],
++                            "refcount-bits": 16,
++                            "corrupt": false
++                        }
++                    },
++                    "full-backing-filename": "/tmp/pull4.1575911522",
++                    "backing-filename": "/tmp/pull4.1575911522",
++                    "dirty-flag": false
++                },
++                "backing-filename-format": "qcow2",
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.1575911540",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 212992,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "d",
++                                "granularity": 65536
++                            },
++                            {
++                                "flags": [
++
++                                ],
++                                "name": "c",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "full-backing-filename": "/tmp/pull4.1575911527",
++                "backing-filename": "/tmp/pull4.1575911527",
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911550",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 212992,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "in-use",
++                                "auto"
++                            ],
++                            "name": "current",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++                                "in-use"
++                            ],
++                            "name": "d",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.1575911540",
++            "backing-filename": "/tmp/pull4.1575911540",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-1-format",
++        "backing_file_depth": 4,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.1575911540",
++        "dirty-bitmaps": [
++            {
++                "name": "d",
++                "recording": false,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            },
++            {
++                "name": "current",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911550",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 393728,
++            "filename": "/tmp/pull4.1575911550",
++            "format": "file",
++            "actual-size": 212992,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-1-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911550",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "backing-image": {
++                    "backing-image": {
++                        "virtual-size": 10485760,
++                        "filename": "/tmp/pull4.qcow2",
++                        "cluster-size": 65536,
++                        "format": "qcow2",
++                        "actual-size": 208896,
++                        "format-specific": {
++                            "type": "qcow2",
++                            "data": {
++                                "compat": "1.1",
++                                "lazy-refcounts": false,
++                                "bitmaps": [
++                                    {
++                                        "flags": [
++                                            "auto"
++                                        ],
++                                        "name": "a",
++                                        "granularity": 65536
++                                    }
++                                ],
++                                "refcount-bits": 16,
++                                "corrupt": false
++                            }
++                        },
++                        "dirty-flag": false
++                    },
++                    "backing-filename-format": "qcow2",
++                    "virtual-size": 10485760,
++                    "filename": "/tmp/pull4.1575911522",
++                    "cluster-size": 65536,
++                    "format": "qcow2",
++                    "actual-size": 208896,
++                    "format-specific": {
++                        "type": "qcow2",
++                        "data": {
++                            "compat": "1.1",
++                            "lazy-refcounts": false,
++                            "bitmaps": [
++                                {
++                                    "flags": [
++                                        "auto"
++                                    ],
++                                    "name": "a",
++                                    "granularity": 65536
++                                }
++                            ],
++                            "refcount-bits": 16,
++                            "corrupt": false
++                        }
++                    },
++                    "full-backing-filename": "/tmp/pull4.qcow2",
++                    "backing-filename": "/tmp/pull4.qcow2",
++                    "dirty-flag": false
++                },
++                "backing-filename-format": "qcow2",
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.1575911527",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 217088,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "c",
++                                "granularity": 65536
++                            },
++                            {
++                                "flags": [
++
++                                ],
++                                "name": "b",
++                                "granularity": 65536
++                            },
++                            {
++                                "flags": [
++
++                                ],
++                                "name": "a",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "full-backing-filename": "/tmp/pull4.1575911522",
++                "backing-filename": "/tmp/pull4.1575911522",
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911540",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 212992,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "d",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++
++                            ],
++                            "name": "c",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.1575911527",
++            "backing-filename": "/tmp/pull4.1575911527",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-2-format",
++        "backing_file_depth": 3,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.1575911527",
++        "dirty-bitmaps": [
++            {
++                "name": "c",
++                "recording": false,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            },
++            {
++                "name": "d",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911540",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 393728,
++            "filename": "/tmp/pull4.1575911540",
++            "format": "file",
++            "actual-size": 212992,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-2-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911540",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "backing-image": {
++                    "virtual-size": 10485760,
++                    "filename": "/tmp/pull4.qcow2",
++                    "cluster-size": 65536,
++                    "format": "qcow2",
++                    "actual-size": 208896,
++                    "format-specific": {
++                        "type": "qcow2",
++                        "data": {
++                            "compat": "1.1",
++                            "lazy-refcounts": false,
++                            "bitmaps": [
++                                {
++                                    "flags": [
++                                        "auto"
++                                    ],
++                                    "name": "a",
++                                    "granularity": 65536
++                                }
++                            ],
++                            "refcount-bits": 16,
++                            "corrupt": false
++                        }
++                    },
++                    "dirty-flag": false
++                },
++                "backing-filename-format": "qcow2",
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.1575911522",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 208896,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "a",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "full-backing-filename": "/tmp/pull4.qcow2",
++                "backing-filename": "/tmp/pull4.qcow2",
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911527",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 217088,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "c",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++
++                            ],
++                            "name": "b",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++
++                            ],
++                            "name": "a",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.1575911522",
++            "backing-filename": "/tmp/pull4.1575911522",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-3-format",
++        "backing_file_depth": 2,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.1575911522",
++        "dirty-bitmaps": [
++            {
++                "name": "a",
++                "recording": false,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            },
++            {
++                "name": "b",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911527",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 459264,
++            "filename": "/tmp/pull4.1575911527",
++            "format": "file",
++            "actual-size": 217088,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-3-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911527",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.qcow2",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 208896,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "a",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911522",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 208896,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "a",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.qcow2",
++            "backing-filename": "/tmp/pull4.qcow2",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-4-format",
++        "backing_file_depth": 1,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.qcow2",
++        "dirty-bitmaps": [
++            {
++                "name": "a",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911522",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 328192,
++            "filename": "/tmp/pull4.1575911522",
++            "format": "file",
++            "actual-size": 208896,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-4-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911522",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.qcow2",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 208896,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "a",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-5-format",
++        "backing_file_depth": 0,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "dirty-bitmaps": [
++            {
++                "name": "a",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.qcow2",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 328192,
++            "filename": "/tmp/pull4.qcow2",
++            "format": "file",
++            "actual-size": 208896,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-5-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.qcow2",
++        "encryption_key_missing": false
++    }
++]
+diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out b/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out
+new file mode 100644
+index 0000000000..0270657001
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmap/snapshots-synthetic-checkpoint.out
+@@ -0,0 +1,13 @@
++libvirt-1-format:
++        d: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++  current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++libvirt-2-format:
++        c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++        d: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++libvirt-3-format:
++        a: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++        b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++libvirt-4-format:
++        a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++libvirt-5-format:
++        a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublock-Add-test-for-checkpoint-deletion-bitmap-merge.patch b/SOURCES/libvirt-tests-qemublock-Add-test-for-checkpoint-deletion-bitmap-merge.patch
new file mode 100644
index 0000000..097acec
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublock-Add-test-for-checkpoint-deletion-bitmap-merge.patch
@@ -0,0 +1,134 @@
+From c71d50132b3ac8dcfefc1acc11ab5d5bd7bc024a Mon Sep 17 00:00:00 2001
+Message-Id: <c71d50132b3ac8dcfefc1acc11ab5d5bd7bc024a@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:09 +0100
+Subject: [PATCH] tests: qemublock: Add test for checkpoint deletion bitmap
+ merge
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add test infrastructure and a basic test for bitmap deletion.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 25f74899720afce52dcf01f230da5c816deaea71)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <50b8789a34b762114b6ea2f87bba1a130be206de.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         | 59 +++++++++++++++++++
+ .../checkpointdelete/basic-noparent-out.json  |  9 +++
+ 2 files changed, 68 insertions(+)
+ create mode 100644 tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 7ff6a6b17b..80355d1340 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -27,6 +27,7 @@
+ #include "qemu/qemu_qapi.h"
+ #include "qemu/qemu_monitor_json.h"
+ #include "qemu/qemu_backup.h"
++#include "qemu/qemu_checkpoint.h"
+ 
+ #include "qemu/qemu_command.h"
+ 
+@@ -696,6 +697,50 @@ testQemuBackupIncrementalBitmapCalculate(const void *opaque)
+ }
+ 
+ 
++static const char *checkpointDeletePrefix = "qemublocktestdata/checkpointdelete/";
++
++struct testQemuCheckpointDeleteMergeData {
++    const char *name;
++    virStorageSourcePtr chain;
++    const char *deletebitmap;
++    const char *parentbitmap;
++};
++
++
++static int
++testQemuCheckpointDeleteMerge(const void *opaque)
++{
++    const struct testQemuCheckpointDeleteMergeData *data = opaque;
++    g_autofree char *actual = NULL;
++    g_autofree char *expectpath = NULL;
++    g_autoptr(virJSONValue) actions = NULL;
++    bool currentcheckpoint;
++
++    expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir,
++                                 checkpointDeletePrefix, data->name);
++
++    if (!(actions = virJSONValueNewArray()))
++        return -1;
++
++    /* hack to get the 'current' state until the function stops accepting it */
++    currentcheckpoint = STREQ("current", data->deletebitmap);
++
++    if (qemuCheckpointDiscardDiskBitmaps(data->chain,
++                                         data->deletebitmap,
++                                         data->parentbitmap,
++                                         currentcheckpoint,
++                                         actions) < 0) {
++        VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n");
++        return -1;
++    }
++
++    if (!(actual = virJSONValueToString(actions, true)))
++        return -1;
++
++    return virTestCompareToFile(actual, expectpath);
++}
++
++
+ static int
+ mymain(void)
+ {
+@@ -705,6 +750,7 @@ mymain(void)
+     struct testQemuDiskXMLToJSONData diskxmljsondata;
+     struct testQemuImageCreateData imagecreatedata;
+     struct testQemuBackupIncrementalBitmapCalculateData backupbitmapcalcdata;
++    struct testQemuCheckpointDeleteMergeData checkpointdeletedata;
+     char *capslatest_x86_64 = NULL;
+     virQEMUCapsPtr caps_x86_64 = NULL;
+     g_autoptr(virStorageSource) bitmapSourceChain = NULL;
+@@ -941,6 +987,19 @@ mymain(void)
+     TEST_BACKUP_BITMAP_CALCULATE("snapshot-intermediate", bitmapSourceChain, "d", "snapshots");
+     TEST_BACKUP_BITMAP_CALCULATE("snapshot-deep", bitmapSourceChain, "a", "snapshots");
+ 
++#define TEST_CHECKPOINT_DELETE_MERGE(testname, delbmp, parbmp) \
++    do { \
++        checkpointdeletedata.name = testname; \
++        checkpointdeletedata.chain = bitmapSourceChain; \
++        checkpointdeletedata.deletebitmap = delbmp; \
++        checkpointdeletedata.parentbitmap = parbmp; \
++        if (virTestRun("checkpoint delete " testname, \
++                       testQemuCheckpointDeleteMerge, &checkpointdeletedata) < 0) \
++        ret = -1; \
++    } while (0)
++
++    TEST_CHECKPOINT_DELETE_MERGE("basic-noparent", "a", NULL);
++
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+     qemuTestDriverFree(&driver);
+diff --git a/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json b/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json
+new file mode 100644
+index 0000000000..e87382fdb4
+--- /dev/null
++++ b/tests/qemublocktestdata/checkpointdelete/basic-noparent-out.json
+@@ -0,0 +1,9 @@
++[
++  {
++    "type": "block-dirty-bitmap-remove",
++    "data": {
++      "node": "libvirt-1-format",
++      "name": "a"
++    }
++  }
++]
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublock-Add-tests-for-qemuBlockBitmapsHandleBlockcopy.patch b/SOURCES/libvirt-tests-qemublock-Add-tests-for-qemuBlockBitmapsHandleBlockcopy.patch
new file mode 100644
index 0000000..8523a0b
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublock-Add-tests-for-qemuBlockBitmapsHandleBlockcopy.patch
@@ -0,0 +1,577 @@
+From 736c0d3748605b553f065332855b61291503ac25 Mon Sep 17 00:00:00 2001
+Message-Id: <736c0d3748605b553f065332855b61291503ac25@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:26 +0100
+Subject: [PATCH] tests: qemublock: Add tests for
+ qemuBlockBitmapsHandleBlockcopy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use some of the existing bitmap data to add tests for
+qemuBlockBitmapsHandleBlockcopy.
+
+As the output depends on the ordering in the hash table we must also
+install the "virdeterministichash" mock preload library.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 9b13af73ac336fb1d93ef15e30204fbf9c7e536f)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <095e8e63f87edfd7924a8e8d8a4a8def04022d77.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |  71 +++++++++-
+ .../bitmapblockcopy/basic-deep-out.json       | 117 +++++++++++++++
+ .../bitmapblockcopy/basic-shallow-out.json    | 117 +++++++++++++++
+ .../bitmapblockcopy/snapshots-deep-out.json   | 133 ++++++++++++++++++
+ .../snapshots-shallow-out.json                |  48 +++++++
+ 5 files changed, 485 insertions(+), 1 deletion(-)
+ create mode 100644 tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json
+ create mode 100644 tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json
+ create mode 100644 tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json
+ create mode 100644 tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 3208e90e41..f66d894aed 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -799,6 +799,56 @@ testQemuBlockBitmapValidate(const void *opaque)
+ }
+ 
+ 
++static const char *blockcopyPrefix = "qemublocktestdata/bitmapblockcopy/";
++
++struct testQemuBlockBitmapBlockcopyData {
++    const char *name;
++    bool shallow;
++    virStorageSourcePtr chain;
++    const char *nodedatafile;
++};
++
++
++static int
++testQemuBlockBitmapBlockcopy(const void *opaque)
++{
++    const struct testQemuBlockBitmapBlockcopyData *data = opaque;
++    g_autofree char *actual = NULL;
++    g_autofree char *expectpath = NULL;
++    g_autoptr(virJSONValue) actions = NULL;
++    g_autoptr(virJSONValue) nodedatajson = NULL;
++    g_autoptr(virHashTable) nodedata = NULL;
++    g_autoptr(virStorageSource) fakemirror = virStorageSourceNew();
++
++    if (!fakemirror)
++        return -1;
++
++    fakemirror->nodeformat = g_strdup("mirror-format-node");
++
++    expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir,
++                                 blockcopyPrefix, data->name);
++
++    if (!(nodedatajson = virTestLoadFileJSON(bitmapDetectPrefix, data->nodedatafile,
++                                             ".json", NULL)))
++        return -1;
++
++    if (!(nodedata = qemuMonitorJSONBlockGetNamedNodeDataJSON(nodedatajson))) {
++        VIR_TEST_VERBOSE("failed to load nodedata JSON\n");
++        return -1;
++    }
++
++    if (qemuBlockBitmapsHandleBlockcopy(data->chain, fakemirror, nodedata,
++                                        data->shallow, &actions) < 0)
++        return -1;
++
++    if (actions &&
++        !(actual = virJSONValueToString(actions, true)))
++        return -1;
++
++    return virTestCompareToFile(actual, expectpath);
++}
++
++
+ static int
+ mymain(void)
+ {
+@@ -810,6 +860,7 @@ mymain(void)
+     struct testQemuBackupIncrementalBitmapCalculateData backupbitmapcalcdata;
+     struct testQemuCheckpointDeleteMergeData checkpointdeletedata;
+     struct testQemuBlockBitmapValidateData blockbitmapvalidatedata;
++    struct testQemuBlockBitmapBlockcopyData blockbitmapblockcopydata;
+     char *capslatest_x86_64 = NULL;
+     virQEMUCapsPtr caps_x86_64 = NULL;
+     g_autoptr(virStorageSource) bitmapSourceChain = NULL;
+@@ -1120,6 +1171,24 @@ mymain(void)
+     TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "d", false);
+     TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "current", true);
+ 
++#define TEST_BITMAP_BLOCKCOPY(testname, shllw, ndf) \
++    do { \
++        blockbitmapblockcopydata.name = testname; \
++        blockbitmapblockcopydata.shallow = shllw; \
++        blockbitmapblockcopydata.nodedatafile = ndf; \
++        blockbitmapblockcopydata.chain = bitmapSourceChain;\
++        if (virTestRun("bitmap block copy " testname, \
++                       testQemuBlockBitmapBlockcopy, \
++                       &blockbitmapblockcopydata) < 0) \
++            ret = -1; \
++    } while (0)
++
++    TEST_BITMAP_BLOCKCOPY("basic-shallow", true, "basic");
++    TEST_BITMAP_BLOCKCOPY("basic-deep", false, "basic");
++
++    TEST_BITMAP_BLOCKCOPY("snapshots-shallow", true, "snapshots");
++    TEST_BITMAP_BLOCKCOPY("snapshots-deep", false, "snapshots");
++
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+     qemuTestDriverFree(&driver);
+@@ -1129,4 +1198,4 @@ mymain(void)
+     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+ 
+-VIR_TEST_MAIN(mymain)
++VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virdeterministichash"))
+diff --git a/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json
+new file mode 100644
+index 0000000000..4ed2b97e95
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcopy/basic-deep-out.json
+@@ -0,0 +1,117 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "a",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json
+new file mode 100644
+index 0000000000..4ed2b97e95
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcopy/basic-shallow-out.json
+@@ -0,0 +1,117 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "a",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json
+new file mode 100644
+index 0000000000..5456553d78
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcopy/snapshots-deep-out.json
+@@ -0,0 +1,133 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "a",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "a",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "a"
++        },
++        {
++          "node": "libvirt-4-format",
++          "name": "a"
++        },
++        {
++          "node": "libvirt-5-format",
++          "name": "a"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "b",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "b",
++      "bitmaps": [
++        {
++          "node": "libvirt-3-format",
++          "name": "b"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "c",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "c",
++      "bitmaps": [
++        {
++          "node": "libvirt-2-format",
++          "name": "c"
++        },
++        {
++          "node": "libvirt-3-format",
++          "name": "c"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        },
++        {
++          "node": "libvirt-2-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json
+new file mode 100644
+index 0000000000..ddd47f7ee1
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmapblockcopy/snapshots-shallow-out.json
+@@ -0,0 +1,48 @@
++[
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "current",
++      "persistent": true,
++      "disabled": false,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "current",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "current"
++        }
++      ]
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-add",
++    "data": {
++      "node": "mirror-format-node",
++      "name": "d",
++      "persistent": true,
++      "disabled": true,
++      "granularity": 65536
++    }
++  },
++  {
++    "type": "block-dirty-bitmap-merge",
++    "data": {
++      "node": "mirror-format-node",
++      "target": "d",
++      "bitmaps": [
++        {
++          "node": "libvirt-1-format",
++          "name": "d"
++        }
++      ]
++    }
++  }
++]
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-qemublocktest-Add-another-synthetic-test-case-for-broken-bitmaps.patch b/SOURCES/libvirt-tests-qemublocktest-Add-another-synthetic-test-case-for-broken-bitmaps.patch
new file mode 100644
index 0000000..8fa3519
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemublocktest-Add-another-synthetic-test-case-for-broken-bitmaps.patch
@@ -0,0 +1,900 @@
+From 51214acf9b65be8575eac8ff82d63e5c260a48fe Mon Sep 17 00:00:00 2001
+Message-Id: <51214acf9b65be8575eac8ff82d63e5c260a48fe@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:24 +0100
+Subject: [PATCH] tests: qemublocktest: Add another synthetic test case for
+ broken bitmaps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a case where a bitmap spanning multiple images is missing one of the
+intermediate components.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 8e29a8b151f59a53d2bb57bb58074185088f38f0)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <0a1a64d620d9770afda50efc0e82c67dd3c2ae19.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemublocktest.c                         |   8 +
+ .../bitmap/snapshots-synthetic-broken.json    | 819 ++++++++++++++++++
+ .../bitmap/snapshots-synthetic-broken.out     |  12 +
+ 3 files changed, 839 insertions(+)
+ create mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json
+ create mode 100644 tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out
+
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 6a7b07cfee..3208e90e41 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -1026,6 +1026,7 @@ mymain(void)
+     TEST_BITMAP_DETECT("synthetic");
+     TEST_BITMAP_DETECT("snapshots");
+     TEST_BITMAP_DETECT("snapshots-synthetic-checkpoint");
++    TEST_BITMAP_DETECT("snapshots-synthetic-broken");
+ 
+ #define TEST_BACKUP_BITMAP_CALCULATE(testname, source, incrbackup, named) \
+     do { \
+@@ -1112,6 +1113,13 @@ mymain(void)
+     TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "c", true);
+     TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "d", true);
+     TEST_BITMAP_VALIDATE("snapshots-synthetic-checkpoint", "current", true);
++
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "a", false);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "b", true);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "c", true);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "d", false);
++    TEST_BITMAP_VALIDATE("snapshots-synthetic-broken", "current", true);
++
+  cleanup:
+     virHashFree(diskxmljsondata.schema);
+     qemuTestDriverFree(&driver);
+diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json
+new file mode 100644
+index 0000000000..bf4963494f
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.json
+@@ -0,0 +1,819 @@
++[
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "backing-image": {
++                    "backing-image": {
++                        "backing-image": {
++                            "virtual-size": 10485760,
++                            "filename": "/tmp/pull4.qcow2",
++                            "cluster-size": 65536,
++                            "format": "qcow2",
++                            "actual-size": 208896,
++                            "format-specific": {
++                                "type": "qcow2",
++                                "data": {
++                                    "compat": "1.1",
++                                    "lazy-refcounts": false,
++                                    "bitmaps": [
++                                        {
++                                            "flags": [
++                                                "auto"
++                                            ],
++                                            "name": "a",
++                                            "granularity": 65536
++                                        }
++                                    ],
++                                    "refcount-bits": 16,
++                                    "corrupt": false
++                                }
++                            },
++                            "dirty-flag": false
++                        },
++                        "backing-filename-format": "qcow2",
++                        "virtual-size": 10485760,
++                        "filename": "/tmp/pull4.1575911522",
++                        "cluster-size": 65536,
++                        "format": "qcow2",
++                        "actual-size": 208896,
++                        "format-specific": {
++                            "type": "qcow2",
++                            "data": {
++                                "compat": "1.1",
++                                "lazy-refcounts": false,
++                                "bitmaps": [
++                                    {
++                                        "flags": [
++                                            "auto"
++                                        ],
++                                        "name": "a",
++                                        "granularity": 65536
++                                    }
++                                ],
++                                "refcount-bits": 16,
++                                "corrupt": false
++                            }
++                        },
++                        "full-backing-filename": "/tmp/pull4.qcow2",
++                        "backing-filename": "/tmp/pull4.qcow2",
++                        "dirty-flag": false
++                    },
++                    "backing-filename-format": "qcow2",
++                    "virtual-size": 10485760,
++                    "filename": "/tmp/pull4.1575911527",
++                    "cluster-size": 65536,
++                    "format": "qcow2",
++                    "actual-size": 217088,
++                    "format-specific": {
++                        "type": "qcow2",
++                        "data": {
++                            "compat": "1.1",
++                            "lazy-refcounts": false,
++                            "bitmaps": [
++                                {
++                                    "flags": [
++                                        "auto"
++                                    ],
++                                    "name": "c",
++                                    "granularity": 65536
++                                },
++                                {
++                                    "flags": [
++
++                                    ],
++                                    "name": "b",
++                                    "granularity": 65536
++                                },
++                                {
++                                    "flags": [
++
++                                    ],
++                                    "name": "a",
++                                    "granularity": 65536
++                                }
++                            ],
++                            "refcount-bits": 16,
++                            "corrupt": false
++                        }
++                    },
++                    "full-backing-filename": "/tmp/pull4.1575911522",
++                    "backing-filename": "/tmp/pull4.1575911522",
++                    "dirty-flag": false
++                },
++                "backing-filename-format": "qcow2",
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.1575911540",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 212992,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "d",
++                                "granularity": 65536
++                            },
++                            {
++                                "flags": [
++
++                                ],
++                                "name": "c",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "full-backing-filename": "/tmp/pull4.1575911527",
++                "backing-filename": "/tmp/pull4.1575911527",
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911550",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 212992,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "in-use",
++                                "auto"
++                            ],
++                            "name": "current",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++                                "in-use"
++                            ],
++                            "name": "d",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.1575911540",
++            "backing-filename": "/tmp/pull4.1575911540",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-1-format",
++        "backing_file_depth": 4,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.1575911540",
++        "dirty-bitmaps": [
++            {
++                "name": "d",
++                "recording": false,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            },
++            {
++                "name": "current",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911550",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 393728,
++            "filename": "/tmp/pull4.1575911550",
++            "format": "file",
++            "actual-size": 212992,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-1-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911550",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "backing-image": {
++                    "backing-image": {
++                        "virtual-size": 10485760,
++                        "filename": "/tmp/pull4.qcow2",
++                        "cluster-size": 65536,
++                        "format": "qcow2",
++                        "actual-size": 208896,
++                        "format-specific": {
++                            "type": "qcow2",
++                            "data": {
++                                "compat": "1.1",
++                                "lazy-refcounts": false,
++                                "bitmaps": [
++                                    {
++                                        "flags": [
++                                            "auto"
++                                        ],
++                                        "name": "a",
++                                        "granularity": 65536
++                                    }
++                                ],
++                                "refcount-bits": 16,
++                                "corrupt": false
++                            }
++                        },
++                        "dirty-flag": false
++                    },
++                    "backing-filename-format": "qcow2",
++                    "virtual-size": 10485760,
++                    "filename": "/tmp/pull4.1575911522",
++                    "cluster-size": 65536,
++                    "format": "qcow2",
++                    "actual-size": 208896,
++                    "format-specific": {
++                        "type": "qcow2",
++                        "data": {
++                            "compat": "1.1",
++                            "lazy-refcounts": false,
++                            "bitmaps": [
++                                {
++                                    "flags": [
++                                        "auto"
++                                    ],
++                                    "name": "a",
++                                    "granularity": 65536
++                                }
++                            ],
++                            "refcount-bits": 16,
++                            "corrupt": false
++                        }
++                    },
++                    "full-backing-filename": "/tmp/pull4.qcow2",
++                    "backing-filename": "/tmp/pull4.qcow2",
++                    "dirty-flag": false
++                },
++                "backing-filename-format": "qcow2",
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.1575911527",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 217088,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "c",
++                                "granularity": 65536
++                            },
++                            {
++                                "flags": [
++
++                                ],
++                                "name": "b",
++                                "granularity": 65536
++                            },
++                            {
++                                "flags": [
++
++                                ],
++                                "name": "a",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "full-backing-filename": "/tmp/pull4.1575911522",
++                "backing-filename": "/tmp/pull4.1575911522",
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911540",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 212992,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "d",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++
++                            ],
++                            "name": "c",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.1575911527",
++            "backing-filename": "/tmp/pull4.1575911527",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-2-format",
++        "backing_file_depth": 3,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.1575911527",
++        "dirty-bitmaps": [
++            {
++                "name": "c",
++                "recording": false,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            },
++            {
++                "name": "d",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "inconsistent": true,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911540",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 393728,
++            "filename": "/tmp/pull4.1575911540",
++            "format": "file",
++            "actual-size": 212992,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-2-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911540",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "backing-image": {
++                    "virtual-size": 10485760,
++                    "filename": "/tmp/pull4.qcow2",
++                    "cluster-size": 65536,
++                    "format": "qcow2",
++                    "actual-size": 208896,
++                    "format-specific": {
++                        "type": "qcow2",
++                        "data": {
++                            "compat": "1.1",
++                            "lazy-refcounts": false,
++                            "bitmaps": [
++                                {
++                                    "flags": [
++                                        "auto"
++                                    ],
++                                    "name": "a",
++                                    "granularity": 65536
++                                }
++                            ],
++                            "refcount-bits": 16,
++                            "corrupt": false
++                        }
++                    },
++                    "dirty-flag": false
++                },
++                "backing-filename-format": "qcow2",
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.1575911522",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 208896,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "a",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "full-backing-filename": "/tmp/pull4.qcow2",
++                "backing-filename": "/tmp/pull4.qcow2",
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911527",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 217088,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "c",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++
++                            ],
++                            "name": "b",
++                            "granularity": 65536
++                        },
++                        {
++                            "flags": [
++
++                            ],
++                            "name": "a",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.1575911522",
++            "backing-filename": "/tmp/pull4.1575911522",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-3-format",
++        "backing_file_depth": 2,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.1575911522",
++        "dirty-bitmaps": [
++            {
++                "name": "a",
++                "recording": false,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            },
++            {
++                "name": "b",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "disabled",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911527",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 459264,
++            "filename": "/tmp/pull4.1575911527",
++            "format": "file",
++            "actual-size": 217088,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-3-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911527",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "backing-image": {
++                "virtual-size": 10485760,
++                "filename": "/tmp/pull4.qcow2",
++                "cluster-size": 65536,
++                "format": "qcow2",
++                "actual-size": 208896,
++                "format-specific": {
++                    "type": "qcow2",
++                    "data": {
++                        "compat": "1.1",
++                        "lazy-refcounts": false,
++                        "bitmaps": [
++                            {
++                                "flags": [
++                                    "auto"
++                                ],
++                                "name": "a",
++                                "granularity": 65536
++                            }
++                        ],
++                        "refcount-bits": 16,
++                        "corrupt": false
++                    }
++                },
++                "dirty-flag": false
++            },
++            "backing-filename-format": "qcow2",
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.1575911522",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 208896,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "a",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "full-backing-filename": "/tmp/pull4.qcow2",
++            "backing-filename": "/tmp/pull4.qcow2",
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-4-format",
++        "backing_file_depth": 1,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "backing_file": "/tmp/pull4.qcow2",
++        "dirty-bitmaps": [
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911522",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 328192,
++            "filename": "/tmp/pull4.1575911522",
++            "format": "file",
++            "actual-size": 208896,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-4-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.1575911522",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 10485760,
++            "filename": "/tmp/pull4.qcow2",
++            "cluster-size": 65536,
++            "format": "qcow2",
++            "actual-size": 208896,
++            "format-specific": {
++                "type": "qcow2",
++                "data": {
++                    "compat": "1.1",
++                    "lazy-refcounts": false,
++                    "bitmaps": [
++                        {
++                            "flags": [
++                                "auto"
++                            ],
++                            "name": "a",
++                            "granularity": 65536
++                        }
++                    ],
++                    "refcount-bits": 16,
++                    "corrupt": false
++                }
++            },
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": true,
++        "node-name": "libvirt-5-format",
++        "backing_file_depth": 0,
++        "drv": "qcow2",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "dirty-bitmaps": [
++            {
++                "name": "a",
++                "recording": true,
++                "persistent": true,
++                "busy": false,
++                "status": "active",
++                "granularity": 65536,
++                "count": 0
++            }
++        ],
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.qcow2",
++        "encryption_key_missing": false
++    },
++    {
++        "iops_rd": 0,
++        "detect_zeroes": "off",
++        "image": {
++            "virtual-size": 328192,
++            "filename": "/tmp/pull4.qcow2",
++            "format": "file",
++            "actual-size": 208896,
++            "dirty-flag": false
++        },
++        "iops_wr": 0,
++        "ro": false,
++        "node-name": "libvirt-5-storage",
++        "backing_file_depth": 0,
++        "drv": "file",
++        "iops": 0,
++        "bps_wr": 0,
++        "write_threshold": 0,
++        "encrypted": false,
++        "bps": 0,
++        "bps_rd": 0,
++        "cache": {
++            "no-flush": false,
++            "direct": false,
++            "writeback": true
++        },
++        "file": "/tmp/pull4.qcow2",
++        "encryption_key_missing": false
++    }
++]
+diff --git a/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out
+new file mode 100644
+index 0000000000..022630bd76
+--- /dev/null
++++ b/tests/qemublocktestdata/bitmap/snapshots-synthetic-broken.out
+@@ -0,0 +1,12 @@
++libvirt-1-format:
++        d: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++  current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++libvirt-2-format:
++        c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++        d: record:1 busy:0 persist:1 inconsist:1 gran:65536 dirty:0
++libvirt-3-format:
++        a: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++        b: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
++libvirt-4-format:
++libvirt-5-format:
++        a: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-virstorage-Add-test-cases-for-json-pseudo-URI-without-file-wrapper.patch b/SOURCES/libvirt-tests-virstorage-Add-test-cases-for-json-pseudo-URI-without-file-wrapper.patch
new file mode 100644
index 0000000..520b1ae
--- /dev/null
+++ b/SOURCES/libvirt-tests-virstorage-Add-test-cases-for-json-pseudo-URI-without-file-wrapper.patch
@@ -0,0 +1,54 @@
+From 4c5c4e4b30016175c40a1f2dac7e145042ea06ed Mon Sep 17 00:00:00 2001
+Message-Id: <4c5c4e4b30016175c40a1f2dac7e145042ea06ed@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:11 +0100
+Subject: [PATCH] tests: virstorage: Add test cases for "json:" pseudo-URI
+ without 'file' wrapper
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add few cases that prove the second format of "json:" pseudo-URIs.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 0d0d60ddc5e58359cff5be8dfd6dd27e98da0282)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <7f9970e468fd99dfb72033f688e45ca086be56a0.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virstoragetest.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index 4341c04b1e..6d62aab654 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1315,6 +1315,10 @@ mymain(void)
+                                         "}"
+                             "}",
+                        "<source file='/path/to/file'/>\n");
++    TEST_BACKING_PARSE("json:{\"driver\":\"file\","
++                             "\"filename\":\"/path/to/file\""
++                            "}",
++                       "<source file='/path/to/file'/>\n");
+     TEST_BACKING_PARSE("json:{\"file.driver\":\"host_device\", "
+                              "\"file.filename\":\"/path/to/dev\"}",
+                        "<source dev='/path/to/dev'/>\n");
+@@ -1389,6 +1393,12 @@ mymain(void)
+                        "<source protocol='nbd'>\n"
+                        "  <host transport='unix' socket='/path/to/socket'/>\n"
+                        "</source>\n");
++    TEST_BACKING_PARSE("json:{\"driver\":\"nbd\","
++                             "\"path\":\"/path/to/socket\""
++                            "}",
++                       "<source protocol='nbd'>\n"
++                       "  <host transport='unix' socket='/path/to/socket'/>\n"
++                       "</source>\n");
+     TEST_BACKING_PARSE("json:{\"file.driver\":\"nbd\","
+                              "\"file.path\":\"/path/to/socket\""
+                             "}",
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-virstorage-Add-test-data-for-json-specified-raw-image-with-offset-size.patch b/SOURCES/libvirt-tests-virstorage-Add-test-data-for-json-specified-raw-image-with-offset-size.patch
new file mode 100644
index 0000000..35963ac
--- /dev/null
+++ b/SOURCES/libvirt-tests-virstorage-Add-test-data-for-json-specified-raw-image-with-offset-size.patch
@@ -0,0 +1,49 @@
+From 5becceb93612985adc0e358c03003b9e85f1053f Mon Sep 17 00:00:00 2001
+Message-Id: <5becceb93612985adc0e358c03003b9e85f1053f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:14 +0100
+Subject: [PATCH] tests: virstorage: Add test data for json specified raw image
+ with offset/size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QEMU allows specifying the offset and size into a raw file to expose a
+sub-slice of the image to the guest with the raw driver. Libvirt
+currently doesn't support it but we can add test case for future
+reference.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 554ae62637fe4205b7f51a75e798be9223dfdc3d)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <36808e0f9518770d82af2562d6a54e36f0cb13f5.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virstoragetest.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index 6d62aab654..25d41f0de4 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1593,6 +1593,15 @@ mymain(void)
+                        "<source protocol='vxhs' name='c6718f6b-0401-441d-a8c3-1f0064d75ee0'>\n"
+                        "  <host name='example.com' port='9999'/>\n"
+                        "</source>\n");
++    TEST_BACKING_PARSE_FULL("json:{ \"driver\": \"raw\","
++                                    "\"offset\": 10752,"
++                                    "\"size\": 4063232,"
++                                    "\"file\": { \"driver\": \"file\","
++                                                "\"filename\": \"/tmp/testfle\""
++                                              "}"
++                                  "}",
++                            "<source file='/tmp/testfle'/>\n", 0);
++
+ #endif /* WITH_YAJL */
+ 
+  cleanup:
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-virstorage-Add-tests-for-NBD-URI-style-syntax-over-UNIX.patch b/SOURCES/libvirt-tests-virstorage-Add-tests-for-NBD-URI-style-syntax-over-UNIX.patch
new file mode 100644
index 0000000..2a3c2cb
--- /dev/null
+++ b/SOURCES/libvirt-tests-virstorage-Add-tests-for-NBD-URI-style-syntax-over-UNIX.patch
@@ -0,0 +1,61 @@
+From f2367a6085be46fa0c3e948d0da1277f38bf2fa8 Mon Sep 17 00:00:00 2001
+Message-Id: <f2367a6085be46fa0c3e948d0da1277f38bf2fa8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 17 Jan 2020 13:16:58 +0100
+Subject: [PATCH] tests: virstorage: Add tests for NBD URI style syntax over
+ UNIX
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add few test cases for nbd+unix style URIs with few corner cases.
+
+The NBD URI syntax is documented at
+https://github.com/NetworkBlockDevice/nbd/blob/master/doc/uri.md
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 2775aada167fad5a508b16a8cadac1fca489c7be)
+https://bugzilla.redhat.com/show_bug.cgi?id=1791614
+Message-Id: <5c316356be1b5aca0cc2858925833e6316de10f8.1579263320.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
+---
+ tests/virstoragetest.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index 370e19252b..4341c04b1e 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1274,6 +1274,26 @@ mymain(void)
+                        "<source protocol='nbd' name='exportname'>\n"
+                        "  <host name='example.org' port='1234'/>\n"
+                        "</source>\n");
++    TEST_BACKING_PARSE("nbd+unix://?socket=/tmp/sock",
++                       "<source protocol='nbd'>\n"
++                       "  <host transport='unix' socket='/tmp/sock'/>\n"
++                       "</source>\n");
++    TEST_BACKING_PARSE("nbd+unix:///?socket=/tmp/sock",
++                       "<source protocol='nbd'>\n"
++                       "  <host transport='unix' socket='/tmp/sock'/>\n"
++                       "</source>\n");
++    TEST_BACKING_PARSE("nbd+unix:////?socket=/tmp/sock",
++                       "<source protocol='nbd' name='/'>\n"
++                       "  <host transport='unix' socket='/tmp/sock'/>\n"
++                       "</source>\n");
++    TEST_BACKING_PARSE("nbd+unix:///exp?socket=/tmp/sock",
++                       "<source protocol='nbd' name='exp'>\n"
++                       "  <host transport='unix' socket='/tmp/sock'/>\n"
++                       "</source>\n");
++    TEST_BACKING_PARSE("nbd+unix:////exp?socket=/tmp/sock",
++                       "<source protocol='nbd' name='/exp'>\n"
++                       "  <host transport='unix' socket='/tmp/sock'/>\n"
++                       "</source>\n");
+     TEST_BACKING_PARSE_FULL("iscsi://testuser:testpass@example.org:1234/exportname",
+                             "<source protocol='iscsi' name='exportname'>\n"
+                             "  <host name='example.org' port='1234'/>\n"
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-tests-virstorage-Fix-backing-file-format-of-created-image.patch b/SOURCES/libvirt-tests-virstorage-Fix-backing-file-format-of-created-image.patch
new file mode 100644
index 0000000..3436012
--- /dev/null
+++ b/SOURCES/libvirt-tests-virstorage-Fix-backing-file-format-of-created-image.patch
@@ -0,0 +1,39 @@
+From 81a506d1ac93ce3c5a21ae0dc6906d26074083f6 Mon Sep 17 00:00:00 2001
+Message-Id: <81a506d1ac93ce3c5a21ae0dc6906d26074083f6@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:35 +0100
+Subject: [PATCH] tests: virstorage: Fix backing file format of created image
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We create some images for testing our code. We've recorded wrong format
+of the backing file for one of the images though.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit e5c8f6e0800106c9331c975344086c7834fcae2a)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <fbd88f094ef3e9e43b4395bb7686bb9f6f76fb38.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virstoragetest.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index 39040bf4cb..e7794d6168 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -964,7 +964,7 @@ mymain(void)
+     /* Rewrite wrap and qcow2 back to 3-deep chain, absolute backing */
+     virCommandFree(cmd);
+     cmd = virCommandNewArgList(qemuimg, "rebase", "-u", "-f", "qcow2",
+-                               "-F", "qcow2", "-b", absraw, "qcow2", NULL);
++                               "-F", "raw", "-b", absraw, "qcow2", NULL);
+     if (virCommandRun(cmd, NULL) < 0)
+         ret = -1;
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-util-add-virBufferTrimChars.patch b/SOURCES/libvirt-util-add-virBufferTrimChars.patch
new file mode 100644
index 0000000..0114425
--- /dev/null
+++ b/SOURCES/libvirt-util-add-virBufferTrimChars.patch
@@ -0,0 +1,151 @@
+From 494b2a24ad03653b4a2658a741669943555744bf Mon Sep 17 00:00:00 2001
+Message-Id: <494b2a24ad03653b4a2658a741669943555744bf@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:07 +0100
+Subject: [PATCH] util: add virBufferTrimChars
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A new helper for trimming combinations of specified characters from
+the tail of the buffer.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit fdd48f5b737c09a0581bf666d1578f5bd5d0de12)
+
+Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <6c9d9490de405d56f3fd787dd5d02d3fb4943bb4.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/util/virbuffer.c     | 26 ++++++++++++++++++++++++++
+ src/util/virbuffer.h     |  1 +
+ tests/virbuftest.c       | 36 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 64 insertions(+)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 1f97879faa..dbbec0d567 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -1642,6 +1642,7 @@ virBufferSetIndent;
+ virBufferStrcat;
+ virBufferStrcatVArgs;
+ virBufferTrim;
++virBufferTrimChars;
+ virBufferURIEncodeString;
+ virBufferUse;
+ virBufferVasprintf;
+diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
+index 1b93110919..914c386b18 100644
+--- a/src/util/virbuffer.c
++++ b/src/util/virbuffer.c
+@@ -673,6 +673,32 @@ virBufferTrim(virBufferPtr buf, const char *str, int len)
+     g_string_truncate(buf->str, buf->str->len - len);
+ }
+ 
++/**
++ * virBufferTrimChars:
++ * @buf: the buffer to trim
++ * @trim: the characters to be trimmed
++ *
++ * Trim the tail of the buffer. The longest string that can be formed with
++ * the characters from @trim is trimmed.
++ */
++void
++virBufferTrimChars(virBufferPtr buf, const char *trim)
++{
++    ssize_t i;
++
++    if (!buf || !buf->str)
++        return;
++
++    if (!trim)
++        return;
++
++    for (i = buf->str->len - 1; i > 0; i--) {
++        if (!strchr(trim, buf->str->str[i]))
++            break;
++    }
++
++    g_string_truncate(buf->str, i + 1);
++}
+ 
+ /**
+  * virBufferAddStr:
+diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
+index 38758a9125..183f78f279 100644
+--- a/src/util/virbuffer.h
++++ b/src/util/virbuffer.h
+@@ -92,4 +92,5 @@ size_t virBufferGetIndent(const virBuffer *buf);
+ size_t virBufferGetEffectiveIndent(const virBuffer *buf);
+ 
+ void virBufferTrim(virBufferPtr buf, const char *trim, int len);
++void virBufferTrimChars(virBufferPtr buf, const char *trim);
+ void virBufferAddStr(virBufferPtr buf, const char *str);
+diff --git a/tests/virbuftest.c b/tests/virbuftest.c
+index 1780b62bf4..7919075000 100644
+--- a/tests/virbuftest.c
++++ b/tests/virbuftest.c
+@@ -12,6 +12,7 @@
+ struct testBufAddStrData {
+     const char *data;
+     const char *expect;
++    const char *arg;
+ };
+ 
+ static int testBufAutoIndent(const void *data G_GNUC_UNUSED)
+@@ -130,6 +131,30 @@ static int testBufTrim(const void *data G_GNUC_UNUSED)
+     return ret;
+ }
+ 
++static int
++testBufTrimChars(const void *opaque)
++{
++    const struct testBufAddStrData *data = opaque;
++    virBuffer buf = VIR_BUFFER_INITIALIZER;
++    g_autofree char *actual = NULL;
++
++    virBufferAddStr(&buf, data->data);
++    virBufferTrimChars(&buf, data->arg);
++
++    if (!(actual = virBufferContentAndReset(&buf))) {
++        VIR_TEST_DEBUG("buf is empty");
++        return -1;
++    }
++
++    if (STRNEQ_NULLABLE(actual, data->expect)) {
++        VIR_TEST_DEBUG("testBufEscapeStr(): Strings don't match:");
++        virTestDifference(stderr, data->expect, actual);
++        return -1;
++    }
++
++    return 0;
++}
++
+ static int testBufAddBuffer(const void *data G_GNUC_UNUSED)
+ {
+     virBuffer buf1 = VIR_BUFFER_INITIALIZER;
+@@ -411,6 +436,17 @@ mymain(void)
+     DO_TEST_ESCAPE_REGEX("^$.|?*+()[]{}\\",
+                          "\\^\\$\\.\\|\\?\\*\\+\\(\\)\\[\\]\\{\\}\\\\");
+ 
++#define DO_TEST_TRIM_CHARS(_data, _arg, _expect) \
++    do { \
++        struct testBufAddStrData info = { .data = _data, .expect = _expect, .arg = _arg }; \
++        if (virTestRun("Buf: Trim: " #_data, testBufTrimChars, &info) < 0) \
++            ret = -1; \
++    } while (0)
++
++    DO_TEST_TRIM_CHARS("Trimmm", "m", "Tri");
++    DO_TEST_TRIM_CHARS("-abcd-efgh--", "-", "-abcd-efgh");
++    DO_TEST_TRIM_CHARS("-hABC-efgh--", "-h", "-hABC-efg");
++
+     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-util-hash-Improve-debugability-of-Duplicate-key-error-message.patch b/SOURCES/libvirt-util-hash-Improve-debugability-of-Duplicate-key-error-message.patch
new file mode 100644
index 0000000..9771afb
--- /dev/null
+++ b/SOURCES/libvirt-util-hash-Improve-debugability-of-Duplicate-key-error-message.patch
@@ -0,0 +1,209 @@
+From 14d881a9ddd3820be9518cc38e5504f26bf5fd56 Mon Sep 17 00:00:00 2001
+Message-Id: <14d881a9ddd3820be9518cc38e5504f26bf5fd56@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:43 +0100
+Subject: [PATCH] util: hash: Improve debugability of "Duplicate key" error
+ message
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If we get a user reporting this error message being shown it's pretty
+useless in terms of actually debugging it since we don't know which hash
+and which key are actually subject to the error.
+
+This patch adds a new hash table callback which formats the
+user-readable version of the hash key and reports it in the new message
+which will look like:
+
+"Duplicate hash table key 'blah'"
+
+That way we will at least have an anchor point where to start the
+search.
+
+There are two special implementations of keys which are numeric so we
+add specific printer functions for them.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit ae60e05817d6ea2d47533051c31e16b430453d62)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <214b5e7934db2f3d3b097c9e19f4e89de4912b6d.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_addr.c |  9 +++++++++
+ src/util/vircgroup.c   |  8 ++++++++
+ src/util/virhash.c     | 22 ++++++++++++++++++++--
+ src/util/virhash.h     | 13 +++++++++++++
+ 4 files changed, 50 insertions(+), 2 deletions(-)
+
+diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
+index ef7ee80e6a..607ba56efd 100644
+--- a/src/conf/domain_addr.c
++++ b/src/conf/domain_addr.c
+@@ -1007,6 +1007,13 @@ virZPCIAddrKeyCopy(const void *name)
+ }
+ 
+ 
++static char *
++virZPCIAddrKeyPrintHuman(const void *name)
++{
++    return g_strdup_printf("%u", *((unsigned int *)name));
++}
++
++
+ static void
+ virZPCIAddrKeyFree(void *name)
+ {
+@@ -1041,6 +1048,7 @@ virDomainPCIAddressSetExtensionAlloc(virDomainPCIAddressSetPtr addrs,
+                                                        virZPCIAddrKeyCode,
+                                                        virZPCIAddrKeyEqual,
+                                                        virZPCIAddrKeyCopy,
++                                                       virZPCIAddrKeyPrintHuman,
+                                                        virZPCIAddrKeyFree)))
+             goto error;
+ 
+@@ -1048,6 +1056,7 @@ virDomainPCIAddressSetExtensionAlloc(virDomainPCIAddressSetPtr addrs,
+                                                        virZPCIAddrKeyCode,
+                                                        virZPCIAddrKeyEqual,
+                                                        virZPCIAddrKeyCopy,
++                                                       virZPCIAddrKeyPrintHuman,
+                                                        virZPCIAddrKeyFree)))
+             goto error;
+     }
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index 87ed9f4565..dff2f6fd3a 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -2502,6 +2502,13 @@ virCgroupPidCopy(const void *name)
+ }
+ 
+ 
++static char *
++virCgroupPidPrintHuman(const void *name)
++{
++    return g_strdup_printf("%ld", (const long)name);
++}
++
++
+ int
+ virCgroupKillRecursiveInternal(virCgroupPtr group,
+                                int signum,
+@@ -2587,6 +2594,7 @@ virCgroupKillRecursive(virCgroupPtr group, int signum)
+                                              virCgroupPidCode,
+                                              virCgroupPidEqual,
+                                              virCgroupPidCopy,
++                                             virCgroupPidPrintHuman,
+                                              NULL);
+ 
+     VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
+diff --git a/src/util/virhash.c b/src/util/virhash.c
+index 313ca57a54..edf11e8b7a 100644
+--- a/src/util/virhash.c
++++ b/src/util/virhash.c
+@@ -59,6 +59,7 @@ struct _virHashTable {
+     virHashKeyCode keyCode;
+     virHashKeyEqual keyEqual;
+     virHashKeyCopy keyCopy;
++    virHashKeyPrintHuman keyPrint;
+     virHashKeyFree keyFree;
+ };
+ 
+@@ -98,6 +99,14 @@ static void *virHashStrCopy(const void *name)
+     return ret;
+ }
+ 
++
++static char *
++virHashStrPrintHuman(const void *name)
++{
++    return g_strdup(name);
++}
++
++
+ static void virHashStrFree(void *name)
+ {
+     VIR_FREE(name);
+@@ -136,6 +145,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
+                                   virHashKeyCode keyCode,
+                                   virHashKeyEqual keyEqual,
+                                   virHashKeyCopy keyCopy,
++                                  virHashKeyPrintHuman keyPrint,
+                                   virHashKeyFree keyFree)
+ {
+     virHashTablePtr table = NULL;
+@@ -153,6 +163,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
+     table->keyCode = keyCode;
+     table->keyEqual = keyEqual;
+     table->keyCopy = keyCopy;
++    table->keyPrint = keyPrint;
+     table->keyFree = keyFree;
+ 
+     if (VIR_ALLOC_N(table->table, size) < 0) {
+@@ -180,6 +191,7 @@ virHashNew(virHashDataFree dataFree)
+                              virHashStrCode,
+                              virHashStrEqual,
+                              virHashStrCopy,
++                             virHashStrPrintHuman,
+                              virHashStrFree);
+ }
+ 
+@@ -200,6 +212,7 @@ virHashTablePtr virHashCreate(ssize_t size, virHashDataFree dataFree)
+                              virHashStrCode,
+                              virHashStrEqual,
+                              virHashStrCopy,
++                             virHashStrPrintHuman,
+                              virHashStrFree);
+ }
+ 
+@@ -353,8 +366,13 @@ virHashAddOrUpdateEntry(virHashTablePtr table, const void *name,
+                 entry->payload = userdata;
+                 return 0;
+             } else {
+-                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                               _("Duplicate key"));
++                g_autofree char *keystr = NULL;
++
++                if (table->keyPrint)
++                    keystr = table->keyPrint(name);
++
++                virReportError(VIR_ERR_INTERNAL_ERROR,
++                               _("Duplicate hash table key '%s'"), NULLSTR(keystr));
+                 return -1;
+             }
+         }
+diff --git a/src/util/virhash.h b/src/util/virhash.h
+index 6318c0b3cd..08f99d8a3d 100644
+--- a/src/util/virhash.h
++++ b/src/util/virhash.h
+@@ -86,6 +86,18 @@ typedef bool (*virHashKeyEqual)(const void *namea, const void *nameb);
+  * Returns a newly allocated copy of @name
+  */
+ typedef void *(*virHashKeyCopy)(const void *name);
++/**
++ * virHashKeyPrintHuman:
++ * @name: the hash key
++ *
++ * Get a human readable version of the key for error messages. Caller
++ * will free the returned string.
++ *
++ * Returns a string representation of the key for use in error messages. Caller
++ * promises to always free the returned string.
++ */
++typedef char *(*virHashKeyPrintHuman) (const void *name);
++
+ /**
+  * virHashKeyFree:
+  * @name: the hash key
+@@ -108,6 +120,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
+                                   virHashKeyCode keyCode,
+                                   virHashKeyEqual keyEqual,
+                                   virHashKeyCopy keyCopy,
++                                  virHashKeyPrintHuman keyPrint,
+                                   virHashKeyFree keyFree);
+ void virHashFree(virHashTablePtr table);
+ ssize_t virHashSize(const virHashTable *table);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-util-hash-Use-g_new0-for-allocating-hash-internals.patch b/SOURCES/libvirt-util-hash-Use-g_new0-for-allocating-hash-internals.patch
new file mode 100644
index 0000000..5a2bc01
--- /dev/null
+++ b/SOURCES/libvirt-util-hash-Use-g_new0-for-allocating-hash-internals.patch
@@ -0,0 +1,79 @@
+From 976fe48829d9dcee11ca33d9fcfdf013f3ad524e Mon Sep 17 00:00:00 2001
+Message-Id: <976fe48829d9dcee11ca33d9fcfdf013f3ad524e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:07:59 +0100
+Subject: [PATCH] util: hash: Use g_new0 for allocating hash internals
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use the glib helpers and remove the mention of returning NULL on failure
+of virHashNew, virHashCreate and virHashCreateFull.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 50f7483a0d69906e90849f7f0a30f3f535021852)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1793263
+Message-Id: <c80f6e73321ef7a1d5db60fa56fcadaac63c199b.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virhash.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/src/util/virhash.c b/src/util/virhash.c
+index edf11e8b7a..d5c5e017a1 100644
+--- a/src/util/virhash.c
++++ b/src/util/virhash.c
+@@ -138,7 +138,7 @@ virHashComputeKey(const virHashTable *table, const void *name)
+  *
+  * Create a new virHashTablePtr.
+  *
+- * Returns the newly created object, or NULL if an error occurred.
++ * Returns the newly created object.
+  */
+ virHashTablePtr virHashCreateFull(ssize_t size,
+                                   virHashDataFree dataFree,
+@@ -153,8 +153,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
+     if (size <= 0)
+         size = 256;
+ 
+-    if (VIR_ALLOC(table) < 0)
+-        return NULL;
++    table = g_new0(virHashTable, 1);
+ 
+     table->seed = virRandomBits(32);
+     table->size = size;
+@@ -166,10 +165,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
+     table->keyPrint = keyPrint;
+     table->keyFree = keyFree;
+ 
+-    if (VIR_ALLOC_N(table->table, size) < 0) {
+-        VIR_FREE(table);
+-        return NULL;
+-    }
++    table->table = g_new0(virHashEntryPtr, table->size);
+ 
+     return table;
+ }
+@@ -181,7 +177,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
+  *
+  * Create a new virHashTablePtr.
+  *
+- * Returns the newly created object, or NULL if an error occurred.
++ * Returns the newly created object.
+  */
+ virHashTablePtr
+ virHashNew(virHashDataFree dataFree)
+@@ -203,7 +199,7 @@ virHashNew(virHashDataFree dataFree)
+  *
+  * Create a new virHashTablePtr.
+  *
+- * Returns the newly created object, or NULL if an error occurred.
++ * Returns the newly created object.
+  */
+ virHashTablePtr virHashCreate(ssize_t size, virHashDataFree dataFree)
+ {
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-util-json-Introduce-virJSONValueArrayConcat.patch b/SOURCES/libvirt-util-json-Introduce-virJSONValueArrayConcat.patch
new file mode 100644
index 0000000..f228f9d
--- /dev/null
+++ b/SOURCES/libvirt-util-json-Introduce-virJSONValueArrayConcat.patch
@@ -0,0 +1,94 @@
+From 28699a44646cf4a754808fb2c815c741343264cd Mon Sep 17 00:00:00 2001
+Message-Id: <28699a44646cf4a754808fb2c815c741343264cd@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:17 +0100
+Subject: [PATCH] util: json: Introduce virJSONValueArrayConcat
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a helper that concatenates the second array into the first.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 3b60a0c0276ae7200b0bff7394e0d1e00706a1dd)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <d7f92bced2f95d7802dd3a823b7c6b966e454a7e.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/util/virjson.c       | 31 +++++++++++++++++++++++++++++++
+ src/util/virjson.h       |  2 ++
+ 3 files changed, 34 insertions(+)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index afa7d4fcae..bc2858fc00 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2279,6 +2279,7 @@ virISCSIScanTargets;
+ virJSONStringReformat;
+ virJSONValueArrayAppend;
+ virJSONValueArrayAppendString;
++virJSONValueArrayConcat;
+ virJSONValueArrayForeachSteal;
+ virJSONValueArrayGet;
+ virJSONValueArraySize;
+diff --git a/src/util/virjson.c b/src/util/virjson.c
+index 988a09e956..50993648eb 100644
+--- a/src/util/virjson.c
++++ b/src/util/virjson.c
+@@ -811,6 +811,37 @@ virJSONValueArrayAppendString(virJSONValuePtr object,
+ }
+ 
+ 
++/**
++ * virJSONValueArrayConcat:
++ * @a: JSON value array (destination)
++ * @c: JSON value array (source)
++ *
++ * Merges the members of @c array into @a. The values are stolen from @c.
++ */
++int
++virJSONValueArrayConcat(virJSONValuePtr a,
++                        virJSONValuePtr c)
++{
++    size_t i;
++
++    if (a->type != VIR_JSON_TYPE_ARRAY ||
++        c->type != VIR_JSON_TYPE_ARRAY) {
++        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("expecting JSON array"));
++        return -1;
++    }
++
++    a->data.array.values = g_renew(virJSONValuePtr, a->data.array.values,
++                                   a->data.array.nvalues + c->data.array.nvalues);
++
++    for (i = 0; i < c->data.array.nvalues; i++)
++        a->data.array.values[a->data.array.nvalues++] = g_steal_pointer(&c->data.array.values[i]);
++
++    c->data.array.nvalues = 0;
++
++    return 0;
++}
++
++
+ int
+ virJSONValueObjectHasKey(virJSONValuePtr object,
+                          const char *key)
+diff --git a/src/util/virjson.h b/src/util/virjson.h
+index 7a6b063b17..0894e91b59 100644
+--- a/src/util/virjson.h
++++ b/src/util/virjson.h
+@@ -71,6 +71,8 @@ virJSONValuePtr virJSONValueNewArrayFromBitmap(virBitmapPtr bitmap);
+ 
+ int virJSONValueObjectAppend(virJSONValuePtr object, const char *key, virJSONValuePtr value);
+ int virJSONValueArrayAppend(virJSONValuePtr object, virJSONValuePtr value);
++int virJSONValueArrayConcat(virJSONValuePtr a,
++                            virJSONValuePtr c);
+ 
+ int virJSONValueObjectHasKey(virJSONValuePtr object, const char *key);
+ virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr object, const char *key);
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-util-storage-Store-backing-store-format-in-virStorageSource.patch b/SOURCES/libvirt-util-storage-Store-backing-store-format-in-virStorageSource.patch
new file mode 100644
index 0000000..70ee8a9
--- /dev/null
+++ b/SOURCES/libvirt-util-storage-Store-backing-store-format-in-virStorageSource.patch
@@ -0,0 +1,155 @@
+From 80cb87e61c8e48d2714c9369c14a880352114d20 Mon Sep 17 00:00:00 2001
+Message-Id: <80cb87e61c8e48d2714c9369c14a880352114d20@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:37 +0100
+Subject: [PATCH] util: storage: Store backing store format in virStorageSource
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We store the backing file string in the structure so we should also
+store the format so that callers can be simplified.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 62539c5f7d6a994b9cbd677564e7206cab1c5a45)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <6f884591ac16f32370925bdb7746c655c7c87302.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 35 +++++++++++++++++------------------
+ src/util/virstoragefile.h |  1 +
+ 2 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 391e2ce86f..d594ee3695 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -935,15 +935,11 @@ virStorageFileGetEncryptionPayloadOffset(const struct FileEncryptionInfo *info,
+ static int
+ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
+                                   char *buf,
+-                                  size_t len,
+-                                  int *backingFormat)
++                                  size_t len)
+ {
+-    int dummy;
++    int format;
+     size_t i;
+ 
+-    if (!backingFormat)
+-        backingFormat = &dummy;
+-
+     VIR_DEBUG("path=%s, buf=%p, len=%zu, meta->format=%d",
+               meta->path, buf, len, meta->format);
+ 
+@@ -1009,8 +1005,10 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
+     VIR_FREE(meta->backingStoreRaw);
+     if (fileTypeInfo[meta->format].getBackingStore != NULL) {
+         int store = fileTypeInfo[meta->format].getBackingStore(&meta->backingStoreRaw,
+-                                                               backingFormat,
++                                                               &format,
+                                                                buf, len);
++        meta->backingStoreRawFormat = format;
++
+         if (store == BACKING_STORE_INVALID)
+             return 0;
+ 
+@@ -1135,20 +1133,18 @@ virStorageFileGetMetadataFromBuf(const char *path,
+                                  int *backingFormat)
+ {
+     virStorageSourcePtr ret = NULL;
+-    int dummy;
+-
+-    if (!backingFormat)
+-        backingFormat = &dummy;
+ 
+     if (!(ret = virStorageFileMetadataNew(path, format)))
+         return NULL;
+ 
+-    if (virStorageFileGetMetadataInternal(ret, buf, len,
+-                                          backingFormat) < 0) {
++    if (virStorageFileGetMetadataInternal(ret, buf, len) < 0) {
+         virObjectUnref(ret);
+         return NULL;
+     }
+ 
++    if (backingFormat)
++        *backingFormat = ret->backingStoreRawFormat;
++
+     return ret;
+ }
+ 
+@@ -1211,9 +1207,12 @@ virStorageFileGetMetadataFromFD(const char *path,
+         return NULL;
+     }
+ 
+-    if (virStorageFileGetMetadataInternal(meta, buf, len, backingFormat) < 0)
++    if (virStorageFileGetMetadataInternal(meta, buf, len) < 0)
+         return NULL;
+ 
++    if (backingFormat)
++        *backingFormat = meta->backingStoreRawFormat;
++
+     if (S_ISREG(sb.st_mode))
+         meta->type = VIR_STORAGE_TYPE_FILE;
+     else if (S_ISBLK(sb.st_mode))
+@@ -2293,6 +2292,7 @@ virStorageSourceCopy(const virStorageSource *src,
+     def->volume = g_strdup(src->volume);
+     def->relPath = g_strdup(src->relPath);
+     def->backingStoreRaw = g_strdup(src->backingStoreRaw);
++    def->backingStoreRawFormat = src->backingStoreRawFormat;
+     def->externalDataStoreRaw = g_strdup(src->externalDataStoreRaw);
+     def->snapshot = g_strdup(src->snapshot);
+     def->configFile = g_strdup(src->configFile);
+@@ -5000,7 +5000,6 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+                                  unsigned int depth)
+ {
+     size_t headerLen;
+-    int backingFormat;
+     int rv;
+     g_autofree char *buf = NULL;
+     g_autoptr(virStorageSource) backingStore = NULL;
+@@ -5018,7 +5017,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+                                                    &buf, &headerLen, cycle) < 0)
+         return -1;
+ 
+-    if (virStorageFileGetMetadataInternal(src, buf, headerLen, &backingFormat) < 0)
++    if (virStorageFileGetMetadataInternal(src, buf, headerLen) < 0)
+         return -1;
+ 
+     if (src->backingStoreRaw) {
+@@ -5029,7 +5028,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+         if (rv == 1)
+             return 0;
+ 
+-        backingStore->format = backingFormat;
++        backingStore->format = src->backingStoreRawFormat;
+ 
+         if (backingStore->format == VIR_STORAGE_FILE_AUTO) {
+             /* Assuming the backing store to be raw can lead to failures. We do
+@@ -5180,7 +5179,7 @@ virStorageFileGetBackingStoreStr(virStorageSourcePtr src,
+     if (!(tmp = virStorageSourceCopy(src, false)))
+         return -1;
+ 
+-    if (virStorageFileGetMetadataInternal(tmp, buf, headerLen, NULL) < 0)
++    if (virStorageFileGetMetadataInternal(tmp, buf, headerLen) < 0)
+         return -1;
+ 
+     *backing = g_steal_pointer(&tmp->backingStoreRaw);
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 2a684fd746..ecba418bb3 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -330,6 +330,7 @@ struct _virStorageSource {
+     /* Name of the child backing store recorded in metadata of the
+      * current file.  */
+     char *backingStoreRaw;
++    virStorageFileFormat backingStoreRawFormat;
+     /* Name of the child data file recorded in metadata of the current file. */
+     char *externalDataStoreRaw;
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-util-storagefile-Drop-image-format-probing-by-file-suffix.patch b/SOURCES/libvirt-util-storagefile-Drop-image-format-probing-by-file-suffix.patch
new file mode 100644
index 0000000..ed14789
--- /dev/null
+++ b/SOURCES/libvirt-util-storagefile-Drop-image-format-probing-by-file-suffix.patch
@@ -0,0 +1,191 @@
+From d926f32560cb7996b6a5ec08545d946bf0594fe8 Mon Sep 17 00:00:00 2001
+Message-Id: <d926f32560cb7996b6a5ec08545d946bf0594fe8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:28 +0100
+Subject: [PATCH] util: storagefile: Drop image format probing by file suffix
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Probing by file suffix was meant to be a last resort if probing by
+contents fails or is not supported. For most formats we never specified
+any suffix. There's a few formats implementing both magic bytes and
+suffix and finally DMG which had only suffix probing. Since suffix
+probing is nowhere reliable and only one format depends on in which has a
+comment that qemu doesn't do the probing either drop the whole
+infrastructure.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 181fccc2ed67a79d462dfcf5b6fcfd2fbb1702b9)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <113e583f0c032b616ea5c691fe36540ebb8e7c8f.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 58 ++++++++++++---------------------------
+ 1 file changed, 17 insertions(+), 41 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index fcbc97d96a..6b83fc0e24 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -146,12 +146,10 @@ struct FileEncryptionInfo {
+     int payloadOffset; /* start offset of the volume data (in 512 byte sectors) */
+ };
+ 
+-/* Either 'magic' or 'extension' *must* be provided */
+ struct FileTypeInfo {
+     int magicOffset;    /* Byte offset of the magic */
+     const char *magic;  /* Optional string of file magic
+                          * to check at head of file */
+-    const char *extension; /* Optional file extension to check */
+     enum lv_endian endian; /* Endianness of file format */
+ 
+     int versionOffset;    /* Byte offset from start of file
+@@ -297,17 +295,17 @@ static struct FileEncryptionInfo const qcow2EncryptionInfo[] = {
+ };
+ 
+ static struct FileTypeInfo const fileTypeInfo[] = {
+-    [VIR_STORAGE_FILE_NONE] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
++    [VIR_STORAGE_FILE_NONE] = { 0, NULL, LV_LITTLE_ENDIAN,
+                                 -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
+-    [VIR_STORAGE_FILE_RAW] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
++    [VIR_STORAGE_FILE_RAW] = { 0, NULL, LV_LITTLE_ENDIAN,
+                                -1, 0, {0}, 0, 0, 0,
+                                luksEncryptionInfo,
+                                NULL, NULL },
+-    [VIR_STORAGE_FILE_DIR] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
++    [VIR_STORAGE_FILE_DIR] = { 0, NULL, LV_LITTLE_ENDIAN,
+                                -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
+     [VIR_STORAGE_FILE_BOCHS] = {
+         /*"Bochs Virtual HD Image", */ /* Untested */
+-        0, NULL, NULL,
++        0, NULL,
+         LV_LITTLE_ENDIAN, 64, 4, {0x20000},
+         32+16+16+4+4+4+4+4, 8, 1, NULL, NULL, NULL
+     },
+@@ -316,7 +314,7 @@ static struct FileTypeInfo const fileTypeInfo[] = {
+            #V2.0 Format
+            modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1
+         */ /* Untested */
+-        0, NULL, NULL,
++        0, NULL,
+         LV_LITTLE_ENDIAN, -1, 0, {0},
+         -1, 0, 0, NULL, NULL, NULL
+     },
+@@ -324,50 +322,50 @@ static struct FileTypeInfo const fileTypeInfo[] = {
+         /* XXX QEMU says there's no magic for dmg,
+          * /usr/share/misc/magic lists double magic (both offsets
+          * would have to match) but then disables that check. */
+-        0, NULL, ".dmg",
++        0, NULL,
+         0, -1, 0, {0},
+         -1, 0, 0, NULL, NULL, NULL
+     },
+     [VIR_STORAGE_FILE_ISO] = {
+-        32769, "CD001", ".iso",
++        32769, "CD001",
+         LV_LITTLE_ENDIAN, -2, 0, {0},
+         -1, 0, 0, NULL, NULL, NULL
+     },
+     [VIR_STORAGE_FILE_VPC] = {
+-        0, "conectix", NULL,
++        0, "conectix",
+         LV_BIG_ENDIAN, 12, 4, {0x10000},
+         8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, NULL, NULL, NULL
+     },
+     /* TODO: add getBackingStore function */
+     [VIR_STORAGE_FILE_VDI] = {
+-        64, "\x7f\x10\xda\xbe", ".vdi",
++        64, "\x7f\x10\xda\xbe",
+         LV_LITTLE_ENDIAN, 68, 4, {0x00010001},
+         64 + 5 * 4 + 256 + 7 * 4, 8, 1, NULL, NULL, NULL},
+ 
+     /* Not direct file formats, but used for various drivers */
+-    [VIR_STORAGE_FILE_FAT] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
++    [VIR_STORAGE_FILE_FAT] = { 0, NULL, LV_LITTLE_ENDIAN,
+                                -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
+-    [VIR_STORAGE_FILE_VHD] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
++    [VIR_STORAGE_FILE_VHD] = { 0, NULL, LV_LITTLE_ENDIAN,
+                                -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
+-    [VIR_STORAGE_FILE_PLOOP] = { 0, "WithouFreSpacExt", NULL, LV_LITTLE_ENDIAN,
++    [VIR_STORAGE_FILE_PLOOP] = { 0, "WithouFreSpacExt", LV_LITTLE_ENDIAN,
+                                  -2, 0, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0,
+                                  PLOOP_SIZE_MULTIPLIER, NULL, NULL, NULL },
+ 
+     /* All formats with a backing store probe below here */
+     [VIR_STORAGE_FILE_COW] = {
+-        0, "OOOM", NULL,
++        0, "OOOM",
+         LV_BIG_ENDIAN, 4, 4, {2},
+         4+4+1024+4, 8, 1, NULL, cowGetBackingStore, NULL
+     },
+     [VIR_STORAGE_FILE_QCOW] = {
+-        0, "QFI", NULL,
++        0, "QFI",
+         LV_BIG_ENDIAN, 4, 4, {1},
+         QCOWX_HDR_IMAGE_SIZE, 8, 1,
+         qcow1EncryptionInfo,
+         qcowXGetBackingStore, NULL
+     },
+     [VIR_STORAGE_FILE_QCOW2] = {
+-        0, "QFI", NULL,
++        0, "QFI",
+         LV_BIG_ENDIAN, 4, 4, {2, 3},
+         QCOWX_HDR_IMAGE_SIZE, 8, 1,
+         qcow2EncryptionInfo,
+@@ -376,12 +374,12 @@ static struct FileTypeInfo const fileTypeInfo[] = {
+     },
+     [VIR_STORAGE_FILE_QED] = {
+         /* https://wiki.qemu.org/Features/QED */
+-        0, "QED", NULL,
++        0, "QED",
+         LV_LITTLE_ENDIAN, -2, 0, {0},
+         QED_HDR_IMAGE_SIZE, 8, 1, NULL, qedGetBackingStore, NULL
+     },
+     [VIR_STORAGE_FILE_VMDK] = {
+-        0, "KDMV", NULL,
++        0, "KDMV",
+         LV_LITTLE_ENDIAN, 4, 4, {1, 2, 3},
+         4+4+4, 8, 512, NULL, vmdk4GetBackingStore, NULL
+     },
+@@ -707,20 +705,6 @@ virStorageFileMatchesMagic(int magicOffset,
+ }
+ 
+ 
+-static bool
+-virStorageFileMatchesExtension(const char *extension,
+-                               const char *path)
+-{
+-    if (extension == NULL)
+-        return false;
+-
+-    if (virStringHasCaseSuffix(path, extension))
+-        return true;
+-
+-    return false;
+-}
+-
+-
+ static bool
+ virStorageFileMatchesVersion(int versionOffset,
+                              int versionSize,
+@@ -842,14 +826,6 @@ virStorageFileProbeFormatFromBuf(const char *path,
+                  "Please report new version to libvir-list@redhat.com",
+                  path, virStorageFileFormatTypeToString(possibleFormat));
+ 
+-    /* No magic, so check file extension */
+-    for (i = 0; i < VIR_STORAGE_FILE_LAST; i++) {
+-        if (virStorageFileMatchesExtension(fileTypeInfo[i].extension, path)) {
+-            format = i;
+-            goto cleanup;
+-        }
+-    }
+-
+  cleanup:
+     VIR_DEBUG("format=%d", format);
+     return format;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-util-storagefile-Properly-set-transport-type-when-parsing-NBD-strings.patch b/SOURCES/libvirt-util-storagefile-Properly-set-transport-type-when-parsing-NBD-strings.patch
new file mode 100644
index 0000000..7b9b4bc
--- /dev/null
+++ b/SOURCES/libvirt-util-storagefile-Properly-set-transport-type-when-parsing-NBD-strings.patch
@@ -0,0 +1,69 @@
+From c8d5d7684ae855f75e3bba3f72b5b3f973ccdea2 Mon Sep 17 00:00:00 2001
+Message-Id: <c8d5d7684ae855f75e3bba3f72b5b3f973ccdea2@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 17 Jan 2020 13:16:57 +0100
+Subject: [PATCH] util: storagefile: Properly set transport type when parsing
+ NBD strings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When parsing legacy NBD backing file strings such as
+'nbd:unix:/tmp/sock:exportname=/' we'd fail to set the transport to
+VIR_STORAGE_NET_HOST_TRANS_UNIX. This started to be a problem once we
+actually started to generate config of the backing store on the command
+line with -blockdev as the JSON code would try to format it as TCP and
+fail with:
+
+ internal error: argument key 'host' must not have null value
+
+Set the type properly and add a test.
+
+This bug was found by the libguestfs test suite in:
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791614
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reported-by: Ming Xie <mxie@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Tested-by: Richard W.M. Jones <rjones@redhat.com>
+(cherry picked from commit 5f2fa393f721861132500f717ce509bb66afcdb7)
+Message-Id: <79e24a6416d5bfbba6cdb2764b29663c2f8ccd45.1579263320.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
+---
+ src/util/virstoragefile.c | 2 +-
+ tests/virstoragetest.c    | 4 ++++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 1397f532fd..7a2af0ad94 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2964,7 +2964,7 @@ virStorageSourceParseNBDColonString(const char *nbdstr,
+         }
+ 
+         src->hosts->socket = g_strdup(backing[2]);
+-
++        src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
+    } else {
+         src->hosts->name = g_strdup(backing[1]);
+ 
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index 2862758752..370e19252b 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1258,6 +1258,10 @@ mymain(void)
+                        "<source protocol='nbd' name=':test'>\n"
+                        "  <host name='example.org' port='6000'/>\n"
+                        "</source>\n");
++    TEST_BACKING_PARSE("nbd:unix:/tmp/sock:exportname=/",
++                       "<source protocol='nbd' name='/'>\n"
++                       "  <host transport='unix' socket='/tmp/sock'/>\n"
++                       "</source>\n");
+     TEST_BACKING_PARSE("nbd://example.org:1234",
+                        "<source protocol='nbd'>\n"
+                        "  <host name='example.org' port='1234'/>\n"
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-util-virstoragefile-Add-data-structure-for-storing-storage-source-slices.patch b/SOURCES/libvirt-util-virstoragefile-Add-data-structure-for-storing-storage-source-slices.patch
new file mode 100644
index 0000000..0d94fbe
--- /dev/null
+++ b/SOURCES/libvirt-util-virstoragefile-Add-data-structure-for-storing-storage-source-slices.patch
@@ -0,0 +1,113 @@
+From 57dfcbb6715008f731deb02b8964fca5f38fd2fc Mon Sep 17 00:00:00 2001
+Message-Id: <57dfcbb6715008f731deb02b8964fca5f38fd2fc@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:15 +0100
+Subject: [PATCH] util: virstoragefile: Add data structure for storing storage
+ source slices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduce virStorageSourceSlice which will store the 'offset' and 'size'
+of a virStorageSource and declare it as 'sliceStorage' and 'sliceFormat'
+attributes of a virStorageSource.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 6efa04616553c573700906cb7154a8ceb3bd2cb3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <c0e6db154dbb2087bd6dbcae2e232b61f36b7800.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 29 +++++++++++++++++++++++++++++
+ src/util/virstoragefile.h | 12 ++++++++++++
+ 2 files changed, 41 insertions(+)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index b02fad92b6..0be4168d6e 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2248,6 +2248,30 @@ virStorageSourcePoolDefCopy(const virStorageSourcePoolDef *src)
+ }
+ 
+ 
++static virStorageSourceSlicePtr
++virStorageSourceSliceCopy(const virStorageSourceSlice *src)
++{
++    virStorageSourceSlicePtr ret = g_new0(virStorageSourceSlice, 1);
++
++    ret->offset = src->offset;
++    ret->size = src->size;
++    ret->nodename = g_strdup(src->nodename);
++
++    return ret;
++}
++
++
++static void
++virStorageSourceSliceFree(virStorageSourceSlicePtr slice)
++{
++    if (!slice)
++        return;
++
++    g_free(slice->nodename);
++    g_free(slice);
++}
++
++
+ /**
+  * virStorageSourcePtr:
+  *
+@@ -2302,6 +2326,9 @@ virStorageSourceCopy(const virStorageSource *src,
+     def->tlsAlias = g_strdup(src->tlsAlias);
+     def->tlsCertdir = g_strdup(src->tlsCertdir);
+ 
++    if (src->sliceStorage)
++        def->sliceStorage = virStorageSourceSliceCopy(src->sliceStorage);
++
+     if (src->nhosts) {
+         if (!(def->hosts = virStorageNetHostDefCopy(src->nhosts, src->hosts)))
+             return NULL;
+@@ -2581,6 +2608,8 @@ virStorageSourceClear(virStorageSourcePtr def)
+     VIR_FREE(def->timestamps);
+     VIR_FREE(def->externalDataStoreRaw);
+ 
++    virStorageSourceSliceFree(def->sliceStorage);
++
+     virObjectUnref(def->externalDataStore);
+     def->externalDataStore = NULL;
+ 
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 39e50a989d..1f41e6e357 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -242,6 +242,16 @@ struct _virStorageSourceNVMeDef {
+     /* Don't forget to update virStorageSourceNVMeDefCopy */
+ };
+ 
++
++typedef struct _virStorageSourceSlice virStorageSourceSlice;
++typedef virStorageSourceSlice *virStorageSourceSlicePtr;
++struct _virStorageSourceSlice {
++    unsigned long long offset;
++    unsigned long long size;
++    char *nodename;
++};
++
++
+ typedef struct _virStorageDriverData virStorageDriverData;
+ typedef virStorageDriverData *virStorageDriverDataPtr;
+ 
+@@ -286,6 +296,8 @@ struct _virStorageSource {
+     bool nocow;
+     bool sparse;
+ 
++    virStorageSourceSlicePtr sliceStorage;
++
+     virStoragePermsPtr perms;
+     virStorageTimestampsPtr timestamps;
+     unsigned long long capacity; /* in bytes, 0 if unknown */
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainCheckpointRedefinePrep-Set-current-checkpoint-if-there-isn-t-any.patch b/SOURCES/libvirt-virDomainCheckpointRedefinePrep-Set-current-checkpoint-if-there-isn-t-any.patch
new file mode 100644
index 0000000..faded4a
--- /dev/null
+++ b/SOURCES/libvirt-virDomainCheckpointRedefinePrep-Set-current-checkpoint-if-there-isn-t-any.patch
@@ -0,0 +1,50 @@
+From da9c0f143d7c917c98b7352be7954e8b2489aa9e Mon Sep 17 00:00:00 2001
+Message-Id: <da9c0f143d7c917c98b7352be7954e8b2489aa9e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 3 Apr 2020 14:32:58 +0200
+Subject: [PATCH] virDomainCheckpointRedefinePrep: Set 'current' checkpoint if
+ there isn't any
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When redefining checkpoints from scratch we'd not set the 'current'
+checkpoint if there wasn't any. This meant that the code wasn't ever
+able to set a 'current' checkpoint as any other one looks up if the
+parent of the redefined checkpoint is current.
+
+Since the backup code then requires the current checkpoint to start the
+lookup we'd not be able to perform a backup after restoring the
+checkpoint hierarchy.
+
+Reported-by: Eyal Shenitzky <eshenitz@redhat.com>
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 9428c4609c7b23b3afe89566dca9ac237256d3df)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1819755
+
+Message-Id: <53c1d685b40f0f540eeb4d15a17e308aab2bf648.1585916255.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/checkpoint_conf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/conf/checkpoint_conf.c b/src/conf/checkpoint_conf.c
+index 26bcfc16b7..d557fada49 100644
+--- a/src/conf/checkpoint_conf.c
++++ b/src/conf/checkpoint_conf.c
+@@ -550,6 +550,10 @@ virDomainCheckpointRedefinePrep(virDomainObjPtr vm,
+             *update_current = true;
+     }
+ 
++    /* set the first redefined checkpoint as current */
++    if (virDomainCheckpointGetCurrent(vm->checkpoints) == NULL)
++        *update_current = true;
++
+     other = virDomainCheckpointFindByName(vm->checkpoints, def->parent.name);
+     if (other) {
+         otherdef = virDomainCheckpointObjGetDef(other);
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-cleanup-label.patch b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-cleanup-label.patch
new file mode 100644
index 0000000..46b4dbb
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-cleanup-label.patch
@@ -0,0 +1,72 @@
+From eaf5a1634e29eb3c4c3267b7724038049dacadc7 Mon Sep 17 00:00:00 2001
+Message-Id: <eaf5a1634e29eb3c4c3267b7724038049dacadc7@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:55 +0100
+Subject: [PATCH] virDomainDiskAddISCSIPoolSourceHost: Remove 'cleanup' label
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4d5093ef75efdf87a941ffd3fbc1d974e031a0a3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <da07ec7957e5c8f502c43bf0542a0d42ae1f62ee.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index f0365329c6..436d094578 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31173,7 +31173,6 @@ static int
+ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+                                     virStoragePoolDefPtr pooldef)
+ {
+-    int ret = -1;
+     VIR_AUTOSTRINGLIST tokens = NULL;
+     size_t ntokens;
+ 
+@@ -31181,7 +31180,7 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+     if (pooldef->source.nhost != 1) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("Expected exactly 1 host for the storage pool"));
+-        goto cleanup;
++        return -1;
+     }
+ 
+     /* iscsi pool only supports one host */
+@@ -31195,13 +31194,13 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+ 
+     /* iscsi volume has name like "unit:0:0:1" */
+     if (!(tokens = virStringSplitCount(def->src->srcpool->volume, ":", 0, &ntokens)))
+-        goto cleanup;
++        return -1;
+ 
+     if (ntokens != 4) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("unexpected iscsi volume name '%s'"),
+                        def->src->srcpool->volume);
+-        goto cleanup;
++        return -1;
+     }
+ 
+     /* iscsi pool has only one source device path */
+@@ -31216,10 +31215,7 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+ 
+     def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
+ 
+-    ret = 0;
+-
+- cleanup:
+-    return ret;
++    return 0;
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-ternary-operator.patch b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-ternary-operator.patch
new file mode 100644
index 0000000..8af602e
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-ternary-operator.patch
@@ -0,0 +1,40 @@
+From 6502a0a52ec29cffc819254b71bea4f5b2fbd5ce Mon Sep 17 00:00:00 2001
+Message-Id: <6502a0a52ec29cffc819254b71bea4f5b2fbd5ce@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:56 +0100
+Subject: [PATCH] virDomainDiskAddISCSIPoolSourceHost: Remove ternary operator
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit e20c5b17037acca0cfffd983c0bcdd0ee5b7e628)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <bddaa981eda3b5145d460711aaf366f360fd155b.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 436d094578..89f1e44536 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31189,8 +31189,10 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+ 
+     def->src->hosts[0].name = g_strdup(pooldef->source.hosts[0].name);
+ 
+-    def->src->hosts[0].port = pooldef->source.hosts[0].port ?
+-        pooldef->source.hosts[0].port : 3260;
++    if (pooldef->source.hosts[0].port != 0)
++        def->src->hosts[0].port = pooldef->source.hosts[0].port;
++    else
++        def->src->hosts[0].port = 3260;
+ 
+     /* iscsi volume has name like "unit:0:0:1" */
+     if (!(tokens = virStringSplitCount(def->src->srcpool->volume, ":", 0, &ntokens)))
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Sanitize-handling-of-string-list.patch b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Sanitize-handling-of-string-list.patch
new file mode 100644
index 0000000..4bb4e30
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Sanitize-handling-of-string-list.patch
@@ -0,0 +1,63 @@
+From 39a1710d9a757391e6ecfdd5e1d5abd359e5a153 Mon Sep 17 00:00:00 2001
+Message-Id: <39a1710d9a757391e6ecfdd5e1d5abd359e5a153@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:53 +0100
+Subject: [PATCH] virDomainDiskAddISCSIPoolSourceHost: Sanitize handling of
+ string list
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use virStringSplitCount instead of virStringSplit so that we can drop
+the call to virStringListLength and use VIR_AUTOSTRINGLIST to declare
+it and allow removal of the cleanup section.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit c5b1c14379994369f5cb92bbb3da36d7d19150c2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <a763fc4d91f223a097e8b709e46c066d348a9e31.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 68d9ce9c4e..6973d97e1d 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31174,7 +31174,8 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+                                     virStoragePoolDefPtr pooldef)
+ {
+     int ret = -1;
+-    char **tokens = NULL;
++    VIR_AUTOSTRINGLIST tokens = NULL;
++    size_t ntokens;
+ 
+     /* Only support one host */
+     if (pooldef->source.nhost != 1) {
+@@ -31195,10 +31196,10 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+         pooldef->source.hosts[0].port : 3260;
+ 
+     /* iscsi volume has name like "unit:0:0:1" */
+-    if (!(tokens = virStringSplit(def->src->srcpool->volume, ":", 0)))
++    if (!(tokens = virStringSplitCount(def->src->srcpool->volume, ":", 0, &ntokens)))
+         goto cleanup;
+ 
+-    if (virStringListLength((const char * const *)tokens) != 4) {
++    if (ntokens != 4) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("unexpected iscsi volume name '%s'"),
+                        def->src->srcpool->volume);
+@@ -31220,7 +31221,6 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+     ret = 0;
+ 
+  cleanup:
+-    virStringListFree(tokens);
+     return ret;
+ }
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
new file mode 100644
index 0000000..68ea47c
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
@@ -0,0 +1,99 @@
+From 80b9f2b4c38eb0cb96e7ebb5d8b2c8ddaa5f7927 Mon Sep 17 00:00:00 2001
+Message-Id: <80b9f2b4c38eb0cb96e7ebb5d8b2c8ddaa5f7927@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:57 +0100
+Subject: [PATCH] virDomainDiskAddISCSIPoolSourceHost: Take virStorageSourcePtr
+ instead of virDomainDiskDefPtr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Only 'def->src' was ever used in this function. Use the source directly.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 47cad725536b9108f23f351fe9836d0469a70fc7)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <7079c5546d76a24c458729e54f408bec39877a3e.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 89f1e44536..9cbc7b47e7 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31170,7 +31170,7 @@ virDomainNetResolveActualType(virDomainNetDefPtr iface)
+ 
+ 
+ static int
+-virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
++virDomainDiskAddISCSIPoolSourceHost(virStorageSourcePtr src,
+                                     virStoragePoolDefPtr pooldef)
+ {
+     VIR_AUTOSTRINGLIST tokens = NULL;
+@@ -31184,38 +31184,38 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+     }
+ 
+     /* iscsi pool only supports one host */
+-    def->src->nhosts = 1;
+-    def->src->hosts = g_new0(virStorageNetHostDef, 1);
++    src->nhosts = 1;
++    src->hosts = g_new0(virStorageNetHostDef, 1);
+ 
+-    def->src->hosts[0].name = g_strdup(pooldef->source.hosts[0].name);
++    src->hosts[0].name = g_strdup(pooldef->source.hosts[0].name);
+ 
+     if (pooldef->source.hosts[0].port != 0)
+-        def->src->hosts[0].port = pooldef->source.hosts[0].port;
++        src->hosts[0].port = pooldef->source.hosts[0].port;
+     else
+-        def->src->hosts[0].port = 3260;
++        src->hosts[0].port = 3260;
+ 
+     /* iscsi volume has name like "unit:0:0:1" */
+-    if (!(tokens = virStringSplitCount(def->src->srcpool->volume, ":", 0, &ntokens)))
++    if (!(tokens = virStringSplitCount(src->srcpool->volume, ":", 0, &ntokens)))
+         return -1;
+ 
+     if (ntokens != 4) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("unexpected iscsi volume name '%s'"),
+-                       def->src->srcpool->volume);
++                       src->srcpool->volume);
+         return -1;
+     }
+ 
+     /* iscsi pool has only one source device path */
+-    def->src->path = g_strdup_printf("%s/%s", pooldef->source.devices[0].path,
+-                                     tokens[3]);
++    src->path = g_strdup_printf("%s/%s", pooldef->source.devices[0].path,
++                                tokens[3]);
+ 
+     /* Storage pool have not supported these 2 attributes yet,
+      * use the defaults.
+      */
+-    def->src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+-    def->src->hosts[0].socket = NULL;
++    src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
++    src->hosts[0].socket = NULL;
+ 
+-    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
++    src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
+ 
+     return 0;
+ }
+@@ -31258,7 +31258,7 @@ virDomainDiskTranslateISCSIDirect(virDomainDiskDefPtr def,
+         def->src->auth->secrettype = g_strdup(secrettype);
+     }
+ 
+-    if (virDomainDiskAddISCSIPoolSourceHost(def, pooldef) < 0)
++    if (virDomainDiskAddISCSIPoolSourceHost(def->src, pooldef) < 0)
+         return -1;
+ 
+     if (!def->src->initiator.iqn && pooldef->source.initiator.iqn &&
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-use-g_new0-instead-of-VIR_ALLOC_N.patch b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-use-g_new0-instead-of-VIR_ALLOC_N.patch
new file mode 100644
index 0000000..a2ae705
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskAddISCSIPoolSourceHost-use-g_new0-instead-of-VIR_ALLOC_N.patch
@@ -0,0 +1,39 @@
+From 93e06ede9932c53518c7b3c9bff01449f52e2be3 Mon Sep 17 00:00:00 2001
+Message-Id: <93e06ede9932c53518c7b3c9bff01449f52e2be3@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:54 +0100
+Subject: [PATCH] virDomainDiskAddISCSIPoolSourceHost: use g_new0 instead of
+ VIR_ALLOC_N
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 5eda34f2e11f7ba4a26b0948dfa0fffa400dfadd)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <67e8bcdbcd5c9a22c75d6da6316a0d950664c2b8.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 6973d97e1d..f0365329c6 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31186,9 +31186,7 @@ virDomainDiskAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+ 
+     /* iscsi pool only supports one host */
+     def->src->nhosts = 1;
+-
+-    if (VIR_ALLOC_N(def->src->hosts, def->src->nhosts) < 0)
+-        goto cleanup;
++    def->src->hosts = g_new0(virStorageNetHostDef, 1);
+ 
+     def->src->hosts[0].name = g_strdup(pooldef->source.hosts[0].name);
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskSourceNVMeFormat-Format-only-valid-managed-values.patch b/SOURCES/libvirt-virDomainDiskSourceNVMeFormat-Format-only-valid-managed-values.patch
new file mode 100644
index 0000000..d7ae104
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskSourceNVMeFormat-Format-only-valid-managed-values.patch
@@ -0,0 +1,43 @@
+From 2eff64aa7a19da95b2f865a40010ab96f6e2e70e Mon Sep 17 00:00:00 2001
+Message-Id: <2eff64aa7a19da95b2f865a40010ab96f6e2e70e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 24 Mar 2020 16:25:57 +0100
+Subject: [PATCH] virDomainDiskSourceNVMeFormat: Format only valid 'managed'
+ values
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+VIR_TRISTATE_BOOL_ABSENT which maps to the 'default' string would not be
+parsed back, so we shouldn't format it either.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit fac9a8b4c45bffbda28c20c99c84542a5e16cba5)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804617
+Message-Id: <562a24096551a25b6c06e33a9afa3fd10ab1598b.1585063415.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 1e8518139c..e3755fa285 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -24442,8 +24442,9 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf,
+                               const virStorageSourceNVMeDef *nvme)
+ {
+     virBufferAddLit(attrBuf, " type='pci'");
+-    virBufferAsprintf(attrBuf, " managed='%s'",
+-                      virTristateBoolTypeToString(nvme->managed));
++    if (nvme->managed != VIR_TRISTATE_BOOL_ABSENT)
++        virBufferAsprintf(attrBuf, " managed='%s'",
++                          virTristateBoolTypeToString(nvme->managed));
+     virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespc);
+     virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false);
+ }
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-virDomainDiskTranslateISCSIDirect-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch b/SOURCES/libvirt-virDomainDiskTranslateISCSIDirect-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
new file mode 100644
index 0000000..6274246
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskTranslateISCSIDirect-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
@@ -0,0 +1,88 @@
+From 452599b446bb9725e1b3b95d7733353b0d76c12f Mon Sep 17 00:00:00 2001
+Message-Id: <452599b446bb9725e1b3b95d7733353b0d76c12f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:59 +0100
+Subject: [PATCH] virDomainDiskTranslateISCSIDirect: Take virStorageSourcePtr
+ instead of virDomainDiskDefPtr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Only 'def->src' was ever used in this function. Use the source directly.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit bc42d88ffdef84a823092bfb35cd6bce39747366)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <6a9c4a227bb1ea5564bfb03d076b080d879239b4.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 14b675d5d6..68dd640dc5 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31239,30 +31239,30 @@ virDomainDiskTranslateSourcePoolAuth(virStorageSourcePtr src,
+ 
+ 
+ static int
+-virDomainDiskTranslateISCSIDirect(virDomainDiskDefPtr def,
++virDomainDiskTranslateISCSIDirect(virStorageSourcePtr src,
+                                   virStoragePoolDefPtr pooldef)
+ {
+-    def->src->srcpool->actualtype = VIR_STORAGE_TYPE_NETWORK;
+-    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
++    src->srcpool->actualtype = VIR_STORAGE_TYPE_NETWORK;
++    src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
+ 
+-    if (virDomainDiskTranslateSourcePoolAuth(def->src,
++    if (virDomainDiskTranslateSourcePoolAuth(src,
+                                              &pooldef->source) < 0)
+         return -1;
+ 
+     /* Source pool may not fill in the secrettype field,
+      * so we need to do so here
+      */
+-    if (def->src->auth && !def->src->auth->secrettype) {
++    if (src->auth && !src->auth->secrettype) {
+         const char *secrettype =
+             virSecretUsageTypeToString(VIR_SECRET_USAGE_TYPE_ISCSI);
+-        def->src->auth->secrettype = g_strdup(secrettype);
++        src->auth->secrettype = g_strdup(secrettype);
+     }
+ 
+-    if (virDomainDiskAddISCSIPoolSourceHost(def->src, pooldef) < 0)
++    if (virDomainDiskAddISCSIPoolSourceHost(src, pooldef) < 0)
+         return -1;
+ 
+-    if (!def->src->initiator.iqn && pooldef->source.initiator.iqn &&
+-        virStorageSourceInitiatorCopy(&def->src->initiator,
++    if (!src->initiator.iqn && pooldef->source.initiator.iqn &&
++        virStorageSourceInitiatorCopy(&src->initiator,
+                                       &pooldef->source.initiator) < 0) {
+         return -1;
+     }
+@@ -31387,7 +31387,7 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+             return -1;
+         }
+ 
+-        if (virDomainDiskTranslateISCSIDirect(def, pooldef) < 0)
++        if (virDomainDiskTranslateISCSIDirect(def->src, pooldef) < 0)
+             return -1;
+ 
+         break;
+@@ -31412,7 +31412,7 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+            break;
+ 
+        case VIR_STORAGE_SOURCE_POOL_MODE_DIRECT:
+-           if (virDomainDiskTranslateISCSIDirect(def, pooldef) < 0)
++           if (virDomainDiskTranslateISCSIDirect(def->src, pooldef) < 0)
+                return -1;
+            break;
+        }
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskTranslateSourcePool-Check-for-disk-type-correctly.patch b/SOURCES/libvirt-virDomainDiskTranslateSourcePool-Check-for-disk-type-correctly.patch
new file mode 100644
index 0000000..2f8cc1d
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskTranslateSourcePool-Check-for-disk-type-correctly.patch
@@ -0,0 +1,44 @@
+From 92d99bea060e3d86a6e3b2fdd2df089362303536 Mon Sep 17 00:00:00 2001
+Message-Id: <92d99bea060e3d86a6e3b2fdd2df089362303536@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Tue, 10 Mar 2020 08:03:12 +0100
+Subject: [PATCH] virDomainDiskTranslateSourcePool: Check for disk type
+ correctly
+
+When rewriting the virDomainDiskTranslateSourcePool() function in
+v6.1.0-rc1~184 a typo was introduced. Previously, we allowed
+startup policy only for those volumes which translated to
+VIR_STORAGE_TYPE_FILE. But starting with the referenced commit,
+the value we checked for was changed to VIR_STORAGE_VOL_FILE
+which comes from a different enum and has a different value too.
+This is wrong, because virStorageSourceGetActualType() returns a
+value from the original enum.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1811728
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 3918dbd84e4951b43f93fbf50ef52be00274850c)
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <ed47a6cb36e55e543ae4ed8cb9f55e1b100d7859.1583823787.git.mprivozn@redhat.com>
+Acked-by: Peter Krempa <pkrempa@redhat.com>
+---
+ src/conf/domain_conf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 3a370e6b90..77e3d25a2d 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31610,7 +31610,7 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+     }
+ 
+     if (def->startupPolicy != 0 &&
+-        virStorageSourceGetActualType(def->src) != VIR_STORAGE_VOL_FILE) {
++        virStorageSourceGetActualType(def->src) != VIR_STORAGE_TYPE_FILE) {
+         virReportError(VIR_ERR_XML_ERROR, "%s",
+                        _("'startupPolicy' is only valid for "
+                          "'file' type volume"));
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virDomainDiskTranslateSourcePool-Translate-volume-disks-in-whole-backing-chain.patch b/SOURCES/libvirt-virDomainDiskTranslateSourcePool-Translate-volume-disks-in-whole-backing-chain.patch
new file mode 100644
index 0000000..971b023
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskTranslateSourcePool-Translate-volume-disks-in-whole-backing-chain.patch
@@ -0,0 +1,64 @@
+From 9b5f10282394b3f3e2a54791f51c3eb8d21c40ce Mon Sep 17 00:00:00 2001
+Message-Id: <9b5f10282394b3f3e2a54791f51c3eb8d21c40ce@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:01 +0100
+Subject: [PATCH] virDomainDiskTranslateSourcePool: Translate 'volume' disks in
+ whole backing chain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Now that we accept full backing chains on input nothing should prevent
+users from also using disk type 'VOLUME' for specifying the backing
+images.
+
+Do the translation for the whole backing chain.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 37f01262eed9f37dd5eb7de8b83edd2fea741054)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <68818efffb0a38e33237e0db9a2b370cef3b6eaa.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index ecd00aa8fc..b46b92aecf 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31407,18 +31407,20 @@ int
+ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+ {
+     g_autoptr(virConnect) conn = NULL;
++    virStorageSourcePtr n;
+ 
+-    if (def->src->type != VIR_STORAGE_TYPE_VOLUME)
+-        return 0;
++    for (n = def->src; virStorageSourceIsBacking(n); n = n->backingStore) {
++        if (n->type != VIR_STORAGE_TYPE_VOLUME || !n->srcpool)
++            continue;
+ 
+-    if (!def->src->srcpool)
+-        return 0;
++        if (!conn) {
++            if (!(conn = virGetConnectStorage()))
++                return -1;
++        }
+ 
+-    if (!(conn = virGetConnectStorage()))
+-        return -1;
+-
+-    if (virDomainStorageSourceTranslateSourcePool(def->src, conn) < 0)
+-        return -1;
++        if (virDomainStorageSourceTranslateSourcePool(n, conn) < 0)
++            return -1;
++    }
+ 
+     if (def->startupPolicy != 0 &&
+         virStorageSourceGetActualType(def->src) != VIR_STORAGE_VOL_FILE) {
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskTranslateSourcePool-split-code-to-setup-one-storage-source.patch b/SOURCES/libvirt-virDomainDiskTranslateSourcePool-split-code-to-setup-one-storage-source.patch
new file mode 100644
index 0000000..0698684
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskTranslateSourcePool-split-code-to-setup-one-storage-source.patch
@@ -0,0 +1,228 @@
+From c6a7e638954bbcb8679966f31ce398d97fa1aca1 Mon Sep 17 00:00:00 2001
+Message-Id: <c6a7e638954bbcb8679966f31ce398d97fa1aca1@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:00 +0100
+Subject: [PATCH] virDomainDiskTranslateSourcePool: split code to setup one
+ storage source
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Extract all the code setting up one storage source from the rest which
+sets up the whole disk. This will allow us to prepare the whole backing
+chain.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 63469116cc83d6d83a45b741826b48562b03a65f)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <ed85da5fc3820ff9d272034b74cb03a63b35d9de.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 112 ++++++++++++++++++++---------------------
+ 1 file changed, 55 insertions(+), 57 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 68dd640dc5..ecd00aa8fc 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31271,37 +31271,28 @@ virDomainDiskTranslateISCSIDirect(virStorageSourcePtr src,
+ }
+ 
+ 
+-int
+-virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
++static int
++virDomainStorageSourceTranslateSourcePool(virStorageSourcePtr src,
++                                          virConnectPtr conn)
+ {
+     virStorageVolInfo info;
+     g_autoptr(virStoragePoolDef) pooldef = NULL;
+     g_autofree char *poolxml = NULL;
+-    g_autoptr(virConnect) conn = NULL;
+     g_autoptr(virStoragePool) pool = NULL;
+     g_autoptr(virStorageVol) vol = NULL;
+ 
+-    if (def->src->type != VIR_STORAGE_TYPE_VOLUME)
+-        return 0;
+-
+-    if (!def->src->srcpool)
+-        return 0;
+-
+-    if (!(conn = virGetConnectStorage()))
+-        return -1;
+-
+-    if (!(pool = virStoragePoolLookupByName(conn, def->src->srcpool->pool)))
++    if (!(pool = virStoragePoolLookupByName(conn, src->srcpool->pool)))
+         return -1;
+ 
+     if (virStoragePoolIsActive(pool) != 1) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                        _("storage pool '%s' containing volume '%s' "
+                          "is not active"),
+-                       def->src->srcpool->pool, def->src->srcpool->volume);
++                       src->srcpool->pool, src->srcpool->volume);
+         return -1;
+     }
+ 
+-    if (!(vol = virStorageVolLookupByName(pool, def->src->srcpool->volume)))
++    if (!(vol = virStorageVolLookupByName(pool, src->srcpool->volume)))
+         return -1;
+ 
+     if (virStorageVolGetInfo(vol, &info) < 0)
+@@ -31313,22 +31304,22 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+     if (!(pooldef = virStoragePoolDefParseString(poolxml)))
+         return -1;
+ 
+-    def->src->srcpool->pooltype = pooldef->type;
+-    def->src->srcpool->voltype = info.type;
++    src->srcpool->pooltype = pooldef->type;
++    src->srcpool->voltype = info.type;
+ 
+-    if (def->src->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
++    if (src->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
+         virReportError(VIR_ERR_XML_ERROR, "%s",
+                        _("disk source mode is only valid when "
+                          "storage pool is of iscsi type"));
+         return -1;
+     }
+ 
+-    VIR_FREE(def->src->path);
+-    virStorageNetHostDefFree(def->src->nhosts, def->src->hosts);
+-    def->src->nhosts = 0;
+-    def->src->hosts = NULL;
+-    virStorageAuthDefFree(def->src->auth);
+-    def->src->auth = NULL;
++    VIR_FREE(src->path);
++    virStorageNetHostDefFree(src->nhosts, src->hosts);
++    src->nhosts = 0;
++    src->hosts = NULL;
++    virStorageAuthDefFree(src->auth);
++    src->auth = NULL;
+ 
+     switch ((virStoragePoolType) pooldef->type) {
+     case VIR_STORAGE_POOL_DIR:
+@@ -31339,32 +31330,24 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+     case VIR_STORAGE_POOL_SCSI:
+     case VIR_STORAGE_POOL_ZFS:
+     case VIR_STORAGE_POOL_VSTORAGE:
+-        if (!(def->src->path = virStorageVolGetPath(vol)))
++        if (!(src->path = virStorageVolGetPath(vol)))
+             return -1;
+ 
+-        if (def->startupPolicy && info.type != VIR_STORAGE_VOL_FILE) {
+-            virReportError(VIR_ERR_XML_ERROR, "%s",
+-                           _("'startupPolicy' is only valid for "
+-                             "'file' type volume"));
+-            return -1;
+-        }
+-
+-
+         switch (info.type) {
+         case VIR_STORAGE_VOL_FILE:
+-            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
++            src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
+             break;
+ 
+         case VIR_STORAGE_VOL_DIR:
+-            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_DIR;
++            src->srcpool->actualtype = VIR_STORAGE_TYPE_DIR;
+             break;
+ 
+         case VIR_STORAGE_VOL_BLOCK:
+-            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
++            src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
+             break;
+ 
+         case VIR_STORAGE_VOL_PLOOP:
+-            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
++            src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
+             break;
+ 
+         case VIR_STORAGE_VOL_NETWORK:
+@@ -31380,39 +31363,25 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+         break;
+ 
+     case VIR_STORAGE_POOL_ISCSI_DIRECT:
+-        if (def->startupPolicy) {
+-            virReportError(VIR_ERR_XML_ERROR, "%s",
+-                           _("'startupPolicy' is only valid for "
+-                             "'file' type volume"));
+-            return -1;
+-        }
+-
+-        if (virDomainDiskTranslateISCSIDirect(def->src, pooldef) < 0)
++        if (virDomainDiskTranslateISCSIDirect(src, pooldef) < 0)
+             return -1;
+ 
+         break;
+ 
+     case VIR_STORAGE_POOL_ISCSI:
+-        if (def->startupPolicy) {
+-            virReportError(VIR_ERR_XML_ERROR, "%s",
+-                           _("'startupPolicy' is only valid for "
+-                             "'file' type volume"));
+-            return -1;
+-        }
+-
+-       switch (def->src->srcpool->mode) {
++       switch (src->srcpool->mode) {
+        case VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT:
+        case VIR_STORAGE_SOURCE_POOL_MODE_LAST:
+-           def->src->srcpool->mode = VIR_STORAGE_SOURCE_POOL_MODE_HOST;
++           src->srcpool->mode = VIR_STORAGE_SOURCE_POOL_MODE_HOST;
+            G_GNUC_FALLTHROUGH;
+        case VIR_STORAGE_SOURCE_POOL_MODE_HOST:
+-           def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
+-           if (!(def->src->path = virStorageVolGetPath(vol)))
++           src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
++           if (!(src->path = virStorageVolGetPath(vol)))
+                return -1;
+            break;
+ 
+        case VIR_STORAGE_SOURCE_POOL_MODE_DIRECT:
+-           if (virDomainDiskTranslateISCSIDirect(def->src, pooldef) < 0)
++           if (virDomainDiskTranslateISCSIDirect(src, pooldef) < 0)
+                return -1;
+            break;
+        }
+@@ -31434,6 +31403,35 @@ virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
+ }
+ 
+ 
++int
++virDomainDiskTranslateSourcePool(virDomainDiskDefPtr def)
++{
++    g_autoptr(virConnect) conn = NULL;
++
++    if (def->src->type != VIR_STORAGE_TYPE_VOLUME)
++        return 0;
++
++    if (!def->src->srcpool)
++        return 0;
++
++    if (!(conn = virGetConnectStorage()))
++        return -1;
++
++    if (virDomainStorageSourceTranslateSourcePool(def->src, conn) < 0)
++        return -1;
++
++    if (def->startupPolicy != 0 &&
++        virStorageSourceGetActualType(def->src) != VIR_STORAGE_VOL_FILE) {
++        virReportError(VIR_ERR_XML_ERROR, "%s",
++                       _("'startupPolicy' is only valid for "
++                         "'file' type volume"));
++        return -1;
++    }
++
++    return 0;
++}
++
++
+ /**
+  * virDomainDiskGetDetectZeroesMode:
+  * @discard: disk/image sector discard setting
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainDiskTranslateSourcePoolAuth-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch b/SOURCES/libvirt-virDomainDiskTranslateSourcePoolAuth-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
new file mode 100644
index 0000000..5f80d52
--- /dev/null
+++ b/SOURCES/libvirt-virDomainDiskTranslateSourcePoolAuth-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
@@ -0,0 +1,62 @@
+From c44dbb2ca444be1d655d41bcd8df8eec89784f81 Mon Sep 17 00:00:00 2001
+Message-Id: <c44dbb2ca444be1d655d41bcd8df8eec89784f81@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:09:58 +0100
+Subject: [PATCH] virDomainDiskTranslateSourcePoolAuth: Take
+ virStorageSourcePtr instead of virDomainDiskDefPtr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Only 'def->src' was ever used in this function. Use the source directly.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4fca8299c5d83378fc950f23bdf9fcca605a8251)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804603
+Message-Id: <66d9f9fe057c447d3b1fc5e93fce513b33242c05.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 9cbc7b47e7..14b675d5d6 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -31222,18 +31222,18 @@ virDomainDiskAddISCSIPoolSourceHost(virStorageSourcePtr src,
+ 
+ 
+ static int
+-virDomainDiskTranslateSourcePoolAuth(virDomainDiskDefPtr def,
++virDomainDiskTranslateSourcePoolAuth(virStorageSourcePtr src,
+                                      virStoragePoolSourcePtr source)
+ {
+     /* Only necessary when authentication set */
+     if (!source->auth)
+         return 0;
+ 
+-    def->src->auth = virStorageAuthDefCopy(source->auth);
+-    if (!def->src->auth)
++    src->auth = virStorageAuthDefCopy(source->auth);
++    if (!src->auth)
+         return -1;
+     /* A <disk> doesn't use <auth type='%s', so clear that out for the disk */
+-    def->src->auth->authType = VIR_STORAGE_AUTH_TYPE_NONE;
++    src->auth->authType = VIR_STORAGE_AUTH_TYPE_NONE;
+     return 0;
+ }
+ 
+@@ -31245,7 +31245,7 @@ virDomainDiskTranslateISCSIDirect(virDomainDiskDefPtr def,
+     def->src->srcpool->actualtype = VIR_STORAGE_TYPE_NETWORK;
+     def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
+ 
+-    if (virDomainDiskTranslateSourcePoolAuth(def,
++    if (virDomainDiskTranslateSourcePoolAuth(def->src,
+                                              &pooldef->source) < 0)
+         return -1;
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virDomainFSDefFree-Unref-private-data.patch b/SOURCES/libvirt-virDomainFSDefFree-Unref-private-data.patch
new file mode 100644
index 0000000..e5a6dc1
--- /dev/null
+++ b/SOURCES/libvirt-virDomainFSDefFree-Unref-private-data.patch
@@ -0,0 +1,53 @@
+From 4fd89121cecafd23bb45c517d5b8ff90d9b40a8f Mon Sep 17 00:00:00 2001
+Message-Id: <4fd89121cecafd23bb45c517d5b8ff90d9b40a8f@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 4 Mar 2020 12:42:34 +0100
+Subject: [PATCH] virDomainFSDefFree: Unref private data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The privateData object is allocated in virDomainFSDefNew() but
+never unref'd.
+
+==119642== 480 bytes in 20 blocks are definitely lost in loss record 656 of 671
+==119642==    at 0x4837B86: calloc (vg_replace_malloc.c:762)
+==119642==    by 0x57806A0: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.6000.7)
+==119642==    by 0x4AE7392: virAllocVar (viralloc.c:331)
+==119642==    by 0x4B64395: virObjectNew (virobject.c:241)
+==119642==    by 0x48F1464: qemuDomainFSPrivateNew (qemu_domain.c:1427)
+==119642==    by 0x4BBF004: virDomainFSDefNew (domain_conf.c:2307)
+==119642==    by 0x4BD859A: virDomainFSDefParseXML (domain_conf.c:11217)
+==119642==    by 0x4BF9DD1: virDomainDefParseXML (domain_conf.c:21179)
+==119642==    by 0x4BFCD5B: virDomainDefParseNode (domain_conf.c:21943)
+==119642==    by 0x4BFCC36: virDomainDefParse (domain_conf.c:21901)
+==119642==    by 0x4BFCCCB: virDomainDefParseFile (domain_conf.c:21924)
+==119642==    by 0x114A9D: testCompareXMLToArgv (qemuxml2argvtest.c:452)
+
+Fixes: 5120577ed79f89e172e3deed534fa9b585f4701f
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit d8b4f70e1e36772ef82dbe0f0706fa7845583e6c)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1694166
+Message-Id: <77519310a2e8c09b41bfcc0c8e37b1c2dcb35b5c.1583322090.git.jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/conf/domain_conf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 88117187c8..990c5bcc1e 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -2320,6 +2320,7 @@ void virDomainFSDefFree(virDomainFSDefPtr def)
+     VIR_FREE(def->dst);
+     virDomainDeviceInfoClear(&def->info);
+     VIR_FREE(def->virtio);
++    virObjectUnref(def->privateData);
+ 
+     VIR_FREE(def);
+ }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virDomainNetDefClear-Free-persistent-name.patch b/SOURCES/libvirt-virDomainNetDefClear-Free-persistent-name.patch
new file mode 100644
index 0000000..5b2f550
--- /dev/null
+++ b/SOURCES/libvirt-virDomainNetDefClear-Free-persistent-name.patch
@@ -0,0 +1,53 @@
+From 97d7066d53be18a9638d28217e2a4216fa422a53 Mon Sep 17 00:00:00 2001
+Message-Id: <97d7066d53be18a9638d28217e2a4216fa422a53@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 21 Feb 2020 14:32:11 +0100
+Subject: [PATCH] virDomainNetDefClear: Free @persistent name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The persistent alias name @persistent is allocated in
+virDomainNetDefParseXML() but never freed.
+
+==119642== 22 bytes in 2 blocks are definitely lost in loss record 178 of 671
+==119642==    at 0x483579F: malloc (vg_replace_malloc.c:309)
+==119642==    by 0x58F89F1: xmlStrndup (in /usr/lib64/libxml2.so.2.9.9)
+==119642==    by 0x4BA3B74: virXMLPropString (virxml.c:520)
+==119642==    by 0x4BDB0C5: virDomainNetDefParseXML (domain_conf.c:11876)
+==119642==    by 0x4BF9EF4: virDomainDefParseXML (domain_conf.c:21196)
+==119642==    by 0x4BFCD5B: virDomainDefParseNode (domain_conf.c:21943)
+==119642==    by 0x4BFCC36: virDomainDefParse (domain_conf.c:21901)
+==119642==    by 0x4BFCCCB: virDomainDefParseFile (domain_conf.c:21924)
+==119642==    by 0x114A9D: testCompareXMLToArgv (qemuxml2argvtest.c:452)
+==119642==    by 0x13894F: virTestRun (testutils.c:143)
+==119642==    by 0x11F46E: mymain (qemuxml2argvtest.c:1316)
+==119642==    by 0x13A60E: virTestMain (testutils.c:839
+
+Fixes: fb0509d06ac57434c2edbd81ee63deb32a0e598a
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 2ab278ec758b09398ea335626a41b453cdda6da7)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1805742
+Message-Id: <d64d26b106c91220bdcb95cd3dd90229fe449cd2.1582291906.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_conf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 5c11f49463..8a5f14d6cb 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -2439,6 +2439,7 @@ virDomainNetDefClear(virDomainNetDefPtr def)
+ 
+     VIR_FREE(def->backend.tap);
+     VIR_FREE(def->backend.vhost);
++    VIR_FREE(def->teaming.persistent);
+     VIR_FREE(def->virtPortProfile);
+     VIR_FREE(def->script);
+     VIR_FREE(def->domain_name);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virHashAddOrUpdateEntry-Simplify-allocation-of-new-entry.patch b/SOURCES/libvirt-virHashAddOrUpdateEntry-Simplify-allocation-of-new-entry.patch
new file mode 100644
index 0000000..d3e1ca8
--- /dev/null
+++ b/SOURCES/libvirt-virHashAddOrUpdateEntry-Simplify-allocation-of-new-entry.patch
@@ -0,0 +1,53 @@
+From ca0f45dfc891bfb383e365376c6a2b4bb2ae3ba3 Mon Sep 17 00:00:00 2001
+Message-Id: <ca0f45dfc891bfb383e365376c6a2b4bb2ae3ba3@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:20 +0100
+Subject: [PATCH] virHashAddOrUpdateEntry: Simplify allocation of new entry
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use g_new0 and skip checking of the return value of keyCopy callback
+as both are bound to return a valid pointer.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 509ddcfde2af565a63ba193d41395aa99ea4744e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <3e351cf75e5514f54bd2e6dc799792248dfe1f82.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virhash.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/src/util/virhash.c b/src/util/virhash.c
+index c57d9f8292..36a2d312fc 100644
+--- a/src/util/virhash.c
++++ b/src/util/virhash.c
+@@ -344,7 +344,6 @@ virHashAddOrUpdateEntry(virHashTablePtr table, const void *name,
+     size_t key, len = 0;
+     virHashEntryPtr entry;
+     virHashEntryPtr last = NULL;
+-    void *new_name;
+ 
+     if ((table == NULL) || (name == NULL))
+         return -1;
+@@ -374,12 +373,8 @@ virHashAddOrUpdateEntry(virHashTablePtr table, const void *name,
+         len++;
+     }
+ 
+-    if (VIR_ALLOC(entry) < 0 || !(new_name = table->keyCopy(name))) {
+-        VIR_FREE(entry);
+-        return -1;
+-    }
+-
+-    entry->name = new_name;
++    entry = g_new0(virHashEntry, 1);
++    entry->name = table->keyCopy(name);
+     entry->payload = userdata;
+ 
+     if (last)
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virJSONValueNewArray-Use-g_new0-to-allocate-and-remove-NULL-checks-from-callers.patch b/SOURCES/libvirt-virJSONValueNewArray-Use-g_new0-to-allocate-and-remove-NULL-checks-from-callers.patch
new file mode 100644
index 0000000..3676fa0
--- /dev/null
+++ b/SOURCES/libvirt-virJSONValueNewArray-Use-g_new0-to-allocate-and-remove-NULL-checks-from-callers.patch
@@ -0,0 +1,472 @@
+From 500025205783acaa29d3c0e020ef8c6ce9579784 Mon Sep 17 00:00:00 2001
+Message-Id: <500025205783acaa29d3c0e020ef8c6ce9579784@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:18 +0100
+Subject: [PATCH] virJSONValueNewArray: Use g_new0 to allocate and remove NULL
+ checks from callers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use the glib allocation function that never returns NULL and remove the
+now dead-code checks from all callers.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit d69470a18afa909a18f336e46a1817657b91635e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <1c666c563fe614b2c61bb47abb6d33dbcab91316.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/locking/lock_daemon.c        |  4 ++--
+ src/logging/log_handler.c        |  3 +--
+ src/network/leaseshelper.c       |  6 +-----
+ src/qemu/qemu_agent.c            |  6 +-----
+ src/qemu/qemu_backup.c           |  6 ++----
+ src/qemu/qemu_block.c            |  9 +++------
+ src/qemu/qemu_blockjob.c         |  3 +--
+ src/qemu/qemu_checkpoint.c       |  9 +++------
+ src/qemu/qemu_driver.c           |  3 +--
+ src/qemu/qemu_firmware.c         | 12 ++++--------
+ src/qemu/qemu_migration_params.c |  3 +--
+ src/qemu/qemu_monitor_json.c     |  3 +--
+ src/rpc/virnetserver.c           |  6 ++----
+ src/rpc/virnetserverservice.c    |  3 +--
+ src/util/virjson.c               | 13 ++-----------
+ src/util/virlockspace.c          |  6 ++----
+ src/util/virmacmap.c             |  8 ++++----
+ tests/qemublocktest.c            |  3 +--
+ tests/qemumonitorjsontest.c      |  5 ++---
+ 19 files changed, 35 insertions(+), 76 deletions(-)
+
+diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c
+index 65c38139c4..75e24eb2f6 100644
+--- a/src/locking/lock_daemon.c
++++ b/src/locking/lock_daemon.c
+@@ -949,8 +949,8 @@ virLockDaemonPreExecRestart(const char *state_file,
+         goto cleanup;
+     }
+ 
+-    if (!(lockspaces = virJSONValueNewArray()))
+-        goto cleanup;
++    lockspaces = virJSONValueNewArray();
++
+     if (virJSONValueObjectAppend(object, "lockspaces", lockspaces) < 0) {
+         virJSONValueFree(lockspaces);
+         goto cleanup;
+diff --git a/src/logging/log_handler.c b/src/logging/log_handler.c
+index 030c9d66e3..973c52c7cd 100644
+--- a/src/logging/log_handler.c
++++ b/src/logging/log_handler.c
+@@ -619,8 +619,7 @@ virLogHandlerPreExecRestart(virLogHandlerPtr handler)
+     if (!ret)
+         return NULL;
+ 
+-    if (!(files = virJSONValueNewArray()))
+-        goto error;
++    files = virJSONValueNewArray();
+ 
+     if (virJSONValueObjectAppend(ret, "files", files) < 0) {
+         virJSONValueFree(files);
+diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c
+index f1a061066e..dd1d5f70ee 100644
+--- a/src/network/leaseshelper.c
++++ b/src/network/leaseshelper.c
+@@ -200,11 +200,7 @@ main(int argc, char **argv)
+         break;
+     }
+ 
+-    if (!(leases_array_new = virJSONValueNewArray())) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                       _("failed to create json"));
+-        goto cleanup;
+-    }
++    leases_array_new = virJSONValueNewArray();
+ 
+     if (virLeaseReadCustomLeaseFile(leases_array_new, custom_lease_file,
+                                     delete ? ip : NULL, &server_duid) < 0)
+diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
+index 5fa8d24a91..f759785050 100644
+--- a/src/qemu/qemu_agent.c
++++ b/src/qemu/qemu_agent.c
+@@ -1203,9 +1203,6 @@ qemuAgentMakeStringsArray(const char **strings, unsigned int len)
+     size_t i;
+     virJSONValuePtr ret = virJSONValueNewArray(), str;
+ 
+-    if (!ret)
+-        return NULL;
+-
+     for (i = 0; i < len; i++) {
+         str = virJSONValueNewString(strings[i]);
+         if (!str)
+@@ -1536,8 +1533,7 @@ qemuAgentSetVCPUsCommand(qemuAgentPtr mon,
+     *nmodified = 0;
+ 
+     /* create the key data array */
+-    if (!(cpus = virJSONValueNewArray()))
+-        goto cleanup;
++    cpus = virJSONValueNewArray();
+ 
+     for (i = 0; i < ninfo; i++) {
+         qemuAgentCPUInfoPtr in = &info[i];
+diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
+index 8b1e9a7e19..2cc6ff7a42 100644
+--- a/src/qemu/qemu_backup.c
++++ b/src/qemu/qemu_backup.c
+@@ -180,8 +180,7 @@ qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental,
+     g_autoptr(virJSONValue) ret = NULL;
+     size_t incridx = 0;
+ 
+-    if (!(ret = virJSONValueNewArray()))
+-        return NULL;
++    ret = virJSONValueNewArray();
+ 
+     if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
+                                                          backingChain,
+@@ -819,8 +818,7 @@ qemuBackupBegin(virDomainObjPtr vm,
+         !(incremental = qemuBackupBeginCollectIncrementalCheckpoints(vm, def->incremental)))
+         goto endjob;
+ 
+-    if (!(actions = virJSONValueNewArray()))
+-        goto endjob;
++    actions = virJSONValueNewArray();
+ 
+     /* The 'chk' checkpoint must be rolled back if the transaction command
+      * which creates it on disk is not executed or fails */
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 13e240fdac..03f029368e 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -524,8 +524,7 @@ qemuBlockStorageSourceBuildHostsJSONSocketAddress(virStorageSourcePtr src,
+     virStorageNetHostDefPtr host;
+     size_t i;
+ 
+-    if (!(servers = virJSONValueNewArray()))
+-        return NULL;
++    servers = virJSONValueNewArray();
+ 
+     for (i = 0; i < src->nhosts; i++) {
+         host = src->hosts + i;
+@@ -590,8 +589,7 @@ qemuBlockStorageSourceBuildHostsJSONInetSocketAddress(virStorageSourcePtr src)
+     virStorageNetHostDefPtr host;
+     size_t i;
+ 
+-    if (!(servers = virJSONValueNewArray()))
+-        return NULL;
++    servers = virJSONValueNewArray();
+ 
+     for (i = 0; i < src->nhosts; i++) {
+         host = src->hosts + i;
+@@ -837,8 +835,7 @@ qemuBlockStorageSourceGetRBDProps(virStorageSourcePtr src,
+         username = srcPriv->secinfo->s.aes.username;
+         keysecret = srcPriv->secinfo->s.aes.alias;
+         /* the auth modes are modelled after our old command line generator */
+-        if (!(authmodes = virJSONValueNewArray()))
+-            return NULL;
++        authmodes = virJSONValueNewArray();
+ 
+         if (!(mode = virJSONValueNewString("cephx")) ||
+             virJSONValueArrayAppend(authmodes, mode) < 0)
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index e04fcf69d1..3dc9222a6f 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -1344,8 +1344,7 @@ qemuBlockJobProcessEventConcludedBackup(virQEMUDriverPtr driver,
+         return;
+ 
+     if (job->data.backup.bitmap) {
+-        if (!(actions = virJSONValueNewArray()))
+-            return;
++        actions = virJSONValueNewArray();
+ 
+         if (qemuMonitorTransactionBitmapRemove(actions,
+                                                job->disk->src->nodeformat,
+diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
+index 59b7f63fdc..c06bfe6a21 100644
+--- a/src/qemu/qemu_checkpoint.c
++++ b/src/qemu/qemu_checkpoint.c
+@@ -217,8 +217,7 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
+                     return -1;
+             }
+ 
+-            if (!(arr = virJSONValueNewArray()))
+-                return -1;
++            arr = virJSONValueNewArray();
+ 
+             if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
+                                                                  n->nodeformat,
+@@ -261,8 +260,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+     g_autoptr(GSList) relabelimages = NULL;
+     GSList *next;
+ 
+-    if (!(actions = virJSONValueNewArray()))
+-        return -1;
++    actions = virJSONValueNewArray();
+ 
+     qemuDomainObjEnterMonitor(driver, vm);
+     blockNamedNodeData = qemuMonitorBlockGetNamedNodeData(priv->mon);
+@@ -535,8 +533,7 @@ qemuCheckpointCreateCommon(virQEMUDriverPtr driver,
+     if ((parent = virDomainCheckpointGetCurrent(vm->checkpoints)))
+         (*def)->parent.parent_name = g_strdup(parent->def->name);
+ 
+-    if (!(tmpactions = virJSONValueNewArray()))
+-        return -1;
++    tmpactions = virJSONValueNewArray();
+ 
+     if (qemuCheckpointAddActions(vm, tmpactions, parent, *def) < 0)
+         return -1;
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index f7ad2dca28..0667402ebb 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -15619,8 +15619,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
+     if (virDomainObjCheckActive(vm) < 0)
+         return -1;
+ 
+-    if (!(actions = virJSONValueNewArray()))
+-        return -1;
++    actions = virJSONValueNewArray();
+ 
+     if (blockdev &&
+         !(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
+diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
+index 7fb57913e8..68e2c6b40f 100644
+--- a/src/qemu/qemu_firmware.c
++++ b/src/qemu/qemu_firmware.c
+@@ -651,8 +651,7 @@ qemuFirmwareInterfaceFormat(virJSONValuePtr doc,
+     g_autoptr(virJSONValue) interfacesJSON = NULL;
+     size_t i;
+ 
+-    if (!(interfacesJSON = virJSONValueNewArray()))
+-        return -1;
++    interfacesJSON = virJSONValueNewArray();
+ 
+     for (i = 0; i < fw->ninterfaces; i++) {
+         if (virJSONValueArrayAppendString(interfacesJSON,
+@@ -799,8 +798,7 @@ qemuFirmwareTargetFormat(virJSONValuePtr doc,
+     g_autoptr(virJSONValue) targetsJSON = NULL;
+     size_t i;
+ 
+-    if (!(targetsJSON = virJSONValueNewArray()))
+-        return -1;
++    targetsJSON = virJSONValueNewArray();
+ 
+     for (i = 0; i < fw->ntargets; i++) {
+         qemuFirmwareTargetPtr t = fw->targets[i];
+@@ -816,8 +814,7 @@ qemuFirmwareTargetFormat(virJSONValuePtr doc,
+                                            virQEMUCapsArchToString(t->architecture)) < 0)
+             return -1;
+ 
+-        if (!(machines = virJSONValueNewArray()))
+-            return -1;
++        machines = virJSONValueNewArray();
+ 
+         for (j = 0; j < t->nmachines; j++) {
+             if (virJSONValueArrayAppendString(machines,
+@@ -851,8 +848,7 @@ qemuFirmwareFeatureFormat(virJSONValuePtr doc,
+     g_autoptr(virJSONValue) featuresJSON = NULL;
+     size_t i;
+ 
+-    if (!(featuresJSON = virJSONValueNewArray()))
+-        return -1;
++    featuresJSON = virJSONValueNewArray();
+ 
+     for (i = 0; i < fw->nfeatures; i++) {
+         if (virJSONValueArrayAppendString(featuresJSON,
+diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
+index 9430ce1d00..45acf8cda2 100644
+--- a/src/qemu/qemu_migration_params.c
++++ b/src/qemu/qemu_migration_params.c
+@@ -785,8 +785,7 @@ qemuMigrationCapsToJSON(virBitmapPtr caps,
+     qemuMigrationCapability bit;
+     const char *name;
+ 
+-    if (!(json = virJSONValueNewArray()))
+-        return NULL;
++    json = virJSONValueNewArray();
+ 
+     for (bit = 0; bit < QEMU_MIGRATION_CAP_LAST; bit++) {
+         bool supported = false;
+diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
+index 3fc0bcb80c..8cd98dbf26 100644
+--- a/src/qemu/qemu_monitor_json.c
++++ b/src/qemu/qemu_monitor_json.c
+@@ -4802,8 +4802,7 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
+     size_t i;
+ 
+     /* create the key data array */
+-    if (!(keys = virJSONValueNewArray()))
+-        goto cleanup;
++    keys = virJSONValueNewArray();
+ 
+     for (i = 0; i < nkeycodes; i++) {
+         if (keycodes[i] > 0xffff) {
+diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
+index 4122636805..c87dade1a8 100644
+--- a/src/rpc/virnetserver.c
++++ b/src/rpc/virnetserver.c
+@@ -603,8 +603,7 @@ virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv)
+         goto error;
+     }
+ 
+-    if (!(services = virJSONValueNewArray()))
+-        goto error;
++    services = virJSONValueNewArray();
+ 
+     if (virJSONValueObjectAppend(object, "services", services) < 0) {
+         virJSONValueFree(services);
+@@ -622,8 +621,7 @@ virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv)
+         }
+     }
+ 
+-    if (!(clients = virJSONValueNewArray()))
+-        goto error;
++    clients = virJSONValueNewArray();
+ 
+     if (virJSONValueObjectAppend(object, "clients", clients) < 0) {
+         virJSONValueFree(clients);
+diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c
+index 5d1178f899..0a003e5814 100644
+--- a/src/rpc/virnetserverservice.c
++++ b/src/rpc/virnetserverservice.c
+@@ -353,8 +353,7 @@ virJSONValuePtr virNetServerServicePreExecRestart(virNetServerServicePtr svc)
+     if (virJSONValueObjectAppendNumberUint(object, "nrequests_client_max", svc->nrequests_client_max) < 0)
+         goto error;
+ 
+-    if (!(socks = virJSONValueNewArray()))
+-        goto error;
++    socks = virJSONValueNewArray();
+ 
+     if (virJSONValueObjectAppend(object, "socks", socks) < 0) {
+         virJSONValueFree(socks);
+diff --git a/src/util/virjson.c b/src/util/virjson.c
+index 50993648eb..ca57df816f 100644
+--- a/src/util/virjson.c
++++ b/src/util/virjson.c
+@@ -561,10 +561,7 @@ virJSONValueNewNull(void)
+ virJSONValuePtr
+ virJSONValueNewArray(void)
+ {
+-    virJSONValuePtr val;
+-
+-    if (VIR_ALLOC(val) < 0)
+-        return NULL;
++    virJSONValuePtr val = g_new0(virJSONValue, 1);
+ 
+     val->type = VIR_JSON_TYPE_ARRAY;
+ 
+@@ -1265,8 +1262,7 @@ virJSONValueNewArrayFromBitmap(virBitmapPtr bitmap)
+     virJSONValuePtr ret;
+     ssize_t pos = -1;
+ 
+-    if (!(ret = virJSONValueNewArray()))
+-        return NULL;
++    ret = virJSONValueNewArray();
+ 
+     if (!bitmap)
+         return ret;
+@@ -1522,8 +1518,6 @@ virJSONValueCopy(const virJSONValue *in)
+         break;
+     case VIR_JSON_TYPE_ARRAY:
+         out = virJSONValueNewArray();
+-        if (!out)
+-            return NULL;
+         for (i = 0; i < in->data.array.nvalues; i++) {
+             virJSONValuePtr val = NULL;
+             if (!(val = virJSONValueCopy(in->data.array.values[i])))
+@@ -1782,9 +1776,6 @@ virJSONParserHandleStartArray(void *ctx)
+ 
+     VIR_DEBUG("parser=%p", parser);
+ 
+-    if (!value)
+-        return 0;
+-
+     if (virJSONParserInsertValue(parser, value) < 0) {
+         virJSONValueFree(value);
+         return 0;
+diff --git a/src/util/virlockspace.c b/src/util/virlockspace.c
+index 59d47daae8..a44377f89e 100644
+--- a/src/util/virlockspace.c
++++ b/src/util/virlockspace.c
+@@ -443,8 +443,7 @@ virJSONValuePtr virLockSpacePreExecRestart(virLockSpacePtr lockspace)
+         virJSONValueObjectAppendString(object, "directory", lockspace->dir) < 0)
+         goto error;
+ 
+-    if (!(resources = virJSONValueNewArray()))
+-        goto error;
++    resources = virJSONValueNewArray();
+ 
+     if (virJSONValueObjectAppend(object, "resources", resources) < 0) {
+         virJSONValueFree(resources);
+@@ -479,8 +478,7 @@ virJSONValuePtr virLockSpacePreExecRestart(virLockSpacePtr lockspace)
+             goto error;
+         }
+ 
+-        if (!(owners = virJSONValueNewArray()))
+-            goto error;
++        owners = virJSONValueNewArray();
+ 
+         if (virJSONValueObjectAppend(child, "owners", owners) < 0) {
+             virJSONValueFree(owners);
+diff --git a/src/util/virmacmap.c b/src/util/virmacmap.c
+index cd74f67678..ec589334ea 100644
+--- a/src/util/virmacmap.c
++++ b/src/util/virmacmap.c
+@@ -206,10 +206,11 @@ virMACMapHashDumper(void *payload,
+     size_t i;
+     int ret = -1;
+ 
+-    if (!(obj = virJSONValueNewObject()) ||
+-        !(arr = virJSONValueNewArray()))
++    if (!(obj = virJSONValueNewObject()))
+         goto cleanup;
+ 
++    arr = virJSONValueNewArray();
++
+     for (i = 0; macs[i]; i++) {
+         virJSONValuePtr m = virJSONValueNewString(macs[i]);
+ 
+@@ -244,8 +245,7 @@ virMacMapDumpStrLocked(virMacMapPtr mgr,
+     virJSONValuePtr arr;
+     int ret = -1;
+ 
+-    if (!(arr = virJSONValueNewArray()))
+-        goto cleanup;
++    arr = virJSONValueNewArray();
+ 
+     if (virHashForEach(mgr->macs, virMACMapHashDumper, arr) < 0)
+         goto cleanup;
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index ed8b061e2e..5946cd6c6b 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -733,8 +733,7 @@ testQemuCheckpointDeleteMerge(const void *opaque)
+         return -1;
+     }
+ 
+-    if (!(actions = virJSONValueNewArray()))
+-        return -1;
++    actions = virJSONValueNewArray();
+ 
+     if (qemuCheckpointDiscardDiskBitmaps(data->chain,
+                                          nodedata,
+diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
+index 0334f83628..2c696a2e8b 100644
+--- a/tests/qemumonitorjsontest.c
++++ b/tests/qemumonitorjsontest.c
+@@ -2948,9 +2948,8 @@ testQemuMonitorJSONTransaction(const void *opaque)
+     if (!(test = qemuMonitorTestNewSchema(data->xmlopt, data->schema)))
+         return -1;
+ 
+-    if (!(actions = virJSONValueNewArray()) ||
+-        !(mergebitmaps = virJSONValueNewArray()))
+-        return -1;
++    actions = virJSONValueNewArray();
++    mergebitmaps = virJSONValueNewArray();
+ 
+     if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(mergebitmaps, "node1", "bitmap1") < 0 ||
+         qemuMonitorTransactionBitmapMergeSourceAddBitmap(mergebitmaps, "node2", "bitmap2") < 0)
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virSecretLookupDefCopy-Remove-return-value.patch b/SOURCES/libvirt-virSecretLookupDefCopy-Remove-return-value.patch
new file mode 100644
index 0000000..d853a55
--- /dev/null
+++ b/SOURCES/libvirt-virSecretLookupDefCopy-Remove-return-value.patch
@@ -0,0 +1,79 @@
+From c671c037d06c761708374dba1b7e4ed4041fe9fb Mon Sep 17 00:00:00 2001
+Message-Id: <c671c037d06c761708374dba1b7e4ed4041fe9fb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 20 Mar 2020 10:28:51 +0100
+Subject: [PATCH] virSecretLookupDefCopy: Remove return value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The function always returns succes so there's no need for a return
+value.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 02f909b8a6ad8c271693fed9ceab606f0dda2294)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1814923
+Message-Id: <a2f47ac4171ea9eaf3fbee12f22670ff10a1b98c.1584696274.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virsecret.c      | 3 +--
+ src/util/virsecret.h      | 4 ++--
+ src/util/virstoragefile.c | 3 +--
+ 3 files changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/src/util/virsecret.c b/src/util/virsecret.c
+index 174ce544c0..167ad24fdf 100644
+--- a/src/util/virsecret.c
++++ b/src/util/virsecret.c
+@@ -47,7 +47,7 @@ virSecretLookupDefClear(virSecretLookupTypeDefPtr def)
+ }
+ 
+ 
+-int
++void
+ virSecretLookupDefCopy(virSecretLookupTypeDefPtr dst,
+                        const virSecretLookupTypeDef *src)
+ {
+@@ -57,7 +57,6 @@ virSecretLookupDefCopy(virSecretLookupTypeDefPtr dst,
+     } else if (dst->type == VIR_SECRET_LOOKUP_TYPE_USAGE) {
+         dst->u.usage = g_strdup(src->u.usage);
+     }
+-    return 0;
+ }
+ 
+ 
+diff --git a/src/util/virsecret.h b/src/util/virsecret.h
+index 8bc8a24e0f..780b5761f4 100644
+--- a/src/util/virsecret.h
++++ b/src/util/virsecret.h
+@@ -49,8 +49,8 @@ struct _virSecretLookupTypeDef {
+ };
+ 
+ void virSecretLookupDefClear(virSecretLookupTypeDefPtr def);
+-int virSecretLookupDefCopy(virSecretLookupTypeDefPtr dst,
+-                           const virSecretLookupTypeDef *src);
++void virSecretLookupDefCopy(virSecretLookupTypeDefPtr dst,
++                            const virSecretLookupTypeDef *src);
+ int virSecretLookupParseSecret(xmlNodePtr secretnode,
+                                virSecretLookupTypeDefPtr def);
+ void virSecretLookupFormatSecret(virBufferPtr buf,
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index ce126f5cba..fa37840532 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -1792,8 +1792,7 @@ virStorageAuthDefCopy(const virStorageAuthDef *src)
+     authdef->secrettype = g_strdup(src->secrettype);
+     authdef->authType = src->authType;
+ 
+-    if (virSecretLookupDefCopy(&authdef->seclookupdef, &src->seclookupdef) < 0)
+-        return NULL;
++    virSecretLookupDefCopy(&authdef->seclookupdef, &src->seclookupdef);
+ 
+     return g_steal_pointer(&authdef);
+ }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virSecurityManagerMetadataLock-Store-locked-paths.patch b/SOURCES/libvirt-virSecurityManagerMetadataLock-Store-locked-paths.patch
new file mode 100644
index 0000000..9a7d0ca
--- /dev/null
+++ b/SOURCES/libvirt-virSecurityManagerMetadataLock-Store-locked-paths.patch
@@ -0,0 +1,115 @@
+From 157a222a2001e3d5df4851ea3f43a00873f82be1 Mon Sep 17 00:00:00 2001
+Message-Id: <157a222a2001e3d5df4851ea3f43a00873f82be1@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Tue, 25 Feb 2020 11:24:50 +0100
+Subject: [PATCH] virSecurityManagerMetadataLock: Store locked paths
+
+So far, in the lock state we are storing only the file
+descriptors of the files we've locked. Therefore, when unlocking
+them and something does wrong the only thing we can report is FD
+number, which is not user friendly at all. But if we store paths
+among with FDs we can do better error reporting.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 256e01e59e922ff70dce56284e53e3463d4dc072)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1804672
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <8b12c9adde3c8553b4a2b588ac1a657d0638336b.1582626185.git.mprivozn@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/security/security_manager.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/src/security/security_manager.c b/src/security/security_manager.c
+index f229d94570..05d20e36af 100644
+--- a/src/security/security_manager.c
++++ b/src/security/security_manager.c
+@@ -1246,8 +1246,9 @@ virSecurityManagerRestoreTPMLabels(virSecurityManagerPtr mgr,
+ 
+ 
+ struct _virSecurityManagerMetadataLockState {
+-    size_t nfds;
++    size_t nfds; /* Captures size of both @fds and @paths */
+     int *fds;
++    const char **paths;
+ };
+ 
+ 
+@@ -1278,6 +1279,7 @@ cmpstringp(const void *p1, const void *p2)
+  *
+  * Lock passed @paths for metadata change. The returned state
+  * should be passed to virSecurityManagerMetadataUnlock.
++ * Passed @paths must not be freed until the corresponding unlock call.
+  *
+  * NOTE: this function is not thread safe (because of usage of
+  * POSIX locks).
+@@ -1293,9 +1295,11 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
+     size_t i = 0;
+     size_t nfds = 0;
+     int *fds = NULL;
++    const char **locked_paths = NULL;
+     virSecurityManagerMetadataLockStatePtr ret = NULL;
+ 
+-    if (VIR_ALLOC_N(fds, npaths) < 0)
++    if (VIR_ALLOC_N(fds, npaths) < 0 ||
++        VIR_ALLOC_N(locked_paths, npaths) < 0)
+         return NULL;
+ 
+     /* Sort paths to lock in order to avoid deadlocks with other
+@@ -1372,12 +1376,14 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
+             break;
+         } while (1);
+ 
++        locked_paths[nfds] = p;
+         VIR_APPEND_ELEMENT_COPY_INPLACE(fds, nfds, fd);
+     }
+ 
+     if (VIR_ALLOC(ret) < 0)
+         goto cleanup;
+ 
++    ret->paths = g_steal_pointer(&locked_paths);
+     ret->fds = g_steal_pointer(&fds);
+     ret->nfds = nfds;
+     nfds = 0;
+@@ -1386,6 +1392,7 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
+     for (i = nfds; i > 0; i--)
+         VIR_FORCE_CLOSE(fds[i - 1]);
+     VIR_FREE(fds);
++    VIR_FREE(locked_paths);
+     return ret;
+ }
+ 
+@@ -1401,21 +1408,23 @@ virSecurityManagerMetadataUnlock(virSecurityManagerPtr mgr G_GNUC_UNUSED,
+ 
+     for (i = 0; i < (*state)->nfds; i++) {
+         char ebuf[1024];
++        const char *path = (*state)->paths[i];
+         int fd = (*state)->fds[i];
+ 
+         /* Technically, unlock is not needed because it will
+          * happen on VIR_CLOSE() anyway. But let's play it nice. */
+         if (virFileUnlock(fd, METADATA_OFFSET, METADATA_LEN) < 0) {
+-            VIR_WARN("Unable to unlock fd %d: %s",
+-                     fd, virStrerror(errno, ebuf, sizeof(ebuf)));
++            VIR_WARN("Unable to unlock fd %d path %s: %s",
++                     fd, path, virStrerror(errno, ebuf, sizeof(ebuf)));
+         }
+ 
+         if (VIR_CLOSE(fd) < 0) {
+-            VIR_WARN("Unable to close fd %d: %s",
+-                     fd, virStrerror(errno, ebuf, sizeof(ebuf)));
++            VIR_WARN("Unable to close fd %d path %s: %s",
++                     fd, path, virStrerror(errno, ebuf, sizeof(ebuf)));
+         }
+     }
+ 
+     VIR_FREE((*state)->fds);
++    VIR_FREE((*state)->paths);
+     VIR_FREE(*state);
+ }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageBackendGlusterRefreshVol-Refactor-handling-of-backing-store.patch b/SOURCES/libvirt-virStorageBackendGlusterRefreshVol-Refactor-handling-of-backing-store.patch
new file mode 100644
index 0000000..c7125d5
--- /dev/null
+++ b/SOURCES/libvirt-virStorageBackendGlusterRefreshVol-Refactor-handling-of-backing-store.patch
@@ -0,0 +1,65 @@
+From 315706837bdb6f11c0bb4b48612d35afa1965454 Mon Sep 17 00:00:00 2001
+Message-Id: <315706837bdb6f11c0bb4b48612d35afa1965454@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:39 +0100
+Subject: [PATCH] virStorageBackendGlusterRefreshVol: Refactor handling of
+ backing store
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Take the format of the backing store from the 'meta' object directly and
+use g_steal_pointer to steal the path.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit fee56942e2dacc64ed4b36aa2ea887f60c117659)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <8bf19c252bd0a49ef7e689c809314345d7831735.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/storage/storage_backend_gluster.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
+index 4a8ee3870d..e92e9612bd 100644
+--- a/src/storage/storage_backend_gluster.c
++++ b/src/storage/storage_backend_gluster.c
+@@ -224,7 +224,6 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
+     int ret = -1;
+     glfs_fd_t *fd = NULL;
+     ssize_t len;
+-    int backingFormat;
+     g_autoptr(virStorageVolDef) vol = NULL;
+     g_autoptr(virStorageSource) meta = NULL;
+     g_autofree char *header = NULL;
+@@ -277,7 +276,7 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
+ 
+     if (!(meta = virStorageFileGetMetadataFromBuf(name, header, len,
+                                                   VIR_STORAGE_FILE_AUTO,
+-                                                  &backingFormat)))
++                                                  NULL)))
+         goto cleanup;
+ 
+     if (meta->backingStoreRaw) {
+@@ -286,13 +285,11 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
+ 
+         vol->target.backingStore->type = VIR_STORAGE_TYPE_NETWORK;
+ 
+-        vol->target.backingStore->path = meta->backingStoreRaw;
++        vol->target.backingStore->path = g_steal_pointer(&meta->backingStoreRaw);
++        vol->target.backingStore->format = meta->backingStoreRawFormat;
+ 
+-        if (backingFormat < 0)
++        if (vol->target.backingStore->format < 0)
+             vol->target.backingStore->format = VIR_STORAGE_FILE_RAW;
+-        else
+-            vol->target.backingStore->format = backingFormat;
+-        meta->backingStoreRaw = NULL;
+     }
+ 
+     vol->target.format = meta->format;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageEncryptionSecretCopy-Properly-copy-internals.patch b/SOURCES/libvirt-virStorageEncryptionSecretCopy-Properly-copy-internals.patch
new file mode 100644
index 0000000..ba630dd
--- /dev/null
+++ b/SOURCES/libvirt-virStorageEncryptionSecretCopy-Properly-copy-internals.patch
@@ -0,0 +1,50 @@
+From 914a920180c9803a57c06bd71f5270724c1dc900 Mon Sep 17 00:00:00 2001
+Message-Id: <914a920180c9803a57c06bd71f5270724c1dc900@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 20 Mar 2020 10:28:52 +0100
+Subject: [PATCH] virStorageEncryptionSecretCopy: Properly copy internals
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+virStorageEncryptionSecretPtr may have a string inside it, thus we must
+copy the string too. Use virSecretLookupDefCopy to do that.
+
+Caused by non-obvious code introduced in 756b46ddd24 and later 47e88b33b
+which added a string that needed to be copied.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1814923
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 299796328c34a30295d6cdc7ebce5d65843e921f)
+Message-Id: <2e350bb771f75d9fd068f69a595401907d92ca33.1584696274.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstorageencryption.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/src/util/virstorageencryption.c b/src/util/virstorageencryption.c
+index 74836d4a00..6765fdc23a 100644
+--- a/src/util/virstorageencryption.c
++++ b/src/util/virstorageencryption.c
+@@ -85,12 +85,10 @@ virStorageEncryptionFree(virStorageEncryptionPtr enc)
+ static virStorageEncryptionSecretPtr
+ virStorageEncryptionSecretCopy(const virStorageEncryptionSecret *src)
+ {
+-    virStorageEncryptionSecretPtr ret;
+-
+-    if (VIR_ALLOC(ret) < 0)
+-        return NULL;
++    virStorageEncryptionSecretPtr ret = g_new0(virStorageEncryptionSecret, 1);
+ 
+-    memcpy(ret, src, sizeof(*src));
++    ret->type = src->type;
++    virSecretLookupDefCopy(&ret->seclookupdef, &src->seclookupdef);
+ 
+     return ret;
+ }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataFromBuf-Remove-backingFormat-argument.patch b/SOURCES/libvirt-virStorageFileGetMetadataFromBuf-Remove-backingFormat-argument.patch
new file mode 100644
index 0000000..d97f609
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataFromBuf-Remove-backingFormat-argument.patch
@@ -0,0 +1,111 @@
+From dfcebf2ac266805c4e144091c04b27155972222f Mon Sep 17 00:00:00 2001
+Message-Id: <dfcebf2ac266805c4e144091c04b27155972222f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:40 +0100
+Subject: [PATCH] virStorageFileGetMetadataFromBuf: Remove 'backingFormat'
+ argument
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+None of the callers actually use it.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 57df35aeadd2107a3c728fe0939e0779121168c0)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <67e0987c502a062fc17ee1d2701501bfdcd0cc92.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/storage/storage_backend_gluster.c |  3 +--
+ src/util/virstoragefile.c             | 16 ++++++----------
+ src/util/virstoragefile.h             |  3 +--
+ 3 files changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
+index e92e9612bd..db3df82aad 100644
+--- a/src/storage/storage_backend_gluster.c
++++ b/src/storage/storage_backend_gluster.c
+@@ -275,8 +275,7 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
+         goto cleanup;
+ 
+     if (!(meta = virStorageFileGetMetadataFromBuf(name, header, len,
+-                                                  VIR_STORAGE_FILE_AUTO,
+-                                                  NULL)))
++                                                  VIR_STORAGE_FILE_AUTO)))
+         goto cleanup;
+ 
+     if (meta->backingStoreRaw) {
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index d80780e291..1b9bd12284 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -1109,7 +1109,6 @@ virStorageFileMetadataNew(const char *path,
+  * @buf: header bytes from @path
+  * @len: length of @buf
+  * @format: format of the storage file
+- * @backingFormat: format of @backing
+  *
+  * Extract metadata about the storage volume with the specified image format.
+  * If image format is VIR_STORAGE_FILE_AUTO, it will probe to automatically
+@@ -1119,9 +1118,10 @@ virStorageFileMetadataNew(const char *path,
+  * that might be raw if that file will then be passed to a guest, since a
+  * malicious guest can turn a raw file into any other non-raw format at will.
+  *
+- * If the returned @backingFormat is VIR_STORAGE_FILE_AUTO it indicates the
+- * image didn't specify an explicit format for its backing store. Callers are
+- * advised against probing for the backing store format in this case.
++ * If the 'backingStoreRawFormat' field of the returned structure is
++ * VIR_STORAGE_FILE_AUTO it indicates the image didn't specify an explicit
++ * format for its backing store. Callers are advised against probing for the
++ * backing store format in this case.
+  *
+  * Caller MUST free the result after use via virObjectUnref.
+  */
+@@ -1129,8 +1129,7 @@ virStorageSourcePtr
+ virStorageFileGetMetadataFromBuf(const char *path,
+                                  char *buf,
+                                  size_t len,
+-                                 int format,
+-                                 int *backingFormat)
++                                 int format)
+ {
+     virStorageSourcePtr ret = NULL;
+ 
+@@ -1142,9 +1141,6 @@ virStorageFileGetMetadataFromBuf(const char *path,
+         return NULL;
+     }
+ 
+-    if (backingFormat)
+-        *backingFormat = ret->backingStoreRawFormat;
+-
+     return ret;
+ }
+ 
+@@ -3991,7 +3987,7 @@ virStorageSourceUpdateCapacity(virStorageSourcePtr src,
+     if (format == VIR_STORAGE_FILE_RAW && !src->encryption) {
+         src->capacity = src->physical;
+     } else if ((meta = virStorageFileGetMetadataFromBuf(src->path, buf,
+-                                                        len, format, NULL))) {
++                                                        len, format))) {
+         src->capacity = meta->capacity ? meta->capacity : src->physical;
+         if (src->encryption && meta->encryption)
+             src->encryption->payload_offset = meta->encryption->payload_offset;
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index ecba418bb3..32f2c82147 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -386,8 +386,7 @@ virStorageSourcePtr virStorageFileGetMetadataFromFD(const char *path,
+ virStorageSourcePtr virStorageFileGetMetadataFromBuf(const char *path,
+                                                      char *buf,
+                                                      size_t len,
+-                                                     int format,
+-                                                     int *backingFormat)
++                                                     int format)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+ int virStorageFileChainGetBroken(virStorageSourcePtr chain,
+                                  char **broken_file);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataFromFD-Remove-unused-backingFormat-argument.patch b/SOURCES/libvirt-virStorageFileGetMetadataFromFD-Remove-unused-backingFormat-argument.patch
new file mode 100644
index 0000000..a54d876
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataFromFD-Remove-unused-backingFormat-argument.patch
@@ -0,0 +1,91 @@
+From c813373a8e6ab6efcd90fd65e7ea15431733280f Mon Sep 17 00:00:00 2001
+Message-Id: <c813373a8e6ab6efcd90fd65e7ea15431733280f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:41 +0100
+Subject: [PATCH] virStorageFileGetMetadataFromFD: Remove unused
+ 'backingFormat' argument
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit c95656c995e9af260c6dfab69c6da0da8a3ae50c)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <7e26b363b7628de0f22e2fa45b2d1ce79a81d59e.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/storage/storage_util.c |  3 +--
+ src/util/virstoragefile.c  | 12 +-----------
+ src/util/virstoragefile.h  |  3 +--
+ 3 files changed, 3 insertions(+), 15 deletions(-)
+
+diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
+index f3e899d0ca..0e80983f1f 100644
+--- a/src/storage/storage_util.c
++++ b/src/storage/storage_util.c
+@@ -3345,8 +3345,7 @@ storageBackendProbeTarget(virStorageSourcePtr target,
+ 
+     if (!(meta = virStorageFileGetMetadataFromFD(target->path,
+                                                  fd,
+-                                                 VIR_STORAGE_FILE_AUTO,
+-                                                 NULL)))
++                                                 VIR_STORAGE_FILE_AUTO)))
+         return -1;
+ 
+     if (meta->backingStoreRaw) {
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 1b9bd12284..0bfd9e16e9 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -1161,21 +1161,14 @@ virStorageFileGetMetadataFromBuf(const char *path,
+ virStorageSourcePtr
+ virStorageFileGetMetadataFromFD(const char *path,
+                                 int fd,
+-                                int format,
+-                                int *backingFormat)
++                                int format)
+ 
+ {
+     ssize_t len = VIR_STORAGE_MAX_HEADER;
+     struct stat sb;
+-    int dummy;
+     g_autofree char *buf = NULL;
+     g_autoptr(virStorageSource) meta = NULL;
+ 
+-    if (!backingFormat)
+-        backingFormat = &dummy;
+-
+-    *backingFormat = VIR_STORAGE_FILE_NONE;
+-
+     if (fstat(fd, &sb) < 0) {
+         virReportSystemError(errno,
+                              _("cannot stat file '%s'"), path);
+@@ -1206,9 +1199,6 @@ virStorageFileGetMetadataFromFD(const char *path,
+     if (virStorageFileGetMetadataInternal(meta, buf, len) < 0)
+         return NULL;
+ 
+-    if (backingFormat)
+-        *backingFormat = meta->backingStoreRawFormat;
+-
+     if (S_ISREG(sb.st_mode))
+         meta->type = VIR_STORAGE_TYPE_FILE;
+     else if (S_ISBLK(sb.st_mode))
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 32f2c82147..5b995d54ab 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -381,8 +381,7 @@ int virStorageFileProbeFormat(const char *path, uid_t uid, gid_t gid);
+ 
+ virStorageSourcePtr virStorageFileGetMetadataFromFD(const char *path,
+                                                     int fd,
+-                                                    int format,
+-                                                    int *backingFormat);
++                                                    int format);
+ virStorageSourcePtr virStorageFileGetMetadataFromBuf(const char *path,
+                                                      char *buf,
+                                                      size_t len,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Allow-format-probing-under-special-circumstances.patch b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Allow-format-probing-under-special-circumstances.patch
new file mode 100644
index 0000000..94131af
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Allow-format-probing-under-special-circumstances.patch
@@ -0,0 +1,148 @@
+From 1e3921f1065972dc236bc726f19be37492a145c6 Mon Sep 17 00:00:00 2001
+Message-Id: <1e3921f1065972dc236bc726f19be37492a145c6@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:43 +0100
+Subject: [PATCH] virStorageFileGetMetadataRecurse: Allow format probing under
+ special circumstances
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allow format probing to work around lazy clients which did not specify
+their format in the overlay. Format probing will be allowed only, if we
+are able to probe the image, the probing result was successful and the
+probed image does not have any backing or data file.
+
+This relaxes the restrictions which were imposed in commit 3615e8b39bad
+in cases when we know that the image probing will not result in security
+issues or data corruption.
+
+We perform the image format detection and in the case that we were able
+to probe the format and the format does not specify a backing store (or
+doesn't support backing store) we can use this format.
+
+With pre-blockdev configurations this will restore the previous
+behaviour for the images mentioned above as qemu would probe the format
+anyways. It also improves error reporting compared to the old state as
+we now report that the backing chain will be broken in case when there
+is a backing file.
+
+In blockdev configurations this ensures that libvirt will not cause data
+corruption by ending the chain prematurely without notifying the user,
+but still allows the old semantics when the users forgot to specify the
+format.
+
+Users thus don't have to re-invent when image format detection is safe
+to do.
+
+The price for this is that libvirt will need to keep the image format
+detector still current and working or replace it by invocation of
+qemu-img.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit ae9e6c2a2b75d958995c661f7bb64ed4353a6404)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <77d1d21a0ce64fd49c501b1ed3667307cbab0b73.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 52 ++++++++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 22 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 0bfd9e16e9..b88763b267 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -4986,6 +4986,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+                                  virHashTablePtr cycle,
+                                  unsigned int depth)
+ {
++    virStorageFileFormat orig_format = src->format;
+     size_t headerLen;
+     int rv;
+     g_autofree char *buf = NULL;
+@@ -4995,10 +4996,17 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+               NULLSTR(src->path), src->format,
+               (unsigned int)uid, (unsigned int)gid);
+ 
++    if (src->format == VIR_STORAGE_FILE_AUTO_SAFE)
++        src->format = VIR_STORAGE_FILE_AUTO;
++
+     /* exit if we can't load information about the current image */
+     rv = virStorageFileSupportsBackingChainTraversal(src);
+-    if (rv <= 0)
++    if (rv <= 0) {
++        if (orig_format == VIR_STORAGE_FILE_AUTO)
++            return -2;
++
+         return rv;
++    }
+ 
+     if (virStorageFileGetMetadataRecurseReadHeader(src, parent, uid, gid,
+                                                    &buf, &headerLen, cycle) < 0)
+@@ -5007,6 +5015,18 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     if (virStorageFileGetMetadataInternal(src, buf, headerLen) < 0)
+         return -1;
+ 
++    /* If we probed the format we MUST ensure that nothing else than the current
++     * image (this includes both backing files and external data store) is
++     * considered for security labelling and/or recursion. */
++    if (orig_format == VIR_STORAGE_FILE_AUTO) {
++        if (src->backingStoreRaw || src->externalDataStoreRaw) {
++            src->format = VIR_STORAGE_FILE_RAW;
++            VIR_FREE(src->backingStoreRaw);
++            VIR_FREE(src->externalDataStoreRaw);
++            return -2;
++        }
++    }
++
+     if (src->backingStoreRaw) {
+         if ((rv = virStorageSourceNewFromBacking(src, &backingStore)) < 0)
+             return -1;
+@@ -5015,33 +5035,21 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+         if (rv == 1)
+             return 0;
+ 
+-        if (backingStore->format == VIR_STORAGE_FILE_AUTO) {
+-            /* Assuming the backing store to be raw can lead to failures. We do
+-             * it only when we must not report an error to prevent losing VMs.
+-             * Otherwise report an error.
+-             */
+-            if (report_broken) {
++        if ((rv = virStorageFileGetMetadataRecurse(backingStore, parent,
++                                                   uid, gid,
++                                                   report_broken,
++                                                   cycle, depth + 1)) < 0) {
++            if (!report_broken)
++                return 0;
++
++            if (rv == -2) {
+                 virReportError(VIR_ERR_OPERATION_INVALID,
+                                _("format of backing image '%s' of image '%s' was not specified in the image metadata "
+                                  "(See https://libvirt.org/kbase/backing_chains.html for troubleshooting)"),
+                                src->backingStoreRaw, NULLSTR(src->path));
+-                return -1;
+             }
+ 
+-            backingStore->format = VIR_STORAGE_FILE_RAW;
+-        }
+-
+-        if (backingStore->format == VIR_STORAGE_FILE_AUTO_SAFE)
+-            backingStore->format = VIR_STORAGE_FILE_AUTO;
+-
+-        if (virStorageFileGetMetadataRecurse(backingStore, parent,
+-                                             uid, gid,
+-                                             report_broken,
+-                                             cycle, depth + 1) < 0) {
+-            if (report_broken)
+-                return -1;
+-            else
+-                return 0;
++            return -1;
+         }
+ 
+         backingStore->id = depth;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Expect-NULL-src-path.patch b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Expect-NULL-src-path.patch
new file mode 100644
index 0000000..7d0facd
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Expect-NULL-src-path.patch
@@ -0,0 +1,48 @@
+From b501151fe2fb1f3b3e8d9617fb1b5a160832f480 Mon Sep 17 00:00:00 2001
+Message-Id: <b501151fe2fb1f3b3e8d9617fb1b5a160832f480@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:31 +0100
+Subject: [PATCH] virStorageFileGetMetadataRecurse: Expect NULL src->path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The path can be NULL e.g. for NBD disks. Use NULLSTR to prevent use of
+NULL in %s.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 157b8722cbcc57103d3dd9211aa94a2c592849b6)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <6f8aa7a68bbde2e405c83c53ee78e746d3efbf39.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 911f811ace..28d1d1aa1e 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -4973,7 +4973,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     g_autoptr(virStorageSource) backingStore = NULL;
+ 
+     VIR_DEBUG("path=%s format=%d uid=%u gid=%u",
+-              src->path, src->format,
++              NULLSTR(src->path), src->format,
+               (unsigned int)uid, (unsigned int)gid);
+ 
+     /* exit if we can't load information about the current image */
+@@ -4995,7 +4995,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     if (virHashLookup(cycle, uniqueName)) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("backing store for %s (%s) is self-referential"),
+-                       src->path, uniqueName);
++                       NULLSTR(src->path), uniqueName);
+         goto cleanup;
+     }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Extract-storage-access.patch b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Extract-storage-access.patch
new file mode 100644
index 0000000..8137719
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Extract-storage-access.patch
@@ -0,0 +1,128 @@
+From 811785bdc008e9d0df7e6f3e723c5f67b40cf6de Mon Sep 17 00:00:00 2001
+Message-Id: <811785bdc008e9d0df7e6f3e723c5f67b40cf6de@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:33 +0100
+Subject: [PATCH] virStorageFileGetMetadataRecurse: Extract storage access
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Extract the code that directly deals with storage. This allows further
+simplification and clarification of virStorageFileGetMetadataRecurse.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 01adad0932a583b1e2183dd4401bddd8607e77c3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <716c58c00cec06dd469b079df124bc896665f169.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 71 ++++++++++++++++++++++++++-------------
+ 1 file changed, 47 insertions(+), 24 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 46d55eda96..7295cebd08 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -4955,31 +4955,18 @@ virStorageFileReportBrokenChain(int errcode,
+ }
+ 
+ 
+-/* Recursive workhorse for virStorageFileGetMetadata.  */
+ static int
+-virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+-                                 virStorageSourcePtr parent,
+-                                 uid_t uid, gid_t gid,
+-                                 bool report_broken,
+-                                 virHashTablePtr cycle,
+-                                 unsigned int depth)
++virStorageFileGetMetadataRecurseReadHeader(virStorageSourcePtr src,
++                                           virStorageSourcePtr parent,
++                                           uid_t uid,
++                                           gid_t gid,
++                                           char **buf,
++                                           size_t *headerLen,
++                                           virHashTablePtr cycle)
+ {
+     int ret = -1;
+     const char *uniqueName;
+-    ssize_t headerLen;
+-    int backingFormat;
+-    int rv;
+-    g_autofree char *buf = NULL;
+-    g_autoptr(virStorageSource) backingStore = NULL;
+-
+-    VIR_DEBUG("path=%s format=%d uid=%u gid=%u",
+-              NULLSTR(src->path), src->format,
+-              (unsigned int)uid, (unsigned int)gid);
+-
+-    /* exit if we can't load information about the current image */
+-    rv = virStorageFileSupportsBackingChainTraversal(src);
+-    if (rv <= 0)
+-        return rv;
++    ssize_t len;
+ 
+     if (virStorageFileInitAs(src, uid, gid) < 0)
+         return -1;
+@@ -5002,10 +4989,47 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     if (virHashAddEntry(cycle, uniqueName, NULL) < 0)
+         goto cleanup;
+ 
+-    if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
+-                                        &buf)) < 0)
++    if ((len = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, buf)) < 0)
+         goto cleanup;
+ 
++    *headerLen = len;
++    ret = 0;
++
++ cleanup:
++    virStorageFileDeinit(src);
++    return ret;
++}
++
++
++/* Recursive workhorse for virStorageFileGetMetadata.  */
++static int
++virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
++                                 virStorageSourcePtr parent,
++                                 uid_t uid, gid_t gid,
++                                 bool report_broken,
++                                 virHashTablePtr cycle,
++                                 unsigned int depth)
++{
++    int ret = -1;
++    size_t headerLen;
++    int backingFormat;
++    int rv;
++    g_autofree char *buf = NULL;
++    g_autoptr(virStorageSource) backingStore = NULL;
++
++    VIR_DEBUG("path=%s format=%d uid=%u gid=%u",
++              NULLSTR(src->path), src->format,
++              (unsigned int)uid, (unsigned int)gid);
++
++    /* exit if we can't load information about the current image */
++    rv = virStorageFileSupportsBackingChainTraversal(src);
++    if (rv <= 0)
++        return rv;
++
++    if (virStorageFileGetMetadataRecurseReadHeader(src, parent, uid, gid,
++                                                   &buf, &headerLen, cycle) < 0)
++        return -1;
++
+     if (virStorageFileGetMetadataInternal(src, buf, headerLen,
+                                           &backingFormat) < 0)
+         goto cleanup;
+@@ -5081,7 +5105,6 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     ret = 0;
+ 
+  cleanup:
+-    virStorageFileDeinit(src);
+     return ret;
+ }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Remove-cleanup-label.patch b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Remove-cleanup-label.patch
new file mode 100644
index 0000000..69739f3
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Remove-cleanup-label.patch
@@ -0,0 +1,124 @@
+From 0b9e19e4d91694f3f55318409b120d132d1db987 Mon Sep 17 00:00:00 2001
+Message-Id: <0b9e19e4d91694f3f55318409b120d132d1db987@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:34 +0100
+Subject: [PATCH] virStorageFileGetMetadataRecurse: Remove 'cleanup' label
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There's nothing to clean up. Make it obvious what is returned.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit a570dc67675618e3946bef7e49c685f56bb258e3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <1aed0cf359219aa713ded5159d3f04b080e3042c.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 50 +++++++++++++++------------------------
+ 1 file changed, 19 insertions(+), 31 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 7295cebd08..5a74034ec4 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -5010,7 +5010,6 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+                                  virHashTablePtr cycle,
+                                  unsigned int depth)
+ {
+-    int ret = -1;
+     size_t headerLen;
+     int backingFormat;
+     int rv;
+@@ -5030,19 +5029,16 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+                                                    &buf, &headerLen, cycle) < 0)
+         return -1;
+ 
+-    if (virStorageFileGetMetadataInternal(src, buf, headerLen,
+-                                          &backingFormat) < 0)
+-        goto cleanup;
++    if (virStorageFileGetMetadataInternal(src, buf, headerLen, &backingFormat) < 0)
++        return -1;
+ 
+     if (src->backingStoreRaw) {
+         if ((rv = virStorageSourceNewFromBacking(src, &backingStore)) < 0)
+-            goto cleanup;
++            return -1;
+ 
+-        if (rv == 1) {
+-            /* the backing file would not be usable for VM usage */
+-            ret = 0;
+-            goto cleanup;
+-        }
++        /* the backing file would not be usable for VM usage */
++        if (rv == 1)
++            return 0;
+ 
+         backingStore->format = backingFormat;
+ 
+@@ -5065,17 +5061,14 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+         if (backingStore->format == VIR_STORAGE_FILE_AUTO_SAFE)
+             backingStore->format = VIR_STORAGE_FILE_AUTO;
+ 
+-        if ((ret = virStorageFileGetMetadataRecurse(backingStore, parent,
+-                                                    uid, gid,
+-                                                    report_broken,
+-                                                    cycle, depth + 1)) < 0) {
++        if (virStorageFileGetMetadataRecurse(backingStore, parent,
++                                             uid, gid,
++                                             report_broken,
++                                             cycle, depth + 1) < 0) {
+             if (report_broken)
+-                goto cleanup;
+-
+-            /* if we fail somewhere midway, just accept and return a
+-             * broken chain */
+-            ret = 0;
+-            goto cleanup;
++                return -1;
++            else
++                return 0;
+         }
+ 
+         backingStore->id = depth;
+@@ -5083,7 +5076,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     } else {
+         /* add terminator */
+         if (!(src->backingStore = virStorageSourceNew()))
+-            goto cleanup;
++            return -1;
+     }
+ 
+     if (src->externalDataStoreRaw) {
+@@ -5091,21 +5084,16 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+ 
+         if ((rv = virStorageSourceNewFromExternalData(src,
+                                                       &externalDataStore)) < 0)
+-            goto cleanup;
++            return -1;
+ 
+-        if (rv == 1) {
+-            /* the file would not be usable for VM usage */
+-            ret = 0;
+-            goto cleanup;
+-        }
++        /* the file would not be usable for VM usage */
++        if (rv == 1)
++            return 0;
+ 
+         src->externalDataStore = g_steal_pointer(&externalDataStore);
+     }
+ 
+-    ret = 0;
+-
+- cleanup:
+-    return ret;
++    return 0;
+ }
+ 
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Remove-impossible-error-report.patch b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Remove-impossible-error-report.patch
new file mode 100644
index 0000000..26c07e9
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Remove-impossible-error-report.patch
@@ -0,0 +1,49 @@
+From cf65fbfb12a209e760b8b2f2b16acfd8b33e8bee Mon Sep 17 00:00:00 2001
+Message-Id: <cf65fbfb12a209e760b8b2f2b16acfd8b33e8bee@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:29 +0100
+Subject: [PATCH] virStorageFileGetMetadataRecurse: Remove impossible error
+ report
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We call virStorageFileSupportsBackingChainTraversal which already checks
+that the 'storageFileRead' callback is non-NULL, which in turn means
+that virStorageFileRead will not return -2.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 84df98f29e031d3b1e68e7e3c0d2651ccba14106)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <bb902dffc6692251cf12a14fcf5b25a62054a20b.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 6b83fc0e24..1f18320756 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -5003,15 +5003,8 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+         goto cleanup;
+ 
+     if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
+-                                        &buf)) < 0) {
+-        if (headerLen == -2)
+-            virReportError(VIR_ERR_INTERNAL_ERROR,
+-                           _("storage file reading is not supported for "
+-                             "storage type %s (protocol: %s)"),
+-                           virStorageTypeToString(src->type),
+-                           virStorageNetProtocolTypeToString(src->protocol));
++                                        &buf)) < 0)
+         goto cleanup;
+-    }
+ 
+     if (virStorageFileGetMetadataInternal(src, buf, headerLen,
+                                           &backingFormat) < 0)
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Shuffle-around-assignment-of-backing-chain-depth.patch b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Shuffle-around-assignment-of-backing-chain-depth.patch
new file mode 100644
index 0000000..5a62f0e
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Shuffle-around-assignment-of-backing-chain-depth.patch
@@ -0,0 +1,59 @@
+From e0c86b78dc5587263aeb10ae0fc8fbb5975135ee Mon Sep 17 00:00:00 2001
+Message-Id: <e0c86b78dc5587263aeb10ae0fc8fbb5975135ee@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:30 +0100
+Subject: [PATCH] virStorageFileGetMetadataRecurse: Shuffle around assignment
+ of backing chain depth
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move the assignment to a place where we know that the backing store is
+present rather than having to check in the cleanup section.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit b347e5c7dd69e3381b073c640ece2460632830cc)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <0432e2bd0f224cd1c55104e33699cb1602013a5d.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 1f18320756..911f811ace 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -5053,14 +5053,15 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+             ret = 0;
+             goto cleanup;
+         }
++
++        backingStore->id = depth;
++        src->backingStore = g_steal_pointer(&backingStore);
+     } else {
+         /* add terminator */
+-        if (!(backingStore = virStorageSourceNew()))
++        if (!(src->backingStore = virStorageSourceNew()))
+             goto cleanup;
+     }
+ 
+-    src->backingStore = g_steal_pointer(&backingStore);
+-
+     if (src->externalDataStoreRaw) {
+         g_autoptr(virStorageSource) externalDataStore = NULL;
+ 
+@@ -5080,8 +5081,6 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     ret = 0;
+ 
+  cleanup:
+-    if (virStorageSourceHasBacking(src))
+-        src->backingStore->id = depth;
+     virStorageFileDeinit(src);
+     return ret;
+ }
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Use-virHashHasEntry-instead-of-fake-pointers.patch b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Use-virHashHasEntry-instead-of-fake-pointers.patch
new file mode 100644
index 0000000..c7d655f
--- /dev/null
+++ b/SOURCES/libvirt-virStorageFileGetMetadataRecurse-Use-virHashHasEntry-instead-of-fake-pointers.patch
@@ -0,0 +1,49 @@
+From 20f764d1837f06b10c7c327b085234b6e5f876e2 Mon Sep 17 00:00:00 2001
+Message-Id: <20f764d1837f06b10c7c327b085234b6e5f876e2@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:32 +0100
+Subject: [PATCH] virStorageFileGetMetadataRecurse: Use virHashHasEntry instead
+ of fake pointers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Replacing virHashLookup by virHashHasEntry allows us to use NULL as the
+payload of the hash table rather than putting a fake '1' pointer into
+the table.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit e3960f4b6d0b6d8cb8b2631f8358abf289c1cc18)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <af53b5ff04169cfa8e40664f2b66f110560486ee.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 28d1d1aa1e..46d55eda96 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -4992,14 +4992,14 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+     if (!(uniqueName = virStorageFileGetUniqueIdentifier(src)))
+         goto cleanup;
+ 
+-    if (virHashLookup(cycle, uniqueName)) {
++    if (virHashHasEntry(cycle, uniqueName)) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("backing store for %s (%s) is self-referential"),
+                        NULLSTR(src->path), uniqueName);
+         goto cleanup;
+     }
+ 
+-    if (virHashAddEntry(cycle, uniqueName, (void *)1) < 0)
++    if (virHashAddEntry(cycle, uniqueName, NULL) < 0)
+         goto cleanup;
+ 
+     if ((headerLen = virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER,
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageSourceJSONDriverParser-annotate-format-drivers.patch b/SOURCES/libvirt-virStorageSourceJSONDriverParser-annotate-format-drivers.patch
new file mode 100644
index 0000000..916802b
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceJSONDriverParser-annotate-format-drivers.patch
@@ -0,0 +1,79 @@
+From e551ad605fd99e92a85acdab53bc52efaa6facb2 Mon Sep 17 00:00:00 2001
+Message-Id: <e551ad605fd99e92a85acdab53bc52efaa6facb2@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:08 +0100
+Subject: [PATCH] virStorageSourceJSONDriverParser: annotate 'format' drivers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The parser was originally designed only for protocol parsers. Since
+we already have 'raw' format driver in the list we'll need to be able
+to parse it too. In later patches this will be used to prevent parsing
+nested format drivers.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 7e13ff8dc016dda5ffd50ff5c059f01c76486c82)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <ef05c98383c79aa7487ea97c7e1cbfb384c80440.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index c97a3a9d6e..b6749b150c 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3563,6 +3563,7 @@ virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src,
+ 
+ struct virStorageSourceJSONDriverParser {
+     const char *drvname;
++    bool formatdriver;
+     /**
+      * The callback gets a pre-allocated storage source @src and the JSON
+      * object to parse. The callback shall return -1 on error and report error
+@@ -3575,22 +3576,22 @@ struct virStorageSourceJSONDriverParser {
+ };
+ 
+ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
+-    {"file", virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE_FILE},
+-    {"host_device", virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE_BLOCK},
+-    {"host_cdrom", virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE_BLOCK},
+-    {"http", virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_HTTP},
+-    {"https", virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_HTTPS},
+-    {"ftp", virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_FTP},
+-    {"ftps", virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_FTPS},
+-    {"tftp", virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_TFTP},
+-    {"gluster", virStorageSourceParseBackingJSONGluster, 0},
+-    {"iscsi", virStorageSourceParseBackingJSONiSCSI, 0},
+-    {"nbd", virStorageSourceParseBackingJSONNbd, 0},
+-    {"sheepdog", virStorageSourceParseBackingJSONSheepdog, 0},
+-    {"ssh", virStorageSourceParseBackingJSONSSH, 0},
+-    {"rbd", virStorageSourceParseBackingJSONRBD, 0},
+-    {"raw", virStorageSourceParseBackingJSONRaw, 0},
+-    {"vxhs", virStorageSourceParseBackingJSONVxHS, 0},
++    {"file", false, virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE_FILE},
++    {"host_device", false, virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE_BLOCK},
++    {"host_cdrom", false, virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE_BLOCK},
++    {"http", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_HTTP},
++    {"https", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_HTTPS},
++    {"ftp", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_FTP},
++    {"ftps", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_FTPS},
++    {"tftp", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_TFTP},
++    {"gluster", false, virStorageSourceParseBackingJSONGluster, 0},
++    {"iscsi", false, virStorageSourceParseBackingJSONiSCSI, 0},
++    {"nbd", false, virStorageSourceParseBackingJSONNbd, 0},
++    {"sheepdog", false, virStorageSourceParseBackingJSONSheepdog, 0},
++    {"ssh", false, virStorageSourceParseBackingJSONSSH, 0},
++    {"rbd", false, virStorageSourceParseBackingJSONRBD, 0},
++    {"raw", true, virStorageSourceParseBackingJSONRaw, 0},
++    {"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0},
+ };
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virStorageSourceNetCookieValidate-Accept-quoted-cookie-value.patch b/SOURCES/libvirt-virStorageSourceNetCookieValidate-Accept-quoted-cookie-value.patch
new file mode 100644
index 0000000..cf83fa6
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceNetCookieValidate-Accept-quoted-cookie-value.patch
@@ -0,0 +1,148 @@
+From ba88fc4f04428c1064bc4eee85acbdf1a3123c4c Mon Sep 17 00:00:00 2001
+Message-Id: <ba88fc4f04428c1064bc4eee85acbdf1a3123c4c@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:40 +0200
+Subject: [PATCH] virStorageSourceNetCookieValidate: Accept quoted cookie value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The quotes are forbidden only inside the value, but the value itself may
+be enclosed in quotes. Fix the RNG schema and validator and add a test
+case.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit b9166baebe70a4b3577ddb6b2ee6af0dd4f60759)
+Message-Id: <f8f910f4e61e0e9434591a02c5d2e50b3d78edc5.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ docs/schemas/domaincommon.rng                 |  2 +-
+ src/util/virstoragefile.c                     | 19 ++++++++++++++++++-
+ .../disk-network-http.x86_64-latest.args      |  4 ++--
+ tests/qemuxml2argvdata/disk-network-http.xml  |  4 ++--
+ .../disk-network-http.x86_64-latest.xml       |  4 ++--
+ 5 files changed, 25 insertions(+), 8 deletions(-)
+
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 3a0edbed97..ac6f180382 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -1846,7 +1846,7 @@
+             </data>
+           </attribute>
+           <data type="string">
+-            <param name="pattern">[!#$%&amp;'()*+\-./0-9:&gt;=&lt;?@A-Z\^_`\[\]a-z|~]+</param>
++            <param name="pattern">"?[!#$%&amp;'()*+\-./0-9:&gt;=&lt;?@A-Z\^_`\[\]a-z|~]+"?</param>
+           </data>
+         </element>
+       </oneOrMore>
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 3eb32edc2a..f8d741f040 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2217,6 +2217,10 @@ static const char virStorageSourceCookieNameInvalidChars[] =
+ static int
+ virStorageSourceNetCookieValidate(virStorageNetCookieDefPtr def)
+ {
++    g_autofree char *val = g_strdup(def->value);
++    const char *checkval = val;
++    size_t len = strlen(val);
++
+     /* name must have at least 1 character */
+     if (*(def->name) == '\0') {
+         virReportError(VIR_ERR_XML_ERROR, "%s",
+@@ -2233,8 +2237,21 @@ virStorageSourceNetCookieValidate(virStorageNetCookieDefPtr def)
+         return -1;
+     }
+ 
++    /* check for optional quotes around the cookie value string */
++    if (val[0] == '"') {
++        if (val[len - 1] != '"') {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("value of cookie '%s' contains invalid characters"),
++                           def->name);
++            return -1;
++        }
++
++        val[len - 1] = '\0';
++        checkval++;
++    }
++
+     /* check invalid characters in value */
+-    if (virStringHasChars(def->value, virStorageSourceCookieValueInvalidChars)) {
++    if (virStringHasChars(checkval, virStorageSourceCookieValueInvalidChars)) {
+         virReportError(VIR_ERR_XML_ERROR,
+                        _("value of cookie '%s' contains invalid characters"),
+                        def->name);
+diff --git a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+index 2f2849ebdf..46aa5f23ce 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
++++ b/tests/qemuxml2argvdata/disk-network-http.x86_64-latest.args
+@@ -42,7 +42,7 @@ id=virtio-disk0,bootindex=1 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=libvirt-3-format,\
+ id=virtio-disk1 \
+ -object secret,id=libvirt-2-storage-httpcookie-secret0,\
+-data=DrPR9NA6GKJb7qi1KbjHad3f3UIGTTDmAmOZHHv1F5w5T8rhnk3f+uSKStHe0J2O,\
++data=DrPR9NA6GKJb7qi1KbjHaealKEMVtOWUl2h3yvO5lgIh6cyLHemmlg+h9fcgwREA,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"http","url":"http://example.org:1234/test3.img",\
+ "cookie-secret":"libvirt-2-storage-httpcookie-secret0",\
+@@ -52,7 +52,7 @@ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=libvirt-2-format,\
+ id=virtio-disk2 \
+ -object secret,id=libvirt-1-storage-httpcookie-secret0,\
+-data=DrPR9NA6GKJb7qi1KbjHad3f3UIGTTDmAmOZHHv1F5w5T8rhnk3f+uSKStHe0J2O,\
++data=DrPR9NA6GKJb7qi1KbjHaealKEMVtOWUl2h3yvO5lgIh6cyLHemmlg+h9fcgwREA,\
+ keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
+ -blockdev '{"driver":"https","url":"https://example.org:1234/test4.img",\
+ "sslverify":false,"cookie-secret":"libvirt-1-storage-httpcookie-secret0",\
+diff --git a/tests/qemuxml2argvdata/disk-network-http.xml b/tests/qemuxml2argvdata/disk-network-http.xml
+index 20024c732e..93e6617433 100644
+--- a/tests/qemuxml2argvdata/disk-network-http.xml
++++ b/tests/qemuxml2argvdata/disk-network-http.xml
+@@ -35,7 +35,7 @@
+         <host name='example.org' port='1234'/>
+         <cookies>
+           <cookie name='test'>testcookievalue</cookie>
+-          <cookie name='test2'>blurb</cookie>
++          <cookie name='test2'>"blurb"</cookie>
+         </cookies>
+       </source>
+       <target dev='vdc' bus='virtio'/>
+@@ -47,7 +47,7 @@
+         <ssl verify='no'/>
+         <cookies>
+           <cookie name='test'>testcookievalue</cookie>
+-          <cookie name='test2'>blurb</cookie>
++          <cookie name='test2'>&quot;blurb&quot;</cookie>
+         </cookies>
+       </source>
+       <target dev='vdd' bus='virtio'/>
+diff --git a/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
+index 238a5fef58..60073c227c 100644
+--- a/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
++++ b/tests/qemuxml2xmloutdata/disk-network-http.x86_64-latest.xml
+@@ -38,7 +38,7 @@
+         <host name='example.org' port='1234'/>
+         <cookies>
+           <cookie name='test'>testcookievalue</cookie>
+-          <cookie name='test2'>blurb</cookie>
++          <cookie name='test2'>&quot;blurb&quot;</cookie>
+         </cookies>
+       </source>
+       <target dev='vdc' bus='virtio'/>
+@@ -51,7 +51,7 @@
+         <ssl verify='no'/>
+         <cookies>
+           <cookie name='test'>testcookievalue</cookie>
+-          <cookie name='test2'>blurb</cookie>
++          <cookie name='test2'>&quot;blurb&quot;</cookie>
+         </cookies>
+       </source>
+       <target dev='vdd' bus='virtio'/>
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-virStorageSourceNewFromBacking-Also-transfer-the-format.patch b/SOURCES/libvirt-virStorageSourceNewFromBacking-Also-transfer-the-format.patch
new file mode 100644
index 0000000..7d975ae
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceNewFromBacking-Also-transfer-the-format.patch
@@ -0,0 +1,81 @@
+From 19778995ed94278db561db198a402d232027aeb8 Mon Sep 17 00:00:00 2001
+Message-Id: <19778995ed94278db561db198a402d232027aeb8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:38 +0100
+Subject: [PATCH] virStorageSourceNewFromBacking: Also transfer the format
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When we create the new virStorageSource from the definitions stored in
+the parent we should also use the 'backingStoreRawFormat' field to
+populate the format.
+
+Callers which use virStorageSourceNewFromBacking are also fixed to stop
+setting the format manually.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 264b79c63a518df8ce32a78dda51ae554cd2d5f2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <c9015f51f31c9a088983562298aaf61b1c43d927.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/storage/storage_util.c | 5 +----
+ src/util/virstoragefile.c  | 3 +--
+ 2 files changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
+index c562cf313f..f3e899d0ca 100644
+--- a/src/storage/storage_util.c
++++ b/src/storage/storage_util.c
+@@ -3316,7 +3316,6 @@ static int
+ storageBackendProbeTarget(virStorageSourcePtr target,
+                           virStorageEncryptionPtr *encryption)
+ {
+-    int backingStoreFormat;
+     int rc;
+     struct stat sb;
+     g_autoptr(virStorageSource) meta = NULL;
+@@ -3347,15 +3346,13 @@ storageBackendProbeTarget(virStorageSourcePtr target,
+     if (!(meta = virStorageFileGetMetadataFromFD(target->path,
+                                                  fd,
+                                                  VIR_STORAGE_FILE_AUTO,
+-                                                 &backingStoreFormat)))
++                                                 NULL)))
+         return -1;
+ 
+     if (meta->backingStoreRaw) {
+         if (virStorageSourceNewFromBacking(meta, &target->backingStore) < 0)
+             return -1;
+ 
+-        target->backingStore->format = backingStoreFormat;
+-
+         /* XXX: Remote storage doesn't play nicely with volumes backed by
+          * remote storage. To avoid trouble, just fake the backing store is RAW
+          * and put the string from the metadata as the path of the target. */
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index d594ee3695..d80780e291 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3824,6 +3824,7 @@ virStorageSourceNewFromBacking(virStorageSourcePtr parent,
+                                            backing)) < 0)
+         return rc;
+ 
++    (*backing)->format = parent->backingStoreRawFormat;
+     (*backing)->readonly = true;
+     return rc;
+ }
+@@ -5028,8 +5029,6 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
+         if (rv == 1)
+             return 0;
+ 
+-        backingStore->format = src->backingStoreRawFormat;
+-
+         if (backingStore->format == VIR_STORAGE_FILE_AUTO) {
+             /* Assuming the backing store to be raw can lead to failures. We do
+              * it only when we must not report an error to prevent losing VMs.
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageSourceParseBackingJSON-Allow-json-pseudo-URIs-without-file-wrapper.patch b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Allow-json-pseudo-URIs-without-file-wrapper.patch
new file mode 100644
index 0000000..4932b4c
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Allow-json-pseudo-URIs-without-file-wrapper.patch
@@ -0,0 +1,115 @@
+From 3a01f1148ea3da0a572a196f987f29f12e397ec1 Mon Sep 17 00:00:00 2001
+Message-Id: <3a01f1148ea3da0a572a196f987f29f12e397ec1@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:09 +0100
+Subject: [PATCH] virStorageSourceParseBackingJSON: Allow 'json:' pseudo URIs
+ without 'file' wrapper
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are two possibilities:
+1) json:{"file":{"driver":...}}
+2) json:{"driver":...}
+
+Our code didn't work properly with the second one as it was expecting
+the 'file' wrapper. Conditionalize the removal to only the situation
+when the top level doesn't have "driver".
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit f8e097570ea9eb0b446f9ff5159b4e9c337e6b07)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <26a21da3bf0642ed6ac80184f97337fba98b0c14.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 41 +++++++++++++++++++++++++--------------
+ 1 file changed, 26 insertions(+), 15 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index b6749b150c..dd05de188f 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3521,10 +3521,17 @@ virStorageSourceParseBackingJSONRaw(virStorageSourcePtr src,
+                                     const char *jsonstr,
+                                     int opaque G_GNUC_UNUSED)
+ {
+-    /* There are no interesting attributes in raw driver.
+-     * Treat it as pass-through.
+-     */
+-    return virStorageSourceParseBackingJSONInternal(src, json, jsonstr);
++    virJSONValuePtr file;
++
++    /* 'raw' is a format driver so it can have protocol driver children */
++    if (!(file = virJSONValueObjectGetObject(json, "file"))) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("JSON backing volume definition '%s' lacks 'file' object"),
++                       jsonstr);
++        return -1;
++    }
++
++    return virStorageSourceParseBackingJSONInternal(src, file, jsonstr);
+ }
+ 
+ 
+@@ -3601,18 +3608,10 @@ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+                                          virJSONValuePtr json,
+                                          const char *jsonstr)
+ {
+-    virJSONValuePtr file;
+     const char *drvname;
+     size_t i;
+ 
+-    if (!(file = virJSONValueObjectGetObject(json, "file"))) {
+-        virReportError(VIR_ERR_INVALID_ARG,
+-                       _("JSON backing volume definition '%s' lacks 'file' object"),
+-                       jsonstr);
+-        return -1;
+-    }
+-
+-    if (!(drvname = virJSONValueObjectGetString(file, "driver"))) {
++    if (!(drvname = virJSONValueObjectGetString(json, "driver"))) {
+         virReportError(VIR_ERR_INVALID_ARG,
+                        _("JSON backing volume definition '%s' lacks driver name"),
+                        jsonstr);
+@@ -3621,7 +3620,7 @@ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+ 
+     for (i = 0; i < G_N_ELEMENTS(jsonParsers); i++) {
+         if (STREQ(drvname, jsonParsers[i].drvname))
+-            return jsonParsers[i].func(src, file, jsonstr, jsonParsers[i].opaque);
++            return jsonParsers[i].func(src, json, jsonstr, jsonParsers[i].opaque);
+     }
+ 
+     virReportError(VIR_ERR_INTERNAL_ERROR,
+@@ -3637,6 +3636,7 @@ virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+ {
+     g_autoptr(virJSONValue) root = NULL;
+     g_autoptr(virJSONValue) deflattened = NULL;
++    virJSONValuePtr file = NULL;
+ 
+     if (!(root = virJSONValueFromString(json)))
+         return -1;
+@@ -3644,7 +3644,18 @@ virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+     if (!(deflattened = virJSONValueObjectDeflatten(root)))
+         return -1;
+ 
+-    return virStorageSourceParseBackingJSONInternal(src, deflattened, json);
++    /* There are 2 possible syntaxes:
++     * 1) json:{"file":{"driver":...}}
++     * 2) json:{"driver":...}
++     * Remove the 'file' wrapper object in case 1.
++     */
++    if (!virJSONValueObjectHasKey(deflattened, "driver"))
++        file = virJSONValueObjectGetObject(deflattened, "file");
++
++    if (!file)
++        file = deflattened;
++
++    return virStorageSourceParseBackingJSONInternal(src, file, json);
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virStorageSourceParseBackingJSON-Move-deflattening-of-json-URIs-out-of-recursion.patch b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Move-deflattening-of-json-URIs-out-of-recursion.patch
new file mode 100644
index 0000000..d762fcc
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Move-deflattening-of-json-URIs-out-of-recursion.patch
@@ -0,0 +1,69 @@
+From dd5ec4a68ef2858ff8d98942d87b59fa09ab819f Mon Sep 17 00:00:00 2001
+Message-Id: <dd5ec4a68ef2858ff8d98942d87b59fa09ab819f@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:07 +0100
+Subject: [PATCH] virStorageSourceParseBackingJSON: Move deflattening of json:
+ URIs out of recursion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Originally virStorageSourceParseBackingJSON didn't recurse, but when
+the 'raw' driver support was added we need to parse it's information
+which contains nested 'file' object.
+
+Since the deflattening helper recurses already there's no need to call
+it again. Move it one level up to the entry point.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit aadb34be3428a5e467289709290b536ae6bf5d2a)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <be49eb68dbd29d1075713483472f32d5e995a263.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 05f17224f4..c97a3a9d6e 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3600,15 +3600,11 @@ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+                                          virJSONValuePtr json,
+                                          const char *jsonstr)
+ {
+-    g_autoptr(virJSONValue) deflattened = NULL;
+     virJSONValuePtr file;
+     const char *drvname;
+     size_t i;
+ 
+-    if (!(deflattened = virJSONValueObjectDeflatten(json)))
+-        return -1;
+-
+-    if (!(file = virJSONValueObjectGetObject(deflattened, "file"))) {
++    if (!(file = virJSONValueObjectGetObject(json, "file"))) {
+         virReportError(VIR_ERR_INVALID_ARG,
+                        _("JSON backing volume definition '%s' lacks 'file' object"),
+                        jsonstr);
+@@ -3639,11 +3635,15 @@ virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+                                  const char *json)
+ {
+     g_autoptr(virJSONValue) root = NULL;
++    g_autoptr(virJSONValue) deflattened = NULL;
+ 
+     if (!(root = virJSONValueFromString(json)))
+         return -1;
+ 
+-    return virStorageSourceParseBackingJSONInternal(src, root, json);
++    if (!(deflattened = virJSONValueObjectDeflatten(root)))
++        return -1;
++
++    return virStorageSourceParseBackingJSONInternal(src, deflattened, json);
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virStorageSourceParseBackingJSON-Pass-around-original-backing-file-string.patch b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Pass-around-original-backing-file-string.patch
new file mode 100644
index 0000000..33fa270
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Pass-around-original-backing-file-string.patch
@@ -0,0 +1,186 @@
+From 5322d68b1c1ce4b8db415e691b666e1aae14ce8b Mon Sep 17 00:00:00 2001
+Message-Id: <5322d68b1c1ce4b8db415e691b666e1aae14ce8b@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:06 +0100
+Subject: [PATCH] virStorageSourceParseBackingJSON: Pass around original
+ backing file string
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are a few error messages which might want to report the original
+backing store string. Pass it around rather than trying to re-generate
+it.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 4a6bc568cd485f8f252a4750c5a67735f15ff82d)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <09648d6aeb27261a420b144c53360158b1e367d0.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 7a2af0ad94..05f17224f4 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3051,12 +3051,14 @@ virStorageSourceParseBackingColon(virStorageSourcePtr src,
+ 
+ static int
+ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+-                                         virJSONValuePtr json);
++                                         virJSONValuePtr json,
++                                         const char *jsonstr);
+ 
+ 
+ static int
+ virStorageSourceParseBackingJSONPath(virStorageSourcePtr src,
+                                      virJSONValuePtr json,
++                                     const char *jsonstr G_GNUC_UNUSED,
+                                      int type)
+ {
+     const char *path;
+@@ -3101,6 +3103,7 @@ virStorageSourceParseBackingJSONUriStr(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONUri(virStorageSourcePtr src,
+                                     virJSONValuePtr json,
++                                    const char *jsonstr G_GNUC_UNUSED,
+                                     int protocol)
+ {
+     const char *uri;
+@@ -3204,6 +3207,7 @@ virStorageSourceParseBackingJSONSocketAddress(virStorageNetHostDefPtr host,
+ static int
+ virStorageSourceParseBackingJSONGluster(virStorageSourcePtr src,
+                                         virJSONValuePtr json,
++                                        const char *jsonstr G_GNUC_UNUSED,
+                                         int opaque G_GNUC_UNUSED)
+ {
+     const char *uri = virJSONValueObjectGetString(json, "filename");
+@@ -3257,6 +3261,7 @@ virStorageSourceParseBackingJSONGluster(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src,
+                                       virJSONValuePtr json,
++                                      const char *jsonstr G_GNUC_UNUSED,
+                                       int opaque G_GNUC_UNUSED)
+ {
+     const char *transport = virJSONValueObjectGetString(json, "transport");
+@@ -3326,6 +3331,7 @@ virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONNbd(virStorageSourcePtr src,
+                                     virJSONValuePtr json,
++                                    const char *jsonstr G_GNUC_UNUSED,
+                                     int opaque G_GNUC_UNUSED)
+ {
+     const char *path = virJSONValueObjectGetString(json, "path");
+@@ -3373,6 +3379,7 @@ virStorageSourceParseBackingJSONNbd(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONSheepdog(virStorageSourcePtr src,
+                                          virJSONValuePtr json,
++                                         const char *jsonstr G_GNUC_UNUSED,
+                                          int opaque G_GNUC_UNUSED)
+ {
+     const char *filename;
+@@ -3416,6 +3423,7 @@ virStorageSourceParseBackingJSONSheepdog(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONSSH(virStorageSourcePtr src,
+                                     virJSONValuePtr json,
++                                    const char *jsonstr G_GNUC_UNUSED,
+                                     int opaque G_GNUC_UNUSED)
+ {
+     const char *path = virJSONValueObjectGetString(json, "path");
+@@ -3458,6 +3466,7 @@ virStorageSourceParseBackingJSONSSH(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
+                                     virJSONValuePtr json,
++                                    const char *jsonstr G_GNUC_UNUSED,
+                                     int opaque G_GNUC_UNUSED)
+ {
+     const char *filename;
+@@ -3509,18 +3518,20 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONRaw(virStorageSourcePtr src,
+                                     virJSONValuePtr json,
++                                    const char *jsonstr,
+                                     int opaque G_GNUC_UNUSED)
+ {
+     /* There are no interesting attributes in raw driver.
+      * Treat it as pass-through.
+      */
+-    return virStorageSourceParseBackingJSONInternal(src, json);
++    return virStorageSourceParseBackingJSONInternal(src, json, jsonstr);
+ }
+ 
+ 
+ static int
+ virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src,
+                                      virJSONValuePtr json,
++                                     const char *jsonstr G_GNUC_UNUSED,
+                                      int opaque G_GNUC_UNUSED)
+ {
+     const char *vdisk_id = virJSONValueObjectGetString(json, "vdisk-id");
+@@ -3559,7 +3570,7 @@ struct virStorageSourceJSONDriverParser {
+      * can't be converted to libvirt's configuration (e.g. inline authentication
+      * credentials are present).
+      */
+-    int (*func)(virStorageSourcePtr src, virJSONValuePtr json, int opaque);
++    int (*func)(virStorageSourcePtr src, virJSONValuePtr json, const char *jsonstr, int opaque);
+     int opaque;
+ };
+ 
+@@ -3586,36 +3597,34 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
+ 
+ static int
+ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+-                                         virJSONValuePtr json)
++                                         virJSONValuePtr json,
++                                         const char *jsonstr)
+ {
+     g_autoptr(virJSONValue) deflattened = NULL;
+     virJSONValuePtr file;
+     const char *drvname;
+     size_t i;
+-    g_autofree char *str = NULL;
+ 
+     if (!(deflattened = virJSONValueObjectDeflatten(json)))
+         return -1;
+ 
+     if (!(file = virJSONValueObjectGetObject(deflattened, "file"))) {
+-        str = virJSONValueToString(json, false);
+         virReportError(VIR_ERR_INVALID_ARG,
+                        _("JSON backing volume definition '%s' lacks 'file' object"),
+-                       NULLSTR(str));
++                       jsonstr);
+         return -1;
+     }
+ 
+     if (!(drvname = virJSONValueObjectGetString(file, "driver"))) {
+-        str = virJSONValueToString(json, false);
+         virReportError(VIR_ERR_INVALID_ARG,
+                        _("JSON backing volume definition '%s' lacks driver name"),
+-                       NULLSTR(str));
++                       jsonstr);
+         return -1;
+     }
+ 
+     for (i = 0; i < G_N_ELEMENTS(jsonParsers); i++) {
+         if (STREQ(drvname, jsonParsers[i].drvname))
+-            return jsonParsers[i].func(src, file, jsonParsers[i].opaque);
++            return jsonParsers[i].func(src, file, jsonstr, jsonParsers[i].opaque);
+     }
+ 
+     virReportError(VIR_ERR_INTERNAL_ERROR,
+@@ -3634,7 +3643,7 @@ virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+     if (!(root = virJSONValueFromString(json)))
+         return -1;
+ 
+-    return virStorageSourceParseBackingJSONInternal(src, root);
++    return virStorageSourceParseBackingJSONInternal(src, root, json);
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virStorageSourceParseBackingJSON-Prevent-arbitrary-nesting-with-format-drivers.patch b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Prevent-arbitrary-nesting-with-format-drivers.patch
new file mode 100644
index 0000000..331ad39
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceParseBackingJSON-Prevent-arbitrary-nesting-with-format-drivers.patch
@@ -0,0 +1,93 @@
+From 57eb21eb48d76798f0c990c839df148301e9cb0e Mon Sep 17 00:00:00 2001
+Message-Id: <57eb21eb48d76798f0c990c839df148301e9cb0e@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:10 +0100
+Subject: [PATCH] virStorageSourceParseBackingJSON: Prevent arbitrary nesting
+ with format drivers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since we parse attributes for 'raw' which is a format driver and thus
+has nested 'file' structure we must prevent that this isn't nested
+arbitrarily.
+
+Add a flag for the function which allows parsing of 'format' type
+drivers only on the first pass.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit fd70f1b4d324361bb9a708762631690aca043178)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+Message-Id: <b5ed395d736eb8570467e2eafb44288d77d416e7.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index dd05de188f..b02fad92b6 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3052,7 +3052,8 @@ virStorageSourceParseBackingColon(virStorageSourcePtr src,
+ static int
+ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+                                          virJSONValuePtr json,
+-                                         const char *jsonstr);
++                                         const char *jsonstr,
++                                         bool allowformat);
+ 
+ 
+ static int
+@@ -3531,7 +3532,7 @@ virStorageSourceParseBackingJSONRaw(virStorageSourcePtr src,
+         return -1;
+     }
+ 
+-    return virStorageSourceParseBackingJSONInternal(src, file, jsonstr);
++    return virStorageSourceParseBackingJSONInternal(src, file, jsonstr, false);
+ }
+ 
+ 
+@@ -3606,7 +3607,8 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
+ static int
+ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+                                          virJSONValuePtr json,
+-                                         const char *jsonstr)
++                                         const char *jsonstr,
++                                         bool allowformat)
+ {
+     const char *drvname;
+     size_t i;
+@@ -3619,8 +3621,17 @@ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
+     }
+ 
+     for (i = 0; i < G_N_ELEMENTS(jsonParsers); i++) {
+-        if (STREQ(drvname, jsonParsers[i].drvname))
+-            return jsonParsers[i].func(src, json, jsonstr, jsonParsers[i].opaque);
++        if (STRNEQ(drvname, jsonParsers[i].drvname))
++            continue;
++
++        if (jsonParsers[i].formatdriver && !allowformat) {
++            virReportError(VIR_ERR_INVALID_ARG,
++                           _("JSON backing volume definition '%s' must not have nested format drivers"),
++                           jsonstr);
++            return -1;
++        }
++
++        return jsonParsers[i].func(src, json, jsonstr, jsonParsers[i].opaque);
+     }
+ 
+     virReportError(VIR_ERR_INTERNAL_ERROR,
+@@ -3655,7 +3666,7 @@ virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+     if (!file)
+         file = deflattened;
+ 
+-    return virStorageSourceParseBackingJSONInternal(src, file, json);
++    return virStorageSourceParseBackingJSONInternal(src, file, json, true);
+ }
+ 
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virStorageSourceParseBackingJSONRaw-Parse-offset-and-size-attributes.patch b/SOURCES/libvirt-virStorageSourceParseBackingJSONRaw-Parse-offset-and-size-attributes.patch
new file mode 100644
index 0000000..2a16358
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceParseBackingJSONRaw-Parse-offset-and-size-attributes.patch
@@ -0,0 +1,78 @@
+From 32d58910c9d5a775315a42a76666844927c4dad1 Mon Sep 17 00:00:00 2001
+Message-Id: <32d58910c9d5a775315a42a76666844927c4dad1@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 19 Feb 2020 15:10:26 +0100
+Subject: [PATCH] virStorageSourceParseBackingJSONRaw: Parse 'offset' and
+ 'size' attributes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If the parsed 'raw' format JSON string has 'offset' or 'size' attributes
+parse them as the format slice.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1791788
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit e8a819e87f806e6c6690614c40dbeab0bd2e800e)
+Message-Id: <88f7d393b22949a8d6afdae44f8215aa06e65329.1582120424.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 20 ++++++++++++++++++++
+ tests/virstoragetest.c    |  6 +++++-
+ 2 files changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 0be4168d6e..fcbc97d96a 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3551,8 +3551,28 @@ virStorageSourceParseBackingJSONRaw(virStorageSourcePtr src,
+                                     const char *jsonstr,
+                                     int opaque G_GNUC_UNUSED)
+ {
++    bool has_offset = virJSONValueObjectHasKey(json, "offset");
++    bool has_size = virJSONValueObjectHasKey(json, "size");
+     virJSONValuePtr file;
+ 
++    if (has_offset || has_size) {
++        src->sliceStorage = g_new0(virStorageSourceSlice, 1);
++
++        if (has_offset &&
++            virJSONValueObjectGetNumberUlong(json, "offset", &src->sliceStorage->offset) < 0) {
++            virReportError(VIR_ERR_INVALID_ARG, "%s",
++                           _("malformed 'offset' property of 'raw' driver"));
++            return -1;
++        }
++
++        if (has_size &&
++            virJSONValueObjectGetNumberUlong(json, "size", &src->sliceStorage->size) < 0) {
++            virReportError(VIR_ERR_INVALID_ARG, "%s",
++                           _("malformed 'size' property of 'raw' driver"));
++            return -1;
++        }
++    }
++
+     /* 'raw' is a format driver so it can have protocol driver children */
+     if (!(file = virJSONValueObjectGetObject(json, "file"))) {
+         virReportError(VIR_ERR_INVALID_ARG,
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index 25d41f0de4..39040bf4cb 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1600,7 +1600,11 @@ mymain(void)
+                                                 "\"filename\": \"/tmp/testfle\""
+                                               "}"
+                                   "}",
+-                            "<source file='/tmp/testfle'/>\n", 0);
++                            "<source file='/tmp/testfle'>\n"
++                            "  <slices>\n"
++                            "    <slice type='storage' offset='10752' size='4063232'/>\n"
++                            "  </slices>\n"
++                            "</source>\n", 0);
+ 
+ #endif /* WITH_YAJL */
+ 
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virStorageSourceParseBackingJSONUri-Handle-undocumented-value-off-for-sslverify.patch b/SOURCES/libvirt-virStorageSourceParseBackingJSONUri-Handle-undocumented-value-off-for-sslverify.patch
new file mode 100644
index 0000000..8627659
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceParseBackingJSONUri-Handle-undocumented-value-off-for-sslverify.patch
@@ -0,0 +1,92 @@
+From a5496b797498dc5393ccbf2775a2947e67a804eb Mon Sep 17 00:00:00 2001
+Message-Id: <a5496b797498dc5393ccbf2775a2947e67a804eb@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:08 +0100
+Subject: [PATCH] virStorageSourceParseBackingJSONUri: Handle undocumented
+ value 'off' for sslverify
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+libguestfs abuses a quirk of qemu's parser to accept also other variants
+of the 'sslverify' field which would be valid on the command line but
+are not documented in the QMP schema.
+
+If we encounter the 'off' string instead of an boolean handle it rather
+than erroring out to continue support of pre-blockdev configurations.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 5179cc6b08a06fad92e8674d048fc0327d48f79e)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <8f277a7bede59b7c8b6de9db9c7726b6cbe02192.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 21 ++++++++++++++-------
+ tests/virstoragetest.c    | 15 +++++++++++++++
+ 2 files changed, 29 insertions(+), 7 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 931f2db6e9..9eca186e99 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3278,16 +3278,23 @@ virStorageSourceParseBackingJSONUri(virStorageSourcePtr src,
+     if (protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS ||
+         protocol == VIR_STORAGE_NET_PROTOCOL_FTPS) {
+         if (virJSONValueObjectHasKey(json, "sslverify")) {
++            const char *tmpstr;
+             bool tmp;
+ 
+-            if (virJSONValueObjectGetBoolean(json, "sslverify", &tmp) < 0) {
+-                virReportError(VIR_ERR_INVALID_ARG,
+-                               _("malformed 'sslverify' field in backing store definition '%s'"),
+-                               jsonstr);
+-                return -1;
+-            }
++            /* libguestfs still uses undocumented legacy value of 'off' */
++            if ((tmpstr = virJSONValueObjectGetString(json, "sslverify")) &&
++                STREQ(tmpstr, "off")) {
++                src->sslverify = VIR_TRISTATE_BOOL_NO;
++            } else {
++                if (virJSONValueObjectGetBoolean(json, "sslverify", &tmp) < 0) {
++                    virReportError(VIR_ERR_INVALID_ARG,
++                                   _("malformed 'sslverify' field in backing store definition '%s'"),
++                                   jsonstr);
++                    return -1;
++                }
+ 
+-            src->sslverify = virTristateBoolFromBool(tmp);
++                src->sslverify = virTristateBoolFromBool(tmp);
++            }
+         }
+     }
+ 
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index 63b991eb71..ca428f5ca7 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1621,6 +1621,21 @@ mymain(void)
+                            "  <timeout seconds='2000'/>\n"
+                            "</source>\n", 0);
+ 
++    TEST_BACKING_PARSE_FULL("json:{ \"file.cookie\": \"vmware_soap_session=\\\"0c8db85112873a79b7ef74f294cb70ef7f\\\"\","
++                                   "\"file.sslverify\": \"off\","
++                                   "\"file.driver\": \"https\","
++                                   "\"file.url\": \"https://host/folder/esx6.5-rhel7.7-x86%5f64/esx6.5-rhel7.7-x86%5f64-flat.vmdk?dcPath=data&dsName=esx6.5-matrix\","
++                                   "\"file.timeout\": 2000"
++                                 "}",
++                           "<source protocol='https' name='folder/esx6.5-rhel7.7-x86_64/esx6.5-rhel7.7-x86_64-flat.vmdk'>\n"
++                           "  <host name='host' port='443'/>\n"
++                           "  <ssl verify='no'/>\n"
++                           "  <cookies>\n"
++                           "    <cookie name='vmware_soap_session'>&quot;0c8db85112873a79b7ef74f294cb70ef7f&quot;</cookie>\n"
++                           "  </cookies>\n"
++                           "  <timeout seconds='2000'/>\n"
++                           "</source>\n", 0);
++
+ #endif /* WITH_YAJL */
+ 
+  cleanup:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virStorageSourceParseBackingURI-Preserve-query-string-of-URI-for-http-s.patch b/SOURCES/libvirt-virStorageSourceParseBackingURI-Preserve-query-string-of-URI-for-http-s.patch
new file mode 100644
index 0000000..4cd7559
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceParseBackingURI-Preserve-query-string-of-URI-for-http-s.patch
@@ -0,0 +1,73 @@
+From a08b866ca5b7ae45d25a584d5e61855015b80794 Mon Sep 17 00:00:00 2001
+Message-Id: <a08b866ca5b7ae45d25a584d5e61855015b80794@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 30 Mar 2020 17:21:47 +0200
+Subject: [PATCH] virStorageSourceParseBackingURI: Preserve query string of URI
+ for http(s)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+For http/https URIs we need to preserve the query part as it may be
+important to refer to the image.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 544ef82d05a675d9c6f939c67635ed46c094b164)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <ecddbeb737c76791d4372c861343da2fc8611371.1585581552.git.pkrempa@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virstoragefile.c | 13 ++++++++++---
+ tests/virstoragetest.c    |  4 ++--
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 4082e3f5f7..aba315d93b 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -2853,9 +2853,16 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src,
+         return -1;
+     }
+ 
+-    /* handle socket stored as a query */
+-    if (uri->query)
+-        src->hosts->socket = g_strdup(STRSKIP(uri->query, "socket="));
++    if (uri->query) {
++        if (src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTP ||
++            src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS) {
++            src->query = g_strdup(uri->query);
++        } else {
++            /* handle socket stored as a query */
++            if (STRPREFIX(uri->query, "socket="))
++                src->hosts->socket = g_strdup(STRSKIP(uri->query, "socket="));
++        }
++    }
+ 
+     /* uri->path is NULL if the URI does not contain slash after host:
+      * transport://host:port */
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index d9244fdfe8..fe8f6dd36f 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1613,7 +1613,7 @@ mymain(void)
+                                    "\"file.url\": \"https://host/folder/esx6.5-rhel7.7-x86%5f64/esx6.5-rhel7.7-x86%5f64-flat.vmdk?dcPath=data&dsName=esx6.5-matrix\","
+                                    "\"file.timeout\": 2000"
+                                  "}",
+-                           "<source protocol='https' name='folder/esx6.5-rhel7.7-x86_64/esx6.5-rhel7.7-x86_64-flat.vmdk'>\n"
++                           "<source protocol='https' name='folder/esx6.5-rhel7.7-x86_64/esx6.5-rhel7.7-x86_64-flat.vmdk' query='dcPath=data&amp;dsName=esx6.5-matrix'>\n"
+                            "  <host name='host' port='443'/>\n"
+                            "  <ssl verify='no'/>\n"
+                            "  <cookies>\n"
+@@ -1628,7 +1628,7 @@ mymain(void)
+                                    "\"file.url\": \"https://host/folder/esx6.5-rhel7.7-x86%5f64/esx6.5-rhel7.7-x86%5f64-flat.vmdk?dcPath=data&dsName=esx6.5-matrix\","
+                                    "\"file.timeout\": 2000"
+                                  "}",
+-                           "<source protocol='https' name='folder/esx6.5-rhel7.7-x86_64/esx6.5-rhel7.7-x86_64-flat.vmdk'>\n"
++                           "<source protocol='https' name='folder/esx6.5-rhel7.7-x86_64/esx6.5-rhel7.7-x86_64-flat.vmdk' query='dcPath=data&amp;dsName=esx6.5-matrix'>\n"
+                            "  <host name='host' port='443'/>\n"
+                            "  <ssl verify='no'/>\n"
+                            "  <cookies>\n"
+-- 
+2.26.0
+
diff --git a/SOURCES/libvirt-virStorageSourceUpdateCapacity-Drop-probe-argument.patch b/SOURCES/libvirt-virStorageSourceUpdateCapacity-Drop-probe-argument.patch
new file mode 100644
index 0000000..05c9a1f
--- /dev/null
+++ b/SOURCES/libvirt-virStorageSourceUpdateCapacity-Drop-probe-argument.patch
@@ -0,0 +1,117 @@
+From f27731da867f6a0784c1f2a222d5b7663c418784 Mon Sep 17 00:00:00 2001
+Message-Id: <f27731da867f6a0784c1f2a222d5b7663c418784@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 28 Feb 2020 10:24:36 +0100
+Subject: [PATCH] virStorageSourceUpdateCapacity: Drop 'probe' argument
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Both callers pass false. Since we frown upon format probing, remove the
+unused possibility to do the probing.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 35d1f5bd145163edf4f05c377b488ffa50d527d6)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1798148
+Message-Id: <c2cfa21552eee3b2cfca74096dfe9d301bbf4e61.1582881363.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_driver.c     |  2 +-
+ src/storage/storage_util.c |  2 +-
+ src/util/virstoragefile.c  | 23 ++++++-----------------
+ src/util/virstoragefile.h  |  3 +--
+ 4 files changed, 9 insertions(+), 21 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index ac3a7ad282..d346446444 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -12221,7 +12221,7 @@ qemuStorageLimitsRefresh(virQEMUDriverPtr driver,
+     if (virStorageSourceUpdateBackingSizes(src, fd, &sb) < 0)
+         goto cleanup;
+ 
+-    if (virStorageSourceUpdateCapacity(src, buf, len, false) < 0)
++    if (virStorageSourceUpdateCapacity(src, buf, len) < 0)
+         goto cleanup;
+ 
+     /* If guest is not using raw disk format and is on a host block
+diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
+index ebc262278d..c562cf313f 100644
+--- a/src/storage/storage_util.c
++++ b/src/storage/storage_util.c
+@@ -1755,7 +1755,7 @@ storageBackendUpdateVolTargetInfo(virStorageVolType voltype,
+             }
+         }
+ 
+-        if (virStorageSourceUpdateCapacity(target, buf, len, false) < 0)
++        if (virStorageSourceUpdateCapacity(target, buf, len) < 0)
+             return -1;
+     }
+ 
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 5a74034ec4..391e2ce86f 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3964,18 +3964,15 @@ virStorageSourceUpdateBackingSizes(virStorageSourcePtr src,
+  * @src: disk source definition structure
+  * @buf: buffer to the storage file header
+  * @len: length of the storage file header
+- * @probe: allow probe
+  *
+- * Update the storage @src capacity. This may involve probing the storage
+- * @src in order to "see" if we can recognize what exists.
++ * Update the storage @src capacity.
+  *
+  * Returns 0 on success, -1 on error.
+  */
+ int
+ virStorageSourceUpdateCapacity(virStorageSourcePtr src,
+                                char *buf,
+-                               ssize_t len,
+-                               bool probe)
++                               ssize_t len)
+ {
+     int format = src->format;
+     g_autoptr(virStorageSource) meta = NULL;
+@@ -3984,18 +3981,10 @@ virStorageSourceUpdateCapacity(virStorageSourcePtr src,
+      * the metadata has a capacity, use that, otherwise fall back to
+      * physical size.  */
+     if (format == VIR_STORAGE_FILE_NONE) {
+-        if (!probe) {
+-            virReportError(VIR_ERR_INTERNAL_ERROR,
+-                           _("no disk format for %s and probing is disabled"),
+-                           src->path);
+-            return -1;
+-        }
+-
+-        if ((format = virStorageFileProbeFormatFromBuf(src->path,
+-                                                       buf, len)) < 0)
+-            return -1;
+-
+-        src->format = format;
++        virReportError(VIR_ERR_INTERNAL_ERROR,
++                       _("no disk format for %s was specified"),
++                       src->path);
++        return -1;
+     }
+ 
+     if (format == VIR_STORAGE_FILE_RAW && !src->encryption) {
+diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
+index 1f41e6e357..2a684fd746 100644
+--- a/src/util/virstoragefile.h
++++ b/src/util/virstoragefile.h
+@@ -472,8 +472,7 @@ int virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src,
+ int virStorageSourceUpdateBackingSizes(virStorageSourcePtr src,
+                                        int fd, struct stat const *sb);
+ int virStorageSourceUpdateCapacity(virStorageSourcePtr src,
+-                                   char *buf, ssize_t len,
+-                                   bool probe);
++                                   char *buf, ssize_t len);
+ 
+ int virStorageSourceNewFromBacking(virStorageSourcePtr parent,
+                                    virStorageSourcePtr *backing);
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virbuftest-declare-testBufAddStrData-earlier.patch b/SOURCES/libvirt-virbuftest-declare-testBufAddStrData-earlier.patch
new file mode 100644
index 0000000..74889f6
--- /dev/null
+++ b/SOURCES/libvirt-virbuftest-declare-testBufAddStrData-earlier.patch
@@ -0,0 +1,55 @@
+From 2056fea539669061bec0d707511ff0f1391953b0 Mon Sep 17 00:00:00 2001
+Message-Id: <2056fea539669061bec0d707511ff0f1391953b0@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:05 +0100
+Subject: [PATCH] virbuftest: declare testBufAddStrData earlier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move the declaration to the beginning of the file for reuse.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit ebd44715f19a81f16b2e263b262c0099fe94a0b6)
+
+Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <5bd2b1b3dfb32ca39c8e1d10810385d483d0643a.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virbuftest.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/tests/virbuftest.c b/tests/virbuftest.c
+index bb7fa9e2e9..bb606c1c28 100644
+--- a/tests/virbuftest.c
++++ b/tests/virbuftest.c
+@@ -9,6 +9,11 @@
+ 
+ #define VIR_FROM_THIS VIR_FROM_NONE
+ 
++struct testBufAddStrData {
++    const char *data;
++    const char *expect;
++};
++
+ static int testBufAutoIndent(const void *data G_GNUC_UNUSED)
+ {
+     virBuffer bufinit = VIR_BUFFER_INITIALIZER;
+@@ -235,11 +240,6 @@ static int testBufAddBuffer(const void *data G_GNUC_UNUSED)
+     return ret;
+ }
+ 
+-struct testBufAddStrData {
+-    const char *data;
+-    const char *expect;
+-};
+-
+ static int
+ testBufAddStr(const void *opaque)
+ {
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virbuftest-remove-extra-G_GNUC_UNUSED-markers.patch b/SOURCES/libvirt-virbuftest-remove-extra-G_GNUC_UNUSED-markers.patch
new file mode 100644
index 0000000..b9da409
--- /dev/null
+++ b/SOURCES/libvirt-virbuftest-remove-extra-G_GNUC_UNUSED-markers.patch
@@ -0,0 +1,49 @@
+From f6916b32bbbd89fb3faf6ad2c21cb975e15a8b18 Mon Sep 17 00:00:00 2001
+Message-Id: <f6916b32bbbd89fb3faf6ad2c21cb975e15a8b18@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:02 +0100
+Subject: [PATCH] virbuftest: remove extra G_GNUC_UNUSED markers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These functions do use the opaque argument.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit 08de39a9c7a65f17292eeef783d0598c2dfc8260)
+
+Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <64efa6130de1732be0feeaf4f2e78c0aecaf38c5.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virbuftest.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/virbuftest.c b/tests/virbuftest.c
+index 56a6ece8f6..f8eadea25a 100644
+--- a/tests/virbuftest.c
++++ b/tests/virbuftest.c
+@@ -244,7 +244,7 @@ struct testBufAddStrData {
+ };
+ 
+ static int
+-testBufAddStr(const void *opaque G_GNUC_UNUSED)
++testBufAddStr(const void *opaque)
+ {
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+@@ -277,7 +277,7 @@ testBufAddStr(const void *opaque G_GNUC_UNUSED)
+ 
+ 
+ static int
+-testBufEscapeStr(const void *opaque G_GNUC_UNUSED)
++testBufEscapeStr(const void *opaque)
+ {
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virbuftest-remove-unnecessary-labels.patch b/SOURCES/libvirt-virbuftest-remove-unnecessary-labels.patch
new file mode 100644
index 0000000..fa5f2bf
--- /dev/null
+++ b/SOURCES/libvirt-virbuftest-remove-unnecessary-labels.patch
@@ -0,0 +1,152 @@
+From 868b112fabc71f2247d2e4880f207f31727b549c Mon Sep 17 00:00:00 2001
+Message-Id: <868b112fabc71f2247d2e4880f207f31727b549c@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:04 +0100
+Subject: [PATCH] virbuftest: remove unnecessary labels
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Remove the ret variables and labels from functions that no longer need
+them.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit 662876723cdfb138ca31847fdb3a84bbe3cadea5)
+
+Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <8d02662ab00fa2c7088912148fb1131f24623d32.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virbuftest.c | 40 ++++++++++++----------------------------
+ 1 file changed, 12 insertions(+), 28 deletions(-)
+
+diff --git a/tests/virbuftest.c b/tests/virbuftest.c
+index 2b241424ad..bb7fa9e2e9 100644
+--- a/tests/virbuftest.c
++++ b/tests/virbuftest.c
+@@ -246,7 +246,6 @@ testBufAddStr(const void *opaque)
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     g_autofree char *actual = NULL;
+-    int ret = -1;
+ 
+     virBufferAddLit(&buf, "<c>\n");
+     virBufferAdjustIndent(&buf, 2);
+@@ -256,19 +255,16 @@ testBufAddStr(const void *opaque)
+ 
+     if (!(actual = virBufferContentAndReset(&buf))) {
+         VIR_TEST_DEBUG("buf is empty");
+-        goto cleanup;
++        return -1;
+     }
+ 
+     if (STRNEQ_NULLABLE(actual, data->expect)) {
+         VIR_TEST_DEBUG("testBufAddStr(): Strings don't match:");
+         virTestDifference(stderr, data->expect, actual);
+-        goto cleanup;
++        return -1;
+     }
+ 
+-    ret = 0;
+-
+- cleanup:
+-    return ret;
++    return 0;
+ }
+ 
+ 
+@@ -278,7 +274,6 @@ testBufEscapeStr(const void *opaque)
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     g_autofree char *actual = NULL;
+-    int ret = -1;
+ 
+     virBufferAddLit(&buf, "<c>\n");
+     virBufferAdjustIndent(&buf, 2);
+@@ -288,19 +283,16 @@ testBufEscapeStr(const void *opaque)
+ 
+     if (!(actual = virBufferContentAndReset(&buf))) {
+         VIR_TEST_DEBUG("buf is empty");
+-        goto cleanup;
++        return -1;
+     }
+ 
+     if (STRNEQ_NULLABLE(actual, data->expect)) {
+         VIR_TEST_DEBUG("testBufEscapeStr(): Strings don't match:");
+         virTestDifference(stderr, data->expect, actual);
+-        goto cleanup;
++        return -1;
+     }
+ 
+-    ret = 0;
+-
+- cleanup:
+-    return ret;
++    return 0;
+ }
+ 
+ 
+@@ -310,25 +302,21 @@ testBufEscapeRegex(const void *opaque)
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     g_autofree char *actual = NULL;
+-    int ret = -1;
+ 
+     virBufferEscapeRegex(&buf, "%s", data->data);
+ 
+     if (!(actual = virBufferContentAndReset(&buf))) {
+         VIR_TEST_DEBUG("testBufEscapeRegex: buf is empty");
+-        goto cleanup;
++        return -1;
+     }
+ 
+     if (STRNEQ_NULLABLE(actual, data->expect)) {
+         VIR_TEST_DEBUG("testBufEscapeRegex: Strings don't match:");
+         virTestDifference(stderr, data->expect, actual);
+-        goto cleanup;
++        return -1;
+     }
+ 
+-    ret = 0;
+-
+- cleanup:
+-    return ret;
++    return 0;
+ }
+ 
+ 
+@@ -337,7 +325,6 @@ testBufSetIndent(const void *opaque G_GNUC_UNUSED)
+ {
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     g_autofree char *actual = NULL;
+-    int ret = -1;
+ 
+     virBufferSetIndent(&buf, 11);
+     virBufferAddLit(&buf, "test\n");
+@@ -345,17 +332,14 @@ testBufSetIndent(const void *opaque G_GNUC_UNUSED)
+     virBufferAddLit(&buf, "test2\n");
+ 
+     if (!(actual = virBufferContentAndReset(&buf)))
+-        goto cleanup;
++        return -1;
+ 
+     if (STRNEQ(actual, "           test\n  test2\n")) {
+         VIR_TEST_DEBUG("testBufSetIndent: expected indent not set");
+-        goto cleanup;
++        return -1;
+     }
+ 
+-    ret = 0;
+-
+- cleanup:
+-    return ret;
++    return 0;
+ }
+ 
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virbuftest-use-field-names-when-initalizing-test-info.patch b/SOURCES/libvirt-virbuftest-use-field-names-when-initalizing-test-info.patch
new file mode 100644
index 0000000..77364f5
--- /dev/null
+++ b/SOURCES/libvirt-virbuftest-use-field-names-when-initalizing-test-info.patch
@@ -0,0 +1,74 @@
+From 401d5f108c69a01fca8843868e12d102e75e8dd2 Mon Sep 17 00:00:00 2001
+Message-Id: <401d5f108c69a01fca8843868e12d102e75e8dd2@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:06 +0100
+Subject: [PATCH] virbuftest: use field names when initalizing test info
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allow adding new fields without changing all the macros.
+
+Otherwise the compiler complains that not all have been initialized:
+../../tests/virbuftest.c:419:5: error: missing field 'arg' initializer [-Werror,-Wmissing-field-initializers]
+    DO_TEST_ESCAPE("<td></td><td></td>",
+    ^
+../../tests/virbuftest.c:414:56: note: expanded from macro 'DO_TEST_ESCAPE'
+        struct testBufAddStrData info = { data, expect }; \
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit 46afdc21207d3276f0e100b6e54ca41ee5f12e99)
+
+Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <b5da3d53ae4fc1a592b41230f3b838357cc57d30.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virbuftest.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/tests/virbuftest.c b/tests/virbuftest.c
+index bb606c1c28..1780b62bf4 100644
+--- a/tests/virbuftest.c
++++ b/tests/virbuftest.c
+@@ -372,9 +372,9 @@ mymain(void)
+     DO_TEST("set indent", testBufSetIndent);
+     DO_TEST("autoclean", testBufferAutoclean);
+ 
+-#define DO_TEST_ADD_STR(DATA, EXPECT) \
++#define DO_TEST_ADD_STR(_data, _expect) \
+     do { \
+-        struct testBufAddStrData info = { DATA, EXPECT }; \
++        struct testBufAddStrData info = { .data = _data, .expect = _expect }; \
+         if (virTestRun("Buf: AddStr", testBufAddStr, &info) < 0) \
+             ret = -1; \
+     } while (0)
+@@ -384,9 +384,9 @@ mymain(void)
+     DO_TEST_ADD_STR("<a/>\n", "<c>\n  <a/>\n</c>");
+     DO_TEST_ADD_STR("<b>\n  <a/>\n</b>\n", "<c>\n  <b>\n    <a/>\n  </b>\n</c>");
+ 
+-#define DO_TEST_ESCAPE(data, expect) \
++#define DO_TEST_ESCAPE(_data, _expect) \
+     do { \
+-        struct testBufAddStrData info = { data, expect }; \
++        struct testBufAddStrData info = { .data = _data, .expect = _expect }; \
+         if (virTestRun("Buf: EscapeStr", testBufEscapeStr, &info) < 0) \
+             ret = -1; \
+     } while (0)
+@@ -400,9 +400,9 @@ mymain(void)
+     DO_TEST_ESCAPE("\x01\x01\x02\x03\x05\x08",
+                    "<c>\n  <el></el>\n</c>");
+ 
+-#define DO_TEST_ESCAPE_REGEX(data, expect) \
++#define DO_TEST_ESCAPE_REGEX(_data, _expect) \
+     do { \
+-        struct testBufAddStrData info = { data, expect }; \
++        struct testBufAddStrData info = { .data = _data, .expect = _expect }; \
+         if (virTestRun("Buf: EscapeRegex", testBufEscapeRegex, &info) < 0) \
+             ret = -1; \
+     } while (0)
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virbuftest-use-g_autofree.patch b/SOURCES/libvirt-virbuftest-use-g_autofree.patch
new file mode 100644
index 0000000..9a0065f
--- /dev/null
+++ b/SOURCES/libvirt-virbuftest-use-g_autofree.patch
@@ -0,0 +1,148 @@
+From e3824886db80dba4e524aa737abb3188373076a6 Mon Sep 17 00:00:00 2001
+Message-Id: <e3824886db80dba4e524aa737abb3188373076a6@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 13 Mar 2020 13:08:03 +0100
+Subject: [PATCH] virbuftest: use g_autofree
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+(cherry picked from commit b0138d55f72ae64c2bf1abb4ab8cc7eea217ca04)
+
+Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <e2251697da65f2cd0566647d3270117744ff0b21.1584101247.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/virbuftest.c | 21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/tests/virbuftest.c b/tests/virbuftest.c
+index f8eadea25a..2b241424ad 100644
+--- a/tests/virbuftest.c
++++ b/tests/virbuftest.c
+@@ -15,7 +15,7 @@ static int testBufAutoIndent(const void *data G_GNUC_UNUSED)
+     virBufferPtr buf = &bufinit;
+     const char expected[] =
+         "  1\n  2\n  3\n  4\n  5\n  6\n  7\n  &amp;\n  8\n  9\n  10\n  ' 11'\n";
+-    char *result = NULL;
++    g_autofree char *result = NULL;
+     int ret = 0;
+ 
+     if (virBufferGetIndent(buf) != 0 ||
+@@ -85,7 +85,6 @@ static int testBufAutoIndent(const void *data G_GNUC_UNUSED)
+         virTestDifference(stderr, expected, result);
+         ret = -1;
+     }
+-    VIR_FREE(result);
+     return ret;
+ }
+ 
+@@ -93,7 +92,7 @@ static int testBufTrim(const void *data G_GNUC_UNUSED)
+ {
+     virBuffer bufinit = VIR_BUFFER_INITIALIZER;
+     virBufferPtr buf = NULL;
+-    char *result = NULL;
++    g_autofree char *result = NULL;
+     const char *expected = "a,b";
+     int ret = -1;
+ 
+@@ -123,7 +122,6 @@ static int testBufTrim(const void *data G_GNUC_UNUSED)
+ 
+  cleanup:
+     virBufferFreeAndReset(buf);
+-    VIR_FREE(result);
+     return ret;
+ }
+ 
+@@ -133,7 +131,7 @@ static int testBufAddBuffer(const void *data G_GNUC_UNUSED)
+     virBuffer buf2 = VIR_BUFFER_INITIALIZER;
+     virBuffer buf3 = VIR_BUFFER_INITIALIZER;
+     int ret = -1;
+-    char *result = NULL;
++    g_autofree char *result = NULL;
+     const char *expected = \
+ "  A long time ago, in a galaxy far,\n" \
+ "  far away...\n" \
+@@ -234,7 +232,6 @@ static int testBufAddBuffer(const void *data G_GNUC_UNUSED)
+  cleanup:
+     virBufferFreeAndReset(&buf1);
+     virBufferFreeAndReset(&buf2);
+-    VIR_FREE(result);
+     return ret;
+ }
+ 
+@@ -248,7 +245,7 @@ testBufAddStr(const void *opaque)
+ {
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+-    char *actual;
++    g_autofree char *actual = NULL;
+     int ret = -1;
+ 
+     virBufferAddLit(&buf, "<c>\n");
+@@ -271,7 +268,6 @@ testBufAddStr(const void *opaque)
+     ret = 0;
+ 
+  cleanup:
+-    VIR_FREE(actual);
+     return ret;
+ }
+ 
+@@ -281,7 +277,7 @@ testBufEscapeStr(const void *opaque)
+ {
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+-    char *actual;
++    g_autofree char *actual = NULL;
+     int ret = -1;
+ 
+     virBufferAddLit(&buf, "<c>\n");
+@@ -304,7 +300,6 @@ testBufEscapeStr(const void *opaque)
+     ret = 0;
+ 
+  cleanup:
+-    VIR_FREE(actual);
+     return ret;
+ }
+ 
+@@ -314,7 +309,7 @@ testBufEscapeRegex(const void *opaque)
+ {
+     const struct testBufAddStrData *data = opaque;
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+-    char *actual;
++    g_autofree char *actual = NULL;
+     int ret = -1;
+ 
+     virBufferEscapeRegex(&buf, "%s", data->data);
+@@ -333,7 +328,6 @@ testBufEscapeRegex(const void *opaque)
+     ret = 0;
+ 
+  cleanup:
+-    VIR_FREE(actual);
+     return ret;
+ }
+ 
+@@ -342,7 +336,7 @@ static int
+ testBufSetIndent(const void *opaque G_GNUC_UNUSED)
+ {
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+-    char *actual;
++    g_autofree char *actual = NULL;
+     int ret = -1;
+ 
+     virBufferSetIndent(&buf, 11);
+@@ -361,7 +355,6 @@ testBufSetIndent(const void *opaque G_GNUC_UNUSED)
+     ret = 0;
+ 
+  cleanup:
+-    VIR_FREE(actual);
+     return ret;
+ }
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-virhash-Fix-the-expectations-of-virHashKeyEqual-implementations.patch b/SOURCES/libvirt-virhash-Fix-the-expectations-of-virHashKeyEqual-implementations.patch
new file mode 100644
index 0000000..be07d36
--- /dev/null
+++ b/SOURCES/libvirt-virhash-Fix-the-expectations-of-virHashKeyEqual-implementations.patch
@@ -0,0 +1,74 @@
+From 946b656463d4947801be9ac138113feec1f0cf48 Mon Sep 17 00:00:00 2001
+Message-Id: <946b656463d4947801be9ac138113feec1f0cf48@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Tue, 4 Feb 2020 15:08:19 +0100
+Subject: [PATCH] virhash: Fix the expectations of virHashKeyEqual
+ implementations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Tweak the return value expectation comment so that it doesn't
+necessarily require to allocate memory and refactor the implementations.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 6cf3ec4428c6b3f3dae30286e50bb7396615cf56)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1207659
+Message-Id: <2b3b0d52d6baa6ddb67b26520cfae1a5f247d803.1580824112.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_addr.c | 5 +----
+ src/util/virhash.c     | 4 +---
+ src/util/virhash.h     | 3 ++-
+ 3 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
+index f07b3d9725..e0be655772 100644
+--- a/src/conf/domain_addr.c
++++ b/src/conf/domain_addr.c
+@@ -997,10 +997,7 @@ virZPCIAddrKeyEqual(const void *namea,
+ static void *
+ virZPCIAddrKeyCopy(const void *name)
+ {
+-    unsigned int *copy;
+-
+-    if (VIR_ALLOC(copy) < 0)
+-        return NULL;
++    unsigned int *copy = g_new0(unsigned int, 1);
+ 
+     *copy = *((unsigned int *)name);
+     return (void *)copy;
+diff --git a/src/util/virhash.c b/src/util/virhash.c
+index d5c5e017a1..c57d9f8292 100644
+--- a/src/util/virhash.c
++++ b/src/util/virhash.c
+@@ -94,9 +94,7 @@ static bool virHashStrEqual(const void *namea, const void *nameb)
+ 
+ static void *virHashStrCopy(const void *name)
+ {
+-    char *ret;
+-    ret = g_strdup(name);
+-    return ret;
++    return g_strdup(name);
+ }
+ 
+ 
+diff --git a/src/util/virhash.h b/src/util/virhash.h
+index 08f99d8a3d..cb59fb639b 100644
+--- a/src/util/virhash.h
++++ b/src/util/virhash.h
+@@ -83,7 +83,8 @@ typedef bool (*virHashKeyEqual)(const void *namea, const void *nameb);
+  * Create a copy of the hash key, duplicating
+  * memory allocation where applicable
+  *
+- * Returns a newly allocated copy of @name
++ * Returns a copy of @name which will eventually be passed to the
++ * 'virHashKeyFree' callback at the end of its lifetime.
+  */
+ typedef void *(*virHashKeyCopy)(const void *name);
+ /**
+-- 
+2.25.0
+
diff --git a/SOURCES/libvirt-virstoragefile-Add-JSON-parser-for-sslverify-readahead-cookies-and-timeout.patch b/SOURCES/libvirt-virstoragefile-Add-JSON-parser-for-sslverify-readahead-cookies-and-timeout.patch
new file mode 100644
index 0000000..d81170f
--- /dev/null
+++ b/SOURCES/libvirt-virstoragefile-Add-JSON-parser-for-sslverify-readahead-cookies-and-timeout.patch
@@ -0,0 +1,183 @@
+From 1fdf4e4f9180b74d59882c1a70ad99e1d5165a14 Mon Sep 17 00:00:00 2001
+Message-Id: <1fdf4e4f9180b74d59882c1a70ad99e1d5165a14@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Mon, 16 Mar 2020 22:12:07 +0100
+Subject: [PATCH] virstoragefile: Add JSON parser for 'sslverify', 'readahead',
+ 'cookies' and 'timeout'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for parsing the recently added fields from backing file
+pseudo-protocol strings.
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 77194db01c4ab785a4668257bc9409b164f059aa)
+https://bugzilla.redhat.com/show_bug.cgi?id=1804750
+Message-Id: <9c5ef44994a5e60b08ad421762acefa26cde5a28.1584391727.git.pkrempa@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virstoragefile.c | 91 ++++++++++++++++++++++++++++++++++++++-
+ tests/qemublocktest.c     |  6 +++
+ tests/virstoragetest.c    | 15 +++++++
+ 3 files changed, 111 insertions(+), 1 deletion(-)
+
+diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
+index 7893e054c3..931f2db6e9 100644
+--- a/src/util/virstoragefile.c
++++ b/src/util/virstoragefile.c
+@@ -3210,10 +3210,61 @@ virStorageSourceParseBackingJSONUriStr(virStorageSourcePtr src,
+ }
+ 
+ 
++static int
++virStorageSourceParseBackingJSONUriCookies(virStorageSourcePtr src,
++                                           virJSONValuePtr json,
++                                           const char *jsonstr)
++{
++    const char *cookiestr;
++    VIR_AUTOSTRINGLIST cookies = NULL;
++    size_t ncookies = 0;
++    size_t i;
++
++    if (!virJSONValueObjectHasKey(json, "cookie"))
++        return 0;
++
++    if (!(cookiestr = virJSONValueObjectGetString(json, "cookie"))) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("wrong format of 'cookie' field in backing store definition '%s'"),
++                       jsonstr);
++        return -1;
++    }
++
++    if (!(cookies = virStringSplitCount(cookiestr, ";", 0, &ncookies)))
++        return -1;
++
++    src->cookies = g_new0(virStorageNetCookieDefPtr, ncookies);
++    src->ncookies = ncookies;
++
++    for (i = 0; i < ncookies; i++) {
++        char *cookiename = cookies[i];
++        char *cookievalue;
++
++        virSkipSpaces((const char **) &cookiename);
++
++        if (!(cookievalue = strchr(cookiename, '='))) {
++            virReportError(VIR_ERR_INVALID_ARG,
++                           _("malformed http cookie '%s' in backing store definition '%s'"),
++                           cookies[i], jsonstr);
++            return -1;
++        }
++
++        *cookievalue = '\0';
++        cookievalue++;
++
++        src->cookies[i] = g_new0(virStorageNetCookieDef, 1);
++        src->cookies[i]->name = g_strdup(cookiename);
++        src->cookies[i]->value = g_strdup(cookievalue);
++    }
++
++    return 0;
++}
++
++
+ static int
+ virStorageSourceParseBackingJSONUri(virStorageSourcePtr src,
+                                     virJSONValuePtr json,
+-                                    const char *jsonstr G_GNUC_UNUSED,
++                                    const char *jsonstr,
+                                     int protocol)
+ {
+     const char *uri;
+@@ -3224,6 +3275,44 @@ virStorageSourceParseBackingJSONUri(virStorageSourcePtr src,
+         return -1;
+     }
+ 
++    if (protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS ||
++        protocol == VIR_STORAGE_NET_PROTOCOL_FTPS) {
++        if (virJSONValueObjectHasKey(json, "sslverify")) {
++            bool tmp;
++
++            if (virJSONValueObjectGetBoolean(json, "sslverify", &tmp) < 0) {
++                virReportError(VIR_ERR_INVALID_ARG,
++                               _("malformed 'sslverify' field in backing store definition '%s'"),
++                               jsonstr);
++                return -1;
++            }
++
++            src->sslverify = virTristateBoolFromBool(tmp);
++        }
++    }
++
++    if (protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS ||
++        protocol == VIR_STORAGE_NET_PROTOCOL_HTTP) {
++        if (virStorageSourceParseBackingJSONUriCookies(src, json, jsonstr) < 0)
++            return -1;
++    }
++
++    if (virJSONValueObjectHasKey(json, "readahead") &&
++        virJSONValueObjectGetNumberUlong(json, "readahead", &src->readahead) < 0) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("malformed 'readahead' field in backing store definition '%s'"),
++                       jsonstr);
++        return -1;
++    }
++
++    if (virJSONValueObjectHasKey(json, "timeout") &&
++        virJSONValueObjectGetNumberUlong(json, "timeout", &src->timeout) < 0) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("malformed 'timeout' field in backing store definition '%s'"),
++                       jsonstr);
++        return -1;
++    }
++
+     return virStorageSourceParseBackingJSONUriStr(src, uri, protocol);
+ }
+ 
+diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
+index 29af0781fc..3057db6930 100644
+--- a/tests/qemublocktest.c
++++ b/tests/qemublocktest.c
+@@ -913,6 +913,12 @@ mymain(void)
+     TEST_JSON_FORMAT_NET("<source protocol='https' name='file'>\n"
+                          "  <host name='example.com' port='432'/>\n"
+                          "</source>\n");
++    TEST_JSON_FORMAT_NET("<source protocol='https' name='file'>\n"
++                         "  <host name='example.com' port='432'/>\n"
++                         "  <ssl verify='no'/>\n"
++                         "  <readahead size='1024'/>\n"
++                         "  <timeout seconds='1337'/>\n"
++                         "</source>\n");
+     TEST_JSON_FORMAT_NET("<source protocol='gluster' name='vol/file'>\n"
+                          "  <host name='example.com' port='24007'/>\n"
+                          "</source>\n");
+diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
+index e7794d6168..63b991eb71 100644
+--- a/tests/virstoragetest.c
++++ b/tests/virstoragetest.c
+@@ -1606,6 +1606,21 @@ mymain(void)
+                             "  </slices>\n"
+                             "</source>\n", 0);
+ 
++    TEST_BACKING_PARSE_FULL("json:{ \"file.cookie\": \"vmware_soap_session=\\\"0c8db85112873a79b7ef74f294cb70ef7f\\\"\","
++                                   "\"file.sslverify\": false,"
++                                   "\"file.driver\": \"https\","
++                                   "\"file.url\": \"https://host/folder/esx6.5-rhel7.7-x86%5f64/esx6.5-rhel7.7-x86%5f64-flat.vmdk?dcPath=data&dsName=esx6.5-matrix\","
++                                   "\"file.timeout\": 2000"
++                                 "}",
++                           "<source protocol='https' name='folder/esx6.5-rhel7.7-x86_64/esx6.5-rhel7.7-x86_64-flat.vmdk'>\n"
++                           "  <host name='host' port='443'/>\n"
++                           "  <ssl verify='no'/>\n"
++                           "  <cookies>\n"
++                           "    <cookie name='vmware_soap_session'>&quot;0c8db85112873a79b7ef74f294cb70ef7f&quot;</cookie>\n"
++                           "  </cookies>\n"
++                           "  <timeout seconds='2000'/>\n"
++                           "</source>\n", 0);
++
+ #endif /* WITH_YAJL */
+ 
+  cleanup:
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-vmx-make-fileName-optional-for-CD-ROMs.patch b/SOURCES/libvirt-vmx-make-fileName-optional-for-CD-ROMs.patch
new file mode 100644
index 0000000..1171d7a
--- /dev/null
+++ b/SOURCES/libvirt-vmx-make-fileName-optional-for-CD-ROMs.patch
@@ -0,0 +1,196 @@
+From f600a3df720e1d68c621e739acbed0554f5f5fb0 Mon Sep 17 00:00:00 2001
+Message-Id: <f600a3df720e1d68c621e739acbed0554f5f5fb0@dist-git>
+From: Pino Toscano <ptoscano@redhat.com>
+Date: Fri, 20 Mar 2020 13:25:39 +0100
+Subject: [PATCH] vmx: make 'fileName' optional for CD-ROMs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It seems like CD-ROMs may have no 'fileName' property specified in case
+there is nothing configured as attachment for the drive. Hence, make
+sure that virVMXParseDisk() do not consider it mandatory anymore,
+considering it an empty block cdrom device. Sadly virVMXParseDisk() is
+used also to parse disk and floppies, so make sure that a NULL fileName
+is handled in cdrom- and floppy-related paths.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808610
+
+Signed-off-by: Pino Toscano <ptoscano@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Tested-by: Richard W.M. Jones <rjones@redhat.com>
+(cherry picked from commit c5ee737bc5c0fc61451e45ff41526270bdf0113c)
+Signed-off-by: Pino Toscano <ptoscano@redhat.com>
+Message-Id: <20200320122539.141785-3-ptoscano@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/vmx/vmx.c                                 | 25 ++++++++++---------
+ .../vmx2xmldata/vmx2xml-cdrom-ide-empty-2.vmx |  4 +++
+ .../vmx2xmldata/vmx2xml-cdrom-ide-empty-2.xml | 23 +++++++++++++++++
+ tests/vmx2xmltest.c                           |  1 +
+ 4 files changed, 41 insertions(+), 12 deletions(-)
+ create mode 100644 tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.vmx
+ create mode 100644 tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.xml
+
+diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
+index fc4fa1c22b..d0bcb9c2de 100644
+--- a/src/vmx/vmx.c
++++ b/src/vmx/vmx.c
+@@ -2206,7 +2206,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+         goto cleanup;
+ 
+     /* vmx:fileName -> def:src, def:type */
+-    if (virVMXGetConfigString(conf, fileName_name, &fileName, false) < 0)
++    if (virVMXGetConfigString(conf, fileName_name, &fileName, true) < 0)
+         goto cleanup;
+ 
+     /* vmx:writeThrough -> def:cachemode */
+@@ -2217,7 +2217,8 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+ 
+     /* Setup virDomainDiskDef */
+     if (device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+-        if (virStringHasCaseSuffix(fileName, ".iso") ||
++        if (fileName == NULL ||
++            virStringHasCaseSuffix(fileName, ".iso") ||
+             STREQ(fileName, "emptyBackingString") ||
+             (deviceType &&
+              (STRCASEEQ(deviceType, "atapi-cdrom") ||
+@@ -2276,7 +2277,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             goto cleanup;
+         }
+     } else if (device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+-        if (virStringHasCaseSuffix(fileName, ".vmdk")) {
++        if (fileName && virStringHasCaseSuffix(fileName, ".vmdk")) {
+             /*
+              * This function was called in order to parse a CDROM device, but
+              * .vmdk files are for harddisk devices only. Just ignore it,
+@@ -2284,7 +2285,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+              * handle it.
+              */
+             goto ignore;
+-        } else if (virStringHasCaseSuffix(fileName, ".iso")) {
++        } else if (fileName && virStringHasCaseSuffix(fileName, ".iso")) {
+             char *tmp;
+ 
+             if (deviceType && STRCASENEQ(deviceType, "cdrom-image")) {
+@@ -2305,7 +2306,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+         } else if (deviceType && STRCASEEQ(deviceType, "atapi-cdrom")) {
+             virDomainDiskSetType(*def, VIR_STORAGE_TYPE_BLOCK);
+ 
+-            if (STRCASEEQ(fileName, "auto detect")) {
++            if (fileName && STRCASEEQ(fileName, "auto detect")) {
+                 ignore_value(virDomainDiskSetSource(*def, NULL));
+                 (*def)->startupPolicy = VIR_DOMAIN_STARTUP_POLICY_OPTIONAL;
+             } else if (virDomainDiskSetSource(*def, fileName) < 0) {
+@@ -2316,7 +2317,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             (*def)->device = VIR_DOMAIN_DISK_DEVICE_LUN;
+             virDomainDiskSetType(*def, VIR_STORAGE_TYPE_BLOCK);
+ 
+-            if (STRCASEEQ(fileName, "auto detect")) {
++            if (fileName && STRCASEEQ(fileName, "auto detect")) {
+                 ignore_value(virDomainDiskSetSource(*def, NULL));
+                 (*def)->startupPolicy = VIR_DOMAIN_STARTUP_POLICY_OPTIONAL;
+             } else if (virDomainDiskSetSource(*def, fileName) < 0) {
+@@ -2324,7 +2325,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             }
+         } else if (busType == VIR_DOMAIN_DISK_BUS_SCSI &&
+                    deviceType && STRCASEEQ(deviceType, "scsi-passthru")) {
+-            if (STRPREFIX(fileName, "/vmfs/devices/cdrom/")) {
++            if (fileName && STRPREFIX(fileName, "/vmfs/devices/cdrom/")) {
+                 /* SCSI-passthru CD-ROMs actually are device='lun' */
+                 (*def)->device = VIR_DOMAIN_DISK_DEVICE_LUN;
+                 virDomainDiskSetType(*def, VIR_STORAGE_TYPE_BLOCK);
+@@ -2340,7 +2341,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+                  */
+                 goto ignore;
+             }
+-        } else if (STREQ(fileName, "emptyBackingString")) {
++        } else if (fileName && STREQ(fileName, "emptyBackingString")) {
+             if (deviceType && STRCASENEQ(deviceType, "cdrom-image")) {
+                 virReportError(VIR_ERR_INTERNAL_ERROR,
+                                _("Expecting VMX entry '%s' to be 'cdrom-image' "
+@@ -2354,7 +2355,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             virReportError(VIR_ERR_INTERNAL_ERROR,
+                            _("Invalid or not yet handled value '%s' "
+                              "for VMX entry '%s' for device type '%s'"),
+-                           fileName, fileName_name,
++                           NULLSTR(fileName), fileName_name,
+                            deviceType ? deviceType : "unknown");
+             goto cleanup;
+         }
+@@ -2364,10 +2365,10 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             if (virDomainDiskSetSource(*def, fileName) < 0)
+                 goto cleanup;
+         } else if (fileType != NULL && STRCASEEQ(fileType, "file")) {
+-            char *tmp;
++            char *tmp = NULL;
+ 
+             virDomainDiskSetType(*def, VIR_STORAGE_TYPE_FILE);
+-            if (!(tmp = ctx->parseFileName(fileName, ctx->opaque)))
++            if (fileName && !(tmp = ctx->parseFileName(fileName, ctx->opaque)))
+                 goto cleanup;
+             if (virDomainDiskSetSource(*def, tmp) < 0) {
+                 VIR_FREE(tmp);
+@@ -2378,7 +2379,7 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             virReportError(VIR_ERR_INTERNAL_ERROR,
+                            _("Invalid or not yet handled value '%s' "
+                              "for VMX entry '%s' for device type '%s'"),
+-                           fileName, fileName_name,
++                           NULLSTR(fileName), fileName_name,
+                            deviceType ? deviceType : "unknown");
+             goto cleanup;
+         }
+diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.vmx b/tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.vmx
+new file mode 100644
+index 0000000000..36286cb20f
+--- /dev/null
++++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.vmx
+@@ -0,0 +1,4 @@
++config.version = "8"
++virtualHW.version = "4"
++ide0:0.present = "true"
++ide0:0.deviceType = "atapi-cdrom"
+diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.xml b/tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.xml
+new file mode 100644
+index 0000000000..af4a5ff9f6
+--- /dev/null
++++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-empty-2.xml
+@@ -0,0 +1,23 @@
++<domain type='vmware'>
++  <uuid>00000000-0000-0000-0000-000000000000</uuid>
++  <memory unit='KiB'>32768</memory>
++  <currentMemory unit='KiB'>32768</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <os>
++    <type arch='i686'>hvm</type>
++  </os>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>destroy</on_crash>
++  <devices>
++    <disk type='block' device='cdrom'>
++      <target dev='hda' bus='ide'/>
++      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
++    </disk>
++    <controller type='ide' index='0'/>
++    <video>
++      <model type='vmvga' vram='4096' primary='yes'/>
++    </video>
++  </devices>
++</domain>
+diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
+index 8d7b8ba2a4..1966aed6fe 100644
+--- a/tests/vmx2xmltest.c
++++ b/tests/vmx2xmltest.c
+@@ -218,6 +218,7 @@ mymain(void)
+     DO_TEST("cdrom-scsi-passthru", "cdrom-scsi-passthru");
+     DO_TEST("cdrom-ide-file", "cdrom-ide-file");
+     DO_TEST("cdrom-ide-empty", "cdrom-ide-empty");
++    DO_TEST("cdrom-ide-empty-2", "cdrom-ide-empty-2");
+     DO_TEST("cdrom-ide-device", "cdrom-ide-device");
+     DO_TEST("cdrom-ide-raw-device", "cdrom-ide-raw-device");
+     DO_TEST("cdrom-ide-raw-auto-detect", "cdrom-ide-raw-auto-detect");
+-- 
+2.25.1
+
diff --git a/SOURCES/libvirt-vmx-shortcut-earlier-few-ignore-cases-in-virVMXParseDisk.patch b/SOURCES/libvirt-vmx-shortcut-earlier-few-ignore-cases-in-virVMXParseDisk.patch
new file mode 100644
index 0000000..0f4137a
--- /dev/null
+++ b/SOURCES/libvirt-vmx-shortcut-earlier-few-ignore-cases-in-virVMXParseDisk.patch
@@ -0,0 +1,109 @@
+From e8bd352038f46facdb4891d4df109a3c6351479c Mon Sep 17 00:00:00 2001
+Message-Id: <e8bd352038f46facdb4891d4df109a3c6351479c@dist-git>
+From: Pino Toscano <ptoscano@redhat.com>
+Date: Fri, 20 Mar 2020 13:25:38 +0100
+Subject: [PATCH] vmx: shortcut earlier few 'ignore' cases in virVMXParseDisk()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move earlier the checks for skipping a hard disk when parsing a CD-DROM,
+and for skipping a CD-ROM when parsing a hard disk. This should have no
+behaviour changes, and avoids to add repeated checks in following
+commits.
+
+Signed-off-by: Pino Toscano <ptoscano@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Tested-by: Richard W.M. Jones <rjones@redhat.com>
+https://bugzilla.redhat.com/show_bug.cgi?id=1808610
+(cherry picked from commit 9a469c0d358bf3fd4b4e55b20360620d6fda44b5)
+Signed-off-by: Pino Toscano <ptoscano@redhat.com>
+Message-Id: <20200320122539.141785-2-ptoscano@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/vmx/vmx.c | 48 ++++++++++++++++++++++++------------------------
+ 1 file changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
+index 4362da6cee..fc4fa1c22b 100644
+--- a/src/vmx/vmx.c
++++ b/src/vmx/vmx.c
+@@ -2217,7 +2217,21 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+ 
+     /* Setup virDomainDiskDef */
+     if (device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+-        if (virStringHasCaseSuffix(fileName, ".vmdk")) {
++        if (virStringHasCaseSuffix(fileName, ".iso") ||
++            STREQ(fileName, "emptyBackingString") ||
++            (deviceType &&
++             (STRCASEEQ(deviceType, "atapi-cdrom") ||
++              STRCASEEQ(deviceType, "cdrom-raw") ||
++              (STRCASEEQ(deviceType, "scsi-passthru") &&
++               STRPREFIX(fileName, "/vmfs/devices/cdrom/"))))) {
++            /*
++             * This function was called in order to parse a harddisk device,
++             * but .iso files, 'atapi-cdrom', 'cdrom-raw', and 'scsi-passthru'
++             * CDROM devices are for CDROM devices only. Just ignore it, another
++             * call to this function to parse a CDROM device may handle it.
++             */
++            goto ignore;
++        } else if (virStringHasCaseSuffix(fileName, ".vmdk")) {
+             char *tmp;
+ 
+             if (deviceType != NULL) {
+@@ -2253,20 +2267,6 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             if (mode)
+                 (*def)->transient = STRCASEEQ(mode,
+                                               "independent-nonpersistent");
+-        } else if (virStringHasCaseSuffix(fileName, ".iso") ||
+-                   STREQ(fileName, "emptyBackingString") ||
+-                   (deviceType &&
+-                    (STRCASEEQ(deviceType, "atapi-cdrom") ||
+-                     STRCASEEQ(deviceType, "cdrom-raw") ||
+-                     (STRCASEEQ(deviceType, "scsi-passthru") &&
+-                      STRPREFIX(fileName, "/vmfs/devices/cdrom/"))))) {
+-            /*
+-             * This function was called in order to parse a harddisk device,
+-             * but .iso files, 'atapi-cdrom', 'cdrom-raw', and 'scsi-passthru'
+-             * CDROM devices are for CDROM devices only. Just ignore it, another
+-             * call to this function to parse a CDROM device may handle it.
+-             */
+-            goto ignore;
+         } else {
+             virReportError(VIR_ERR_INTERNAL_ERROR,
+                            _("Invalid or not yet handled value '%s' "
+@@ -2276,7 +2276,15 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+             goto cleanup;
+         }
+     } else if (device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+-        if (virStringHasCaseSuffix(fileName, ".iso")) {
++        if (virStringHasCaseSuffix(fileName, ".vmdk")) {
++            /*
++             * This function was called in order to parse a CDROM device, but
++             * .vmdk files are for harddisk devices only. Just ignore it,
++             * another call to this function to parse a harddisk device may
++             * handle it.
++             */
++            goto ignore;
++        } else if (virStringHasCaseSuffix(fileName, ".iso")) {
+             char *tmp;
+ 
+             if (deviceType && STRCASENEQ(deviceType, "cdrom-image")) {
+@@ -2294,14 +2302,6 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
+                 goto cleanup;
+             }
+             VIR_FREE(tmp);
+-        } else if (virStringHasCaseSuffix(fileName, ".vmdk")) {
+-            /*
+-             * This function was called in order to parse a CDROM device, but
+-             * .vmdk files are for harddisk devices only. Just ignore it,
+-             * another call to this function to parse a harddisk device may
+-             * handle it.
+-             */
+-            goto ignore;
+         } else if (deviceType && STRCASEEQ(deviceType, "atapi-cdrom")) {
+             virDomainDiskSetType(*def, VIR_STORAGE_TYPE_BLOCK);
+ 
+-- 
+2.25.1
+
diff --git a/SOURCES/symlinks b/SOURCES/symlinks
new file mode 100644
index 0000000..8ddd1c3
--- /dev/null
+++ b/SOURCES/symlinks
@@ -0,0 +1,980 @@
+ABOUT-NLS po/README.md
+README README.md
+.ctags.d/libvirt.ctags ../.ctags
+tests/virt-admin-self-test ./virsh-self-test
+tests/qemublocktestdata/imagecreate/qcow2-backing-luks.xml qcow2.xml
+tests/qemublocktestdata/imagecreate/qcow2-backing-raw-nbd.xml qcow2.xml
+tests/qemublocktestdata/imagecreate/qcow2-backing-raw.xml qcow2.xml
+tests/qemublocktestdata/imagecreate/qcow2-luks-encopts-backing.xml qcow2-luks-encopts.xml
+tests/qemufirmwaredata/etc/qemu/firmware/40-ovmf-sb-keys.json ../../../usr/share/qemu/firmware/50-ovmf-sb-keys.json
+tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell-detach.xml qemuhotplug-base-live+ivshmem-plain.xml
+tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain-detach.xml qemuhotplug-base-live.xml
+tests/qemustatusxml2xmldata/backup-pull-out.xml backup-pull-in.xml
+tests/qemustatusxml2xmldata/blockjob-blockdev-out.xml blockjob-blockdev-in.xml
+tests/qemustatusxml2xmldata/blockjob-mirror-out.xml blockjob-mirror-in.xml
+tests/qemustatusxml2xmldata/migration-in-params-out.xml migration-in-params-in.xml
+tests/qemustatusxml2xmldata/migration-out-params-out.xml migration-out-params-in.xml
+tests/qemustatusxml2xmldata/modern-out.xml modern-in.xml
+tests/qemustatusxml2xmldata/vcpus-multi-out.xml vcpus-multi-in.xml
+tests/qemuvhostuserdata/etc/qemu/vhost-user/40-gpu.json ../../../usr/share/qemu/vhost-user/50-gpu.json
+tests/qemuvhostuserdata/usr/share/qemu/vhost-user/30-gpu.json 50-gpu.json
+tests/qemuvhostuserdata/usr/share/qemu/vhost-user/60-gpu.json 50-gpu.json
+tests/qemuxml2argvdata/aarch64-gic-default-both.args aarch64-gic-v3.args
+tests/qemuxml2argvdata/aarch64-gic-default-both.xml aarch64-gic-default.xml
+tests/qemuxml2argvdata/aarch64-gic-default-v2.args aarch64-gic-v2.args
+tests/qemuxml2argvdata/aarch64-gic-default-v2.xml aarch64-gic-default.xml
+tests/qemuxml2argvdata/aarch64-gic-default-v3.args aarch64-gic-v3.args
+tests/qemuxml2argvdata/aarch64-gic-default-v3.xml aarch64-gic-default.xml
+tests/qemuxml2argvdata/aarch64-gic-default.args aarch64-gic-v2.args
+tests/qemuxml2argvdata/aarch64-gic-none-both.args aarch64-gic-v3.args
+tests/qemuxml2argvdata/aarch64-gic-none-both.xml aarch64-gic-none.xml
+tests/qemuxml2argvdata/aarch64-gic-none-v2.args aarch64-gic-v2.args
+tests/qemuxml2argvdata/aarch64-gic-none-v2.xml aarch64-gic-none.xml
+tests/qemuxml2argvdata/aarch64-gic-none-v3.args aarch64-gic-v3.args
+tests/qemuxml2argvdata/aarch64-gic-none-v3.xml aarch64-gic-none-v2.xml
+tests/qemuxml2argvdata/aarch64-gic-none.args aarch64-gic-v2.args
+tests/qemuxml2argvdata/cpu-check-full.args cpu-check-none.args
+tests/qemuxml2argvdata/cpu-check-partial.args cpu-check-none.args
+tests/qemuxml2argvdata/disk-backing-chains-index.x86_64-2.12.0.args disk-backing-chains-noindex.x86_64-2.12.0.args
+tests/qemuxml2argvdata/disk-backing-chains-index.x86_64-latest.args disk-backing-chains-noindex.x86_64-latest.args
+tests/qemuxml2argvdata/mach-virt-console-native.args mach-virt-serial-native.args
+tests/qemuxml2argvdata/mach-virt-serial+console-native.args mach-virt-serial-native.args
+tests/qemuxml2argvdata/mach-virt-serial-compat.args mach-virt-serial-native.args
+tests/qemuxml2argvdata/pci-rom-disabled-invalid.args pci-rom-disabled.args
+tests/qemuxml2argvdata/ppc64-usb-controller-legacy.xml ppc64-usb-controller.xml
+tests/qemuxml2argvdata/ppc64-usb-controller-qemu-xhci.xml ppc64-usb-controller.xml
+tests/qemuxml2argvdata/pseries-console-native.args pseries-serial-native.args
+tests/qemuxml2argvdata/pseries-serial+console-native.args pseries-serial-native.args
+tests/qemuxml2argvdata/pseries-serial-compat.args pseries-serial-native.args
+tests/qemuxml2argvdata/q35-virtio-pci.xml q35-pcie.xml
+tests/qemuxml2argvdata/usb-controller-default-unavailable-q35.xml usb-controller-default-q35.xml
+tests/qemuxml2argvdata/usb-controller-explicit-unavailable-q35.xml usb-controller-explicit-q35.xml
+tests/qemuxml2argvdata/usb-controller-qemu-xhci-unavailable.xml usb-controller-qemu-xhci.xml
+tests/qemuxml2argvdata/user-aliases2.args boot-floppy-q35.args
+tests/qemuxml2xmloutdata/aarch64-gic-default-both.xml ../qemuxml2argvdata/aarch64-gic-v3.xml
+tests/qemuxml2xmloutdata/aarch64-gic-default-v2.xml ../qemuxml2argvdata/aarch64-gic-v2.xml
+tests/qemuxml2xmloutdata/aarch64-gic-default-v3.xml ../qemuxml2argvdata/aarch64-gic-v3.xml
+tests/qemuxml2xmloutdata/aarch64-gic-default.xml ../qemuxml2argvdata/aarch64-gic-v2.xml
+tests/qemuxml2xmloutdata/aarch64-gic-host.xml ../qemuxml2argvdata/aarch64-gic-host.xml
+tests/qemuxml2xmloutdata/aarch64-gic-none-both.xml ../qemuxml2argvdata/aarch64-gic-v3.xml
+tests/qemuxml2xmloutdata/aarch64-gic-none-v2.xml ../qemuxml2argvdata/aarch64-gic-v2.xml
+tests/qemuxml2xmloutdata/aarch64-gic-none-v3.xml ../qemuxml2argvdata/aarch64-gic-v3.xml
+tests/qemuxml2xmloutdata/aarch64-gic-none.xml ../qemuxml2argvdata/aarch64-gic-v2.xml
+tests/qemuxml2xmloutdata/aarch64-gic-v2.xml ../qemuxml2argvdata/aarch64-gic-v2.xml
+tests/qemuxml2xmloutdata/aarch64-gic-v3.xml ../qemuxml2argvdata/aarch64-gic-v3.xml
+tests/qemuxml2xmloutdata/blkdeviotune-group-num.xml ../qemuxml2argvdata/blkdeviotune-group-num.xml
+tests/qemuxml2xmloutdata/blkdeviotune-max-length.xml ../qemuxml2argvdata/blkdeviotune-max-length.xml
+tests/qemuxml2xmloutdata/blkdeviotune-max.xml ../qemuxml2argvdata/blkdeviotune-max.xml
+tests/qemuxml2xmloutdata/boot-floppy-q35.xml ../qemuxml2argvdata/boot-floppy-q35.xml
+tests/qemuxml2xmloutdata/disk-detect-zeroes.xml ../qemuxml2argvdata/disk-detect-zeroes.xml
+tests/qemuxml2xmloutdata/disk-nvme.xml ../qemuxml2argvdata/disk-nvme.xml
+tests/qemuxml2xmloutdata/disk-virtio-queues.xml ../qemuxml2argvdata/disk-virtio-queues.xml
+tests/qemuxml2xmloutdata/disk-virtio-scsi-reservations.xml ../qemuxml2argvdata/disk-virtio-scsi-reservations.xml
+tests/qemuxml2xmloutdata/encrypted-disk-usage.xml ../qemuxml2argvdata/encrypted-disk-usage.xml
+tests/qemuxml2xmloutdata/fd-memory-no-numa-topology.xml ../qemuxml2argvdata/fd-memory-no-numa-topology.xml
+tests/qemuxml2xmloutdata/fd-memory-numa-topology.xml ../qemuxml2argvdata/fd-memory-numa-topology.xml
+tests/qemuxml2xmloutdata/fd-memory-numa-topology2.xml ../qemuxml2argvdata/fd-memory-numa-topology2.xml
+tests/qemuxml2xmloutdata/fd-memory-numa-topology3.xml ../qemuxml2argvdata/fd-memory-numa-topology3.xml
+tests/qemuxml2xmloutdata/hugepages-default-2M.xml ../qemuxml2argvdata/hugepages-default-2M.xml
+tests/qemuxml2xmloutdata/hugepages-default-system-size.xml ../qemuxml2argvdata/hugepages-default-system-size.xml
+tests/qemuxml2xmloutdata/hugepages-memaccess.xml ../qemuxml2argvdata/hugepages-memaccess.xml
+tests/qemuxml2xmloutdata/hugepages-memaccess2.xml ../qemuxml2argvdata/hugepages-memaccess2.xml
+tests/qemuxml2xmloutdata/hugepages-numa-default-dimm.xml ../qemuxml2argvdata/hugepages-numa-default-dimm.xml
+tests/qemuxml2xmloutdata/hugepages-nvdimm.xml ../qemuxml2argvdata/hugepages-nvdimm.xml
+tests/qemuxml2xmloutdata/intel-iommu-caching-mode.x86_64-latest.xml ../qemuxml2argvdata/intel-iommu-caching-mode.xml
+tests/qemuxml2xmloutdata/intel-iommu-device-iotlb.x86_64-latest.xml ../qemuxml2argvdata/intel-iommu-device-iotlb.xml
+tests/qemuxml2xmloutdata/intel-iommu-eim.x86_64-latest.xml ../qemuxml2argvdata/intel-iommu-eim.xml
+tests/qemuxml2xmloutdata/intel-iommu.x86_64-latest.xml ../qemuxml2argvdata/intel-iommu.xml
+tests/qemuxml2xmloutdata/luks-disks.xml ../qemuxml2argvdata/luks-disks.xml
+tests/qemuxml2xmloutdata/mach-virt-console-native.xml mach-virt-serial-compat.xml
+tests/qemuxml2xmloutdata/mach-virt-serial+console-native.xml mach-virt-serial-compat.xml
+tests/qemuxml2xmloutdata/mach-virt-serial-native.xml mach-virt-serial-compat.xml
+tests/qemuxml2xmloutdata/memfd-memory-default-hugepage.xml ../qemuxml2argvdata/memfd-memory-default-hugepage.xml
+tests/qemuxml2xmloutdata/memfd-memory-numa.xml ../qemuxml2argvdata/memfd-memory-numa.xml
+tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-access.xml ../qemuxml2argvdata/memory-hotplug-nvdimm-access.xml
+tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-align.xml ../qemuxml2argvdata/memory-hotplug-nvdimm-align.xml
+tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-label.xml ../qemuxml2argvdata/memory-hotplug-nvdimm-label.xml
+tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-pmem.xml ../qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml
+tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-readonly.xml ../qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml
+tests/qemuxml2xmloutdata/memory-hotplug-nvdimm.xml ../qemuxml2argvdata/memory-hotplug-nvdimm.xml
+tests/qemuxml2xmloutdata/net-user-addr.xml ../qemuxml2argvdata/net-user-addr.xml
+tests/qemuxml2xmloutdata/pages-dimm-discard.xml ../qemuxml2argvdata/pages-dimm-discard.xml
+tests/qemuxml2xmloutdata/pages-discard-hugepages.xml ../qemuxml2argvdata/pages-discard-hugepages.xml
+tests/qemuxml2xmloutdata/pages-discard.xml ../qemuxml2argvdata/pages-discard.xml
+tests/qemuxml2xmloutdata/pseries-console-native.xml pseries-serial-native.xml
+tests/qemuxml2xmloutdata/pseries-serial+console-native.xml pseries-serial-native.xml
+tests/qemuxml2xmloutdata/pseries-serial-compat.xml pseries-serial-native.xml
+tests/qemuxml2xmloutdata/serial-tcp-tlsx509-chardev-notls.xml ../qemuxml2argvdata/serial-tcp-tlsx509-chardev-notls.xml
+tests/qemuxml2xmloutdata/user-aliases.xml ../qemuxml2argvdata/user-aliases.xml
+tests/qemuxml2xmloutdata/vcpu-placement-static.xml ../qemuxml2argvdata/vcpu-placement-static.xml
+tests/qemuxml2xmloutdata/vhost-vsock-ccw.xml ../qemuxml2argvdata/vhost-vsock-ccw.xml
+tests/qemuxml2xmloutdata/vhost-vsock.xml ../qemuxml2argvdata/vhost-vsock.xml
+tests/qemuxml2xmloutdata/virtio-options.xml ../qemuxml2argvdata/virtio-options.xml
+tests/vircaps2xmldata/linux-basic/system/node/node0/cpu0 ../../cpu/cpu0
+tests/vircaps2xmldata/linux-basic/system/node/node0/cpu1 ../../cpu/cpu1
+tests/vircaps2xmldata/linux-basic/system/node/node0/cpu2 ../../cpu/cpu2
+tests/vircaps2xmldata/linux-basic/system/node/node0/cpu3 ../../cpu/cpu3
+tests/vircaps2xmldata/linux-basic/system/node/node1/cpu4 ../../cpu/cpu4
+tests/vircaps2xmldata/linux-basic/system/node/node1/cpu5 ../../cpu/cpu5
+tests/vircaps2xmldata/linux-basic/system/node/node1/cpu6 ../../cpu/cpu6
+tests/vircaps2xmldata/linux-basic/system/node/node1/cpu7 ../../cpu/cpu7
+tests/vircaps2xmldata/linux-basic/system/node/node2/cpu10 ../../cpu/cpu10
+tests/vircaps2xmldata/linux-basic/system/node/node2/cpu11 ../../cpu/cpu11
+tests/vircaps2xmldata/linux-basic/system/node/node2/cpu8 ../../cpu/cpu8
+tests/vircaps2xmldata/linux-basic/system/node/node2/cpu9 ../../cpu/cpu9
+tests/vircaps2xmldata/linux-basic/system/node/node3/cpu12 ../../cpu/cpu12
+tests/vircaps2xmldata/linux-basic/system/node/node3/cpu13 ../../cpu/cpu13
+tests/vircaps2xmldata/linux-basic/system/node/node3/cpu14 ../../cpu/cpu14
+tests/vircaps2xmldata/linux-basic/system/node/node3/cpu15 ../../cpu/cpu15
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu0 ../../cpu/cpu0
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu1 ../../cpu/cpu1
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu2 ../../cpu/cpu2
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu3 ../../cpu/cpu3
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu4 ../../cpu/cpu4
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu5 ../../cpu/cpu5
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu6 ../../cpu/cpu6
+tests/vircaps2xmldata/linux-caches/system/node/node0/cpu7 ../../cpu/cpu7
+tests/vircaps2xmldata/linux-resctrl-cdp/system ../linux-resctrl/system/
+tests/vircaps2xmldata/linux-resctrl-cmt/system ../linux-resctrl/system
+tests/vircaps2xmldata/linux-resctrl-fake-feature/system ../linux-resctrl/system
+tests/vircaps2xmldata/linux-resctrl-skx-twocaches/system/node/node0/cpu0 ../../cpu/cpu0
+tests/vircaps2xmldata/linux-resctrl-skx/system/node/node0/cpu0 ../../cpu/cpu0
+tests/vircaps2xmldata/linux-resctrl/system/node/node0/cpu0 ../../cpu/cpu0
+tests/vircaps2xmldata/linux-resctrl/system/node/node0/cpu1 ../../cpu/cpu1
+tests/vircaps2xmldata/linux-resctrl/system/node/node0/cpu2 ../../cpu/cpu2
+tests/vircaps2xmldata/linux-resctrl/system/node/node0/cpu3 ../../cpu/cpu3
+tests/vircaps2xmldata/linux-resctrl/system/node/node0/cpu4 ../../cpu/cpu4
+tests/vircaps2xmldata/linux-resctrl/system/node/node0/cpu5 ../../cpu/cpu5
+tests/vircaps2xmldata/linux-resctrl/system/node/node1/cpu10 ../../cpu/cpu10
+tests/vircaps2xmldata/linux-resctrl/system/node/node1/cpu11 ../../cpu/cpu11
+tests/vircaps2xmldata/linux-resctrl/system/node/node1/cpu6 ../../cpu/cpu6
+tests/vircaps2xmldata/linux-resctrl/system/node/node1/cpu7 ../../cpu/cpu7
+tests/vircaps2xmldata/linux-resctrl/system/node/node1/cpu8 ../../cpu/cpu8
+tests/vircaps2xmldata/linux-resctrl/system/node/node1/cpu9 ../../cpu/cpu9
+tests/virfilecachedata/9ca150bf3119b75dcac8e8bae4bc3a28e75bc3e262757001e8b953580f5e75ef.cache 5f3154560c130108b282a2aa15b1658aa16923e46497dd8deeb6be287ddb0ca0.cache
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu100 ../../cpu/cpu100
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu101 ../../cpu/cpu101
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu102 ../../cpu/cpu102
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu103 ../../cpu/cpu103
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu144 ../../cpu/cpu144
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu145 ../../cpu/cpu145
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu146 ../../cpu/cpu146
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu147 ../../cpu/cpu147
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu148 ../../cpu/cpu148
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu149 ../../cpu/cpu149
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu150 ../../cpu/cpu150
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu151 ../../cpu/cpu151
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu152 ../../cpu/cpu152
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu153 ../../cpu/cpu153
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu154 ../../cpu/cpu154
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu155 ../../cpu/cpu155
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu156 ../../cpu/cpu156
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu157 ../../cpu/cpu157
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu158 ../../cpu/cpu158
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu159 ../../cpu/cpu159
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu16 ../../cpu/cpu16
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu17 ../../cpu/cpu17
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu18 ../../cpu/cpu18
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu19 ../../cpu/cpu19
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu20 ../../cpu/cpu20
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu21 ../../cpu/cpu21
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu22 ../../cpu/cpu22
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu23 ../../cpu/cpu23
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu24 ../../cpu/cpu24
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu25 ../../cpu/cpu25
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu26 ../../cpu/cpu26
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu27 ../../cpu/cpu27
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu28 ../../cpu/cpu28
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu29 ../../cpu/cpu29
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu30 ../../cpu/cpu30
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu31 ../../cpu/cpu31
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu32 ../../cpu/cpu32
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu33 ../../cpu/cpu33
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu34 ../../cpu/cpu34
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu35 ../../cpu/cpu35
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu36 ../../cpu/cpu36
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu37 ../../cpu/cpu37
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu38 ../../cpu/cpu38
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu39 ../../cpu/cpu39
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu56 ../../cpu/cpu56
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu57 ../../cpu/cpu57
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu58 ../../cpu/cpu58
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu59 ../../cpu/cpu59
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu60 ../../cpu/cpu60
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu61 ../../cpu/cpu61
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu62 ../../cpu/cpu62
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu63 ../../cpu/cpu63
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu64 ../../cpu/cpu64
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu65 ../../cpu/cpu65
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu66 ../../cpu/cpu66
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu67 ../../cpu/cpu67
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu68 ../../cpu/cpu68
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu69 ../../cpu/cpu69
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu70 ../../cpu/cpu70
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu71 ../../cpu/cpu71
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu80 ../../cpu/cpu80
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu81 ../../cpu/cpu81
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu82 ../../cpu/cpu82
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu83 ../../cpu/cpu83
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu84 ../../cpu/cpu84
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu85 ../../cpu/cpu85
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu86 ../../cpu/cpu86
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu87 ../../cpu/cpu87
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu88 ../../cpu/cpu88
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu89 ../../cpu/cpu89
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu90 ../../cpu/cpu90
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu91 ../../cpu/cpu91
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu92 ../../cpu/cpu92
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu93 ../../cpu/cpu93
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu94 ../../cpu/cpu94
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu95 ../../cpu/cpu95
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu96 ../../cpu/cpu96
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu97 ../../cpu/cpu97
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu98 ../../cpu/cpu98
+tests/virhostcpudata/linux-deconf-cpus/node/node0/cpu99 ../../cpu/cpu99
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu40 ../../cpu/cpu40
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu41 ../../cpu/cpu41
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu42 ../../cpu/cpu42
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu43 ../../cpu/cpu43
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu44 ../../cpu/cpu44
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu45 ../../cpu/cpu45
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu46 ../../cpu/cpu46
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu47 ../../cpu/cpu47
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu48 ../../cpu/cpu48
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu49 ../../cpu/cpu49
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu50 ../../cpu/cpu50
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu51 ../../cpu/cpu51
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu52 ../../cpu/cpu52
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu53 ../../cpu/cpu53
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu54 ../../cpu/cpu54
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu55 ../../cpu/cpu55
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu72 ../../cpu/cpu72
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu73 ../../cpu/cpu73
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu74 ../../cpu/cpu74
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu75 ../../cpu/cpu75
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu76 ../../cpu/cpu76
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu77 ../../cpu/cpu77
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu78 ../../cpu/cpu78
+tests/virhostcpudata/linux-deconf-cpus/node/node1/cpu79 ../../cpu/cpu79
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu104 ../../cpu/cpu104
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu105 ../../cpu/cpu105
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu106 ../../cpu/cpu106
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu107 ../../cpu/cpu107
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu108 ../../cpu/cpu108
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu109 ../../cpu/cpu109
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu110 ../../cpu/cpu110
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu111 ../../cpu/cpu111
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu112 ../../cpu/cpu112
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu113 ../../cpu/cpu113
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu114 ../../cpu/cpu114
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu115 ../../cpu/cpu115
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu116 ../../cpu/cpu116
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu117 ../../cpu/cpu117
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu118 ../../cpu/cpu118
+tests/virhostcpudata/linux-deconf-cpus/node/node16/cpu119 ../../cpu/cpu119
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu120 ../../cpu/cpu120
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu121 ../../cpu/cpu121
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu122 ../../cpu/cpu122
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu123 ../../cpu/cpu123
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu124 ../../cpu/cpu124
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu125 ../../cpu/cpu125
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu126 ../../cpu/cpu126
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu127 ../../cpu/cpu127
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu128 ../../cpu/cpu128
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu129 ../../cpu/cpu129
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu130 ../../cpu/cpu130
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu131 ../../cpu/cpu131
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu132 ../../cpu/cpu132
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu133 ../../cpu/cpu133
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu134 ../../cpu/cpu134
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu135 ../../cpu/cpu135
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu136 ../../cpu/cpu136
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu137 ../../cpu/cpu137
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu138 ../../cpu/cpu138
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu139 ../../cpu/cpu139
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu140 ../../cpu/cpu140
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu141 ../../cpu/cpu141
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu142 ../../cpu/cpu142
+tests/virhostcpudata/linux-deconf-cpus/node/node17/cpu143 ../../cpu/cpu143
+tests/virhostcpudata/linux-high-ids/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-high-ids/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-high-ids/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-high-ids/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-high-ids/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-high-ids/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-high-ids/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-high-ids/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-high-ids/node/node1/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-high-ids/node/node1/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-high-ids/node/node1/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-high-ids/node/node1/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-high-ids/node/node1/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-high-ids/node/node1/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-high-ids/node/node1/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-high-ids/node/node1/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-rhel74-moonshot/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-subcores1/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-subcores1/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-subcores1/node/node0/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-subcores1/node/node0/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-subcores1/node/node0/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-subcores1/node/node0/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-subcores1/node/node0/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-subcores1/node/node0/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-subcores1/node/node0/cpu16 ../../cpu/cpu16
+tests/virhostcpudata/linux-subcores1/node/node0/cpu17 ../../cpu/cpu17
+tests/virhostcpudata/linux-subcores1/node/node0/cpu18 ../../cpu/cpu18
+tests/virhostcpudata/linux-subcores1/node/node0/cpu19 ../../cpu/cpu19
+tests/virhostcpudata/linux-subcores1/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-subcores1/node/node0/cpu20 ../../cpu/cpu20
+tests/virhostcpudata/linux-subcores1/node/node0/cpu21 ../../cpu/cpu21
+tests/virhostcpudata/linux-subcores1/node/node0/cpu22 ../../cpu/cpu22
+tests/virhostcpudata/linux-subcores1/node/node0/cpu23 ../../cpu/cpu23
+tests/virhostcpudata/linux-subcores1/node/node0/cpu24 ../../cpu/cpu24
+tests/virhostcpudata/linux-subcores1/node/node0/cpu25 ../../cpu/cpu25
+tests/virhostcpudata/linux-subcores1/node/node0/cpu26 ../../cpu/cpu26
+tests/virhostcpudata/linux-subcores1/node/node0/cpu27 ../../cpu/cpu27
+tests/virhostcpudata/linux-subcores1/node/node0/cpu28 ../../cpu/cpu28
+tests/virhostcpudata/linux-subcores1/node/node0/cpu29 ../../cpu/cpu29
+tests/virhostcpudata/linux-subcores1/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-subcores1/node/node0/cpu30 ../../cpu/cpu30
+tests/virhostcpudata/linux-subcores1/node/node0/cpu31 ../../cpu/cpu31
+tests/virhostcpudata/linux-subcores1/node/node0/cpu32 ../../cpu/cpu32
+tests/virhostcpudata/linux-subcores1/node/node0/cpu33 ../../cpu/cpu33
+tests/virhostcpudata/linux-subcores1/node/node0/cpu34 ../../cpu/cpu34
+tests/virhostcpudata/linux-subcores1/node/node0/cpu35 ../../cpu/cpu35
+tests/virhostcpudata/linux-subcores1/node/node0/cpu36 ../../cpu/cpu36
+tests/virhostcpudata/linux-subcores1/node/node0/cpu37 ../../cpu/cpu37
+tests/virhostcpudata/linux-subcores1/node/node0/cpu38 ../../cpu/cpu38
+tests/virhostcpudata/linux-subcores1/node/node0/cpu39 ../../cpu/cpu39
+tests/virhostcpudata/linux-subcores1/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-subcores1/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-subcores1/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-subcores1/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-subcores1/node/node0/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-subcores1/node/node0/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-subcores1/node/node1/cpu40 ../../cpu/cpu40
+tests/virhostcpudata/linux-subcores1/node/node1/cpu41 ../../cpu/cpu41
+tests/virhostcpudata/linux-subcores1/node/node1/cpu42 ../../cpu/cpu42
+tests/virhostcpudata/linux-subcores1/node/node1/cpu43 ../../cpu/cpu43
+tests/virhostcpudata/linux-subcores1/node/node1/cpu44 ../../cpu/cpu44
+tests/virhostcpudata/linux-subcores1/node/node1/cpu45 ../../cpu/cpu45
+tests/virhostcpudata/linux-subcores1/node/node1/cpu46 ../../cpu/cpu46
+tests/virhostcpudata/linux-subcores1/node/node1/cpu47 ../../cpu/cpu47
+tests/virhostcpudata/linux-subcores1/node/node1/cpu48 ../../cpu/cpu48
+tests/virhostcpudata/linux-subcores1/node/node1/cpu49 ../../cpu/cpu49
+tests/virhostcpudata/linux-subcores1/node/node1/cpu50 ../../cpu/cpu50
+tests/virhostcpudata/linux-subcores1/node/node1/cpu51 ../../cpu/cpu51
+tests/virhostcpudata/linux-subcores1/node/node1/cpu52 ../../cpu/cpu52
+tests/virhostcpudata/linux-subcores1/node/node1/cpu53 ../../cpu/cpu53
+tests/virhostcpudata/linux-subcores1/node/node1/cpu54 ../../cpu/cpu54
+tests/virhostcpudata/linux-subcores1/node/node1/cpu55 ../../cpu/cpu55
+tests/virhostcpudata/linux-subcores1/node/node1/cpu56 ../../cpu/cpu56
+tests/virhostcpudata/linux-subcores1/node/node1/cpu57 ../../cpu/cpu57
+tests/virhostcpudata/linux-subcores1/node/node1/cpu58 ../../cpu/cpu58
+tests/virhostcpudata/linux-subcores1/node/node1/cpu59 ../../cpu/cpu59
+tests/virhostcpudata/linux-subcores1/node/node1/cpu60 ../../cpu/cpu60
+tests/virhostcpudata/linux-subcores1/node/node1/cpu61 ../../cpu/cpu61
+tests/virhostcpudata/linux-subcores1/node/node1/cpu62 ../../cpu/cpu62
+tests/virhostcpudata/linux-subcores1/node/node1/cpu63 ../../cpu/cpu63
+tests/virhostcpudata/linux-subcores1/node/node1/cpu64 ../../cpu/cpu64
+tests/virhostcpudata/linux-subcores1/node/node1/cpu65 ../../cpu/cpu65
+tests/virhostcpudata/linux-subcores1/node/node1/cpu66 ../../cpu/cpu66
+tests/virhostcpudata/linux-subcores1/node/node1/cpu67 ../../cpu/cpu67
+tests/virhostcpudata/linux-subcores1/node/node1/cpu68 ../../cpu/cpu68
+tests/virhostcpudata/linux-subcores1/node/node1/cpu69 ../../cpu/cpu69
+tests/virhostcpudata/linux-subcores1/node/node1/cpu70 ../../cpu/cpu70
+tests/virhostcpudata/linux-subcores1/node/node1/cpu71 ../../cpu/cpu71
+tests/virhostcpudata/linux-subcores1/node/node1/cpu72 ../../cpu/cpu72
+tests/virhostcpudata/linux-subcores1/node/node1/cpu73 ../../cpu/cpu73
+tests/virhostcpudata/linux-subcores1/node/node1/cpu74 ../../cpu/cpu74
+tests/virhostcpudata/linux-subcores1/node/node1/cpu75 ../../cpu/cpu75
+tests/virhostcpudata/linux-subcores1/node/node1/cpu76 ../../cpu/cpu76
+tests/virhostcpudata/linux-subcores1/node/node1/cpu77 ../../cpu/cpu77
+tests/virhostcpudata/linux-subcores1/node/node1/cpu78 ../../cpu/cpu78
+tests/virhostcpudata/linux-subcores1/node/node1/cpu79 ../../cpu/cpu79
+tests/virhostcpudata/linux-subcores1/node/node16/cpu100 ../../cpu/cpu100
+tests/virhostcpudata/linux-subcores1/node/node16/cpu101 ../../cpu/cpu101
+tests/virhostcpudata/linux-subcores1/node/node16/cpu102 ../../cpu/cpu102
+tests/virhostcpudata/linux-subcores1/node/node16/cpu103 ../../cpu/cpu103
+tests/virhostcpudata/linux-subcores1/node/node16/cpu104 ../../cpu/cpu104
+tests/virhostcpudata/linux-subcores1/node/node16/cpu105 ../../cpu/cpu105
+tests/virhostcpudata/linux-subcores1/node/node16/cpu106 ../../cpu/cpu106
+tests/virhostcpudata/linux-subcores1/node/node16/cpu107 ../../cpu/cpu107
+tests/virhostcpudata/linux-subcores1/node/node16/cpu108 ../../cpu/cpu108
+tests/virhostcpudata/linux-subcores1/node/node16/cpu109 ../../cpu/cpu109
+tests/virhostcpudata/linux-subcores1/node/node16/cpu110 ../../cpu/cpu110
+tests/virhostcpudata/linux-subcores1/node/node16/cpu111 ../../cpu/cpu111
+tests/virhostcpudata/linux-subcores1/node/node16/cpu112 ../../cpu/cpu112
+tests/virhostcpudata/linux-subcores1/node/node16/cpu113 ../../cpu/cpu113
+tests/virhostcpudata/linux-subcores1/node/node16/cpu114 ../../cpu/cpu114
+tests/virhostcpudata/linux-subcores1/node/node16/cpu115 ../../cpu/cpu115
+tests/virhostcpudata/linux-subcores1/node/node16/cpu116 ../../cpu/cpu116
+tests/virhostcpudata/linux-subcores1/node/node16/cpu117 ../../cpu/cpu117
+tests/virhostcpudata/linux-subcores1/node/node16/cpu118 ../../cpu/cpu118
+tests/virhostcpudata/linux-subcores1/node/node16/cpu119 ../../cpu/cpu119
+tests/virhostcpudata/linux-subcores1/node/node16/cpu80 ../../cpu/cpu80
+tests/virhostcpudata/linux-subcores1/node/node16/cpu81 ../../cpu/cpu81
+tests/virhostcpudata/linux-subcores1/node/node16/cpu82 ../../cpu/cpu82
+tests/virhostcpudata/linux-subcores1/node/node16/cpu83 ../../cpu/cpu83
+tests/virhostcpudata/linux-subcores1/node/node16/cpu84 ../../cpu/cpu84
+tests/virhostcpudata/linux-subcores1/node/node16/cpu85 ../../cpu/cpu85
+tests/virhostcpudata/linux-subcores1/node/node16/cpu86 ../../cpu/cpu86
+tests/virhostcpudata/linux-subcores1/node/node16/cpu87 ../../cpu/cpu87
+tests/virhostcpudata/linux-subcores1/node/node16/cpu88 ../../cpu/cpu88
+tests/virhostcpudata/linux-subcores1/node/node16/cpu89 ../../cpu/cpu89
+tests/virhostcpudata/linux-subcores1/node/node16/cpu90 ../../cpu/cpu90
+tests/virhostcpudata/linux-subcores1/node/node16/cpu91 ../../cpu/cpu91
+tests/virhostcpudata/linux-subcores1/node/node16/cpu92 ../../cpu/cpu92
+tests/virhostcpudata/linux-subcores1/node/node16/cpu93 ../../cpu/cpu93
+tests/virhostcpudata/linux-subcores1/node/node16/cpu94 ../../cpu/cpu94
+tests/virhostcpudata/linux-subcores1/node/node16/cpu95 ../../cpu/cpu95
+tests/virhostcpudata/linux-subcores1/node/node16/cpu96 ../../cpu/cpu96
+tests/virhostcpudata/linux-subcores1/node/node16/cpu97 ../../cpu/cpu97
+tests/virhostcpudata/linux-subcores1/node/node16/cpu98 ../../cpu/cpu98
+tests/virhostcpudata/linux-subcores1/node/node16/cpu99 ../../cpu/cpu99
+tests/virhostcpudata/linux-subcores1/node/node17/cpu120 ../../cpu/cpu120
+tests/virhostcpudata/linux-subcores1/node/node17/cpu121 ../../cpu/cpu121
+tests/virhostcpudata/linux-subcores1/node/node17/cpu122 ../../cpu/cpu122
+tests/virhostcpudata/linux-subcores1/node/node17/cpu123 ../../cpu/cpu123
+tests/virhostcpudata/linux-subcores1/node/node17/cpu124 ../../cpu/cpu124
+tests/virhostcpudata/linux-subcores1/node/node17/cpu125 ../../cpu/cpu125
+tests/virhostcpudata/linux-subcores1/node/node17/cpu126 ../../cpu/cpu126
+tests/virhostcpudata/linux-subcores1/node/node17/cpu127 ../../cpu/cpu127
+tests/virhostcpudata/linux-subcores1/node/node17/cpu128 ../../cpu/cpu128
+tests/virhostcpudata/linux-subcores1/node/node17/cpu129 ../../cpu/cpu129
+tests/virhostcpudata/linux-subcores1/node/node17/cpu130 ../../cpu/cpu130
+tests/virhostcpudata/linux-subcores1/node/node17/cpu131 ../../cpu/cpu131
+tests/virhostcpudata/linux-subcores1/node/node17/cpu132 ../../cpu/cpu132
+tests/virhostcpudata/linux-subcores1/node/node17/cpu133 ../../cpu/cpu133
+tests/virhostcpudata/linux-subcores1/node/node17/cpu134 ../../cpu/cpu134
+tests/virhostcpudata/linux-subcores1/node/node17/cpu135 ../../cpu/cpu135
+tests/virhostcpudata/linux-subcores1/node/node17/cpu136 ../../cpu/cpu136
+tests/virhostcpudata/linux-subcores1/node/node17/cpu137 ../../cpu/cpu137
+tests/virhostcpudata/linux-subcores1/node/node17/cpu138 ../../cpu/cpu138
+tests/virhostcpudata/linux-subcores1/node/node17/cpu139 ../../cpu/cpu139
+tests/virhostcpudata/linux-subcores1/node/node17/cpu140 ../../cpu/cpu140
+tests/virhostcpudata/linux-subcores1/node/node17/cpu141 ../../cpu/cpu141
+tests/virhostcpudata/linux-subcores1/node/node17/cpu142 ../../cpu/cpu142
+tests/virhostcpudata/linux-subcores1/node/node17/cpu143 ../../cpu/cpu143
+tests/virhostcpudata/linux-subcores1/node/node17/cpu144 ../../cpu/cpu144
+tests/virhostcpudata/linux-subcores1/node/node17/cpu145 ../../cpu/cpu145
+tests/virhostcpudata/linux-subcores1/node/node17/cpu146 ../../cpu/cpu146
+tests/virhostcpudata/linux-subcores1/node/node17/cpu147 ../../cpu/cpu147
+tests/virhostcpudata/linux-subcores1/node/node17/cpu148 ../../cpu/cpu148
+tests/virhostcpudata/linux-subcores1/node/node17/cpu149 ../../cpu/cpu149
+tests/virhostcpudata/linux-subcores1/node/node17/cpu150 ../../cpu/cpu150
+tests/virhostcpudata/linux-subcores1/node/node17/cpu151 ../../cpu/cpu151
+tests/virhostcpudata/linux-subcores1/node/node17/cpu152 ../../cpu/cpu152
+tests/virhostcpudata/linux-subcores1/node/node17/cpu153 ../../cpu/cpu153
+tests/virhostcpudata/linux-subcores1/node/node17/cpu154 ../../cpu/cpu154
+tests/virhostcpudata/linux-subcores1/node/node17/cpu155 ../../cpu/cpu155
+tests/virhostcpudata/linux-subcores1/node/node17/cpu156 ../../cpu/cpu156
+tests/virhostcpudata/linux-subcores1/node/node17/cpu157 ../../cpu/cpu157
+tests/virhostcpudata/linux-subcores1/node/node17/cpu158 ../../cpu/cpu158
+tests/virhostcpudata/linux-subcores1/node/node17/cpu159 ../../cpu/cpu159
+tests/virhostcpudata/linux-subcores2/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-subcores2/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-subcores2/node/node0/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-subcores2/node/node0/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-subcores2/node/node0/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-subcores2/node/node0/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-subcores2/node/node0/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-subcores2/node/node0/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-subcores2/node/node0/cpu16 ../../cpu/cpu16
+tests/virhostcpudata/linux-subcores2/node/node0/cpu17 ../../cpu/cpu17
+tests/virhostcpudata/linux-subcores2/node/node0/cpu18 ../../cpu/cpu18
+tests/virhostcpudata/linux-subcores2/node/node0/cpu19 ../../cpu/cpu19
+tests/virhostcpudata/linux-subcores2/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-subcores2/node/node0/cpu20 ../../cpu/cpu20
+tests/virhostcpudata/linux-subcores2/node/node0/cpu21 ../../cpu/cpu21
+tests/virhostcpudata/linux-subcores2/node/node0/cpu22 ../../cpu/cpu22
+tests/virhostcpudata/linux-subcores2/node/node0/cpu23 ../../cpu/cpu23
+tests/virhostcpudata/linux-subcores2/node/node0/cpu24 ../../cpu/cpu24
+tests/virhostcpudata/linux-subcores2/node/node0/cpu25 ../../cpu/cpu25
+tests/virhostcpudata/linux-subcores2/node/node0/cpu26 ../../cpu/cpu26
+tests/virhostcpudata/linux-subcores2/node/node0/cpu27 ../../cpu/cpu27
+tests/virhostcpudata/linux-subcores2/node/node0/cpu28 ../../cpu/cpu28
+tests/virhostcpudata/linux-subcores2/node/node0/cpu29 ../../cpu/cpu29
+tests/virhostcpudata/linux-subcores2/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-subcores2/node/node0/cpu30 ../../cpu/cpu30
+tests/virhostcpudata/linux-subcores2/node/node0/cpu31 ../../cpu/cpu31
+tests/virhostcpudata/linux-subcores2/node/node0/cpu32 ../../cpu/cpu32
+tests/virhostcpudata/linux-subcores2/node/node0/cpu33 ../../cpu/cpu33
+tests/virhostcpudata/linux-subcores2/node/node0/cpu34 ../../cpu/cpu34
+tests/virhostcpudata/linux-subcores2/node/node0/cpu35 ../../cpu/cpu35
+tests/virhostcpudata/linux-subcores2/node/node0/cpu36 ../../cpu/cpu36
+tests/virhostcpudata/linux-subcores2/node/node0/cpu37 ../../cpu/cpu37
+tests/virhostcpudata/linux-subcores2/node/node0/cpu38 ../../cpu/cpu38
+tests/virhostcpudata/linux-subcores2/node/node0/cpu39 ../../cpu/cpu39
+tests/virhostcpudata/linux-subcores2/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-subcores2/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-subcores2/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-subcores2/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-subcores2/node/node0/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-subcores2/node/node0/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-subcores2/node/node1/cpu40 ../../cpu/cpu40
+tests/virhostcpudata/linux-subcores2/node/node1/cpu41 ../../cpu/cpu41
+tests/virhostcpudata/linux-subcores2/node/node1/cpu42 ../../cpu/cpu42
+tests/virhostcpudata/linux-subcores2/node/node1/cpu43 ../../cpu/cpu43
+tests/virhostcpudata/linux-subcores2/node/node1/cpu44 ../../cpu/cpu44
+tests/virhostcpudata/linux-subcores2/node/node1/cpu45 ../../cpu/cpu45
+tests/virhostcpudata/linux-subcores2/node/node1/cpu46 ../../cpu/cpu46
+tests/virhostcpudata/linux-subcores2/node/node1/cpu47 ../../cpu/cpu47
+tests/virhostcpudata/linux-subcores2/node/node1/cpu48 ../../cpu/cpu48
+tests/virhostcpudata/linux-subcores2/node/node1/cpu49 ../../cpu/cpu49
+tests/virhostcpudata/linux-subcores2/node/node1/cpu50 ../../cpu/cpu50
+tests/virhostcpudata/linux-subcores2/node/node1/cpu51 ../../cpu/cpu51
+tests/virhostcpudata/linux-subcores2/node/node1/cpu52 ../../cpu/cpu52
+tests/virhostcpudata/linux-subcores2/node/node1/cpu53 ../../cpu/cpu53
+tests/virhostcpudata/linux-subcores2/node/node1/cpu54 ../../cpu/cpu54
+tests/virhostcpudata/linux-subcores2/node/node1/cpu55 ../../cpu/cpu55
+tests/virhostcpudata/linux-subcores2/node/node1/cpu56 ../../cpu/cpu56
+tests/virhostcpudata/linux-subcores2/node/node1/cpu57 ../../cpu/cpu57
+tests/virhostcpudata/linux-subcores2/node/node1/cpu58 ../../cpu/cpu58
+tests/virhostcpudata/linux-subcores2/node/node1/cpu59 ../../cpu/cpu59
+tests/virhostcpudata/linux-subcores2/node/node1/cpu60 ../../cpu/cpu60
+tests/virhostcpudata/linux-subcores2/node/node1/cpu61 ../../cpu/cpu61
+tests/virhostcpudata/linux-subcores2/node/node1/cpu62 ../../cpu/cpu62
+tests/virhostcpudata/linux-subcores2/node/node1/cpu63 ../../cpu/cpu63
+tests/virhostcpudata/linux-subcores2/node/node1/cpu64 ../../cpu/cpu64
+tests/virhostcpudata/linux-subcores2/node/node1/cpu65 ../../cpu/cpu65
+tests/virhostcpudata/linux-subcores2/node/node1/cpu66 ../../cpu/cpu66
+tests/virhostcpudata/linux-subcores2/node/node1/cpu67 ../../cpu/cpu67
+tests/virhostcpudata/linux-subcores2/node/node1/cpu68 ../../cpu/cpu68
+tests/virhostcpudata/linux-subcores2/node/node1/cpu69 ../../cpu/cpu69
+tests/virhostcpudata/linux-subcores2/node/node1/cpu70 ../../cpu/cpu70
+tests/virhostcpudata/linux-subcores2/node/node1/cpu71 ../../cpu/cpu71
+tests/virhostcpudata/linux-subcores2/node/node1/cpu72 ../../cpu/cpu72
+tests/virhostcpudata/linux-subcores2/node/node1/cpu73 ../../cpu/cpu73
+tests/virhostcpudata/linux-subcores2/node/node1/cpu74 ../../cpu/cpu74
+tests/virhostcpudata/linux-subcores2/node/node1/cpu75 ../../cpu/cpu75
+tests/virhostcpudata/linux-subcores2/node/node1/cpu76 ../../cpu/cpu76
+tests/virhostcpudata/linux-subcores2/node/node1/cpu77 ../../cpu/cpu77
+tests/virhostcpudata/linux-subcores2/node/node1/cpu78 ../../cpu/cpu78
+tests/virhostcpudata/linux-subcores2/node/node1/cpu79 ../../cpu/cpu79
+tests/virhostcpudata/linux-subcores2/node/node16/cpu100 ../../cpu/cpu100
+tests/virhostcpudata/linux-subcores2/node/node16/cpu101 ../../cpu/cpu101
+tests/virhostcpudata/linux-subcores2/node/node16/cpu102 ../../cpu/cpu102
+tests/virhostcpudata/linux-subcores2/node/node16/cpu103 ../../cpu/cpu103
+tests/virhostcpudata/linux-subcores2/node/node16/cpu104 ../../cpu/cpu104
+tests/virhostcpudata/linux-subcores2/node/node16/cpu105 ../../cpu/cpu105
+tests/virhostcpudata/linux-subcores2/node/node16/cpu106 ../../cpu/cpu106
+tests/virhostcpudata/linux-subcores2/node/node16/cpu107 ../../cpu/cpu107
+tests/virhostcpudata/linux-subcores2/node/node16/cpu108 ../../cpu/cpu108
+tests/virhostcpudata/linux-subcores2/node/node16/cpu109 ../../cpu/cpu109
+tests/virhostcpudata/linux-subcores2/node/node16/cpu110 ../../cpu/cpu110
+tests/virhostcpudata/linux-subcores2/node/node16/cpu111 ../../cpu/cpu111
+tests/virhostcpudata/linux-subcores2/node/node16/cpu112 ../../cpu/cpu112
+tests/virhostcpudata/linux-subcores2/node/node16/cpu113 ../../cpu/cpu113
+tests/virhostcpudata/linux-subcores2/node/node16/cpu114 ../../cpu/cpu114
+tests/virhostcpudata/linux-subcores2/node/node16/cpu115 ../../cpu/cpu115
+tests/virhostcpudata/linux-subcores2/node/node16/cpu116 ../../cpu/cpu116
+tests/virhostcpudata/linux-subcores2/node/node16/cpu117 ../../cpu/cpu117
+tests/virhostcpudata/linux-subcores2/node/node16/cpu118 ../../cpu/cpu118
+tests/virhostcpudata/linux-subcores2/node/node16/cpu119 ../../cpu/cpu119
+tests/virhostcpudata/linux-subcores2/node/node16/cpu80 ../../cpu/cpu80
+tests/virhostcpudata/linux-subcores2/node/node16/cpu81 ../../cpu/cpu81
+tests/virhostcpudata/linux-subcores2/node/node16/cpu82 ../../cpu/cpu82
+tests/virhostcpudata/linux-subcores2/node/node16/cpu83 ../../cpu/cpu83
+tests/virhostcpudata/linux-subcores2/node/node16/cpu84 ../../cpu/cpu84
+tests/virhostcpudata/linux-subcores2/node/node16/cpu85 ../../cpu/cpu85
+tests/virhostcpudata/linux-subcores2/node/node16/cpu86 ../../cpu/cpu86
+tests/virhostcpudata/linux-subcores2/node/node16/cpu87 ../../cpu/cpu87
+tests/virhostcpudata/linux-subcores2/node/node16/cpu88 ../../cpu/cpu88
+tests/virhostcpudata/linux-subcores2/node/node16/cpu89 ../../cpu/cpu89
+tests/virhostcpudata/linux-subcores2/node/node16/cpu90 ../../cpu/cpu90
+tests/virhostcpudata/linux-subcores2/node/node16/cpu91 ../../cpu/cpu91
+tests/virhostcpudata/linux-subcores2/node/node16/cpu92 ../../cpu/cpu92
+tests/virhostcpudata/linux-subcores2/node/node16/cpu93 ../../cpu/cpu93
+tests/virhostcpudata/linux-subcores2/node/node16/cpu94 ../../cpu/cpu94
+tests/virhostcpudata/linux-subcores2/node/node16/cpu95 ../../cpu/cpu95
+tests/virhostcpudata/linux-subcores2/node/node16/cpu96 ../../cpu/cpu96
+tests/virhostcpudata/linux-subcores2/node/node16/cpu97 ../../cpu/cpu97
+tests/virhostcpudata/linux-subcores2/node/node16/cpu98 ../../cpu/cpu98
+tests/virhostcpudata/linux-subcores2/node/node16/cpu99 ../../cpu/cpu99
+tests/virhostcpudata/linux-subcores2/node/node17/cpu120 ../../cpu/cpu120
+tests/virhostcpudata/linux-subcores2/node/node17/cpu121 ../../cpu/cpu121
+tests/virhostcpudata/linux-subcores2/node/node17/cpu122 ../../cpu/cpu122
+tests/virhostcpudata/linux-subcores2/node/node17/cpu123 ../../cpu/cpu123
+tests/virhostcpudata/linux-subcores2/node/node17/cpu124 ../../cpu/cpu124
+tests/virhostcpudata/linux-subcores2/node/node17/cpu125 ../../cpu/cpu125
+tests/virhostcpudata/linux-subcores2/node/node17/cpu126 ../../cpu/cpu126
+tests/virhostcpudata/linux-subcores2/node/node17/cpu127 ../../cpu/cpu127
+tests/virhostcpudata/linux-subcores2/node/node17/cpu128 ../../cpu/cpu128
+tests/virhostcpudata/linux-subcores2/node/node17/cpu129 ../../cpu/cpu129
+tests/virhostcpudata/linux-subcores2/node/node17/cpu130 ../../cpu/cpu130
+tests/virhostcpudata/linux-subcores2/node/node17/cpu131 ../../cpu/cpu131
+tests/virhostcpudata/linux-subcores2/node/node17/cpu132 ../../cpu/cpu132
+tests/virhostcpudata/linux-subcores2/node/node17/cpu133 ../../cpu/cpu133
+tests/virhostcpudata/linux-subcores2/node/node17/cpu134 ../../cpu/cpu134
+tests/virhostcpudata/linux-subcores2/node/node17/cpu135 ../../cpu/cpu135
+tests/virhostcpudata/linux-subcores2/node/node17/cpu136 ../../cpu/cpu136
+tests/virhostcpudata/linux-subcores2/node/node17/cpu137 ../../cpu/cpu137
+tests/virhostcpudata/linux-subcores2/node/node17/cpu138 ../../cpu/cpu138
+tests/virhostcpudata/linux-subcores2/node/node17/cpu139 ../../cpu/cpu139
+tests/virhostcpudata/linux-subcores2/node/node17/cpu140 ../../cpu/cpu140
+tests/virhostcpudata/linux-subcores2/node/node17/cpu141 ../../cpu/cpu141
+tests/virhostcpudata/linux-subcores2/node/node17/cpu142 ../../cpu/cpu142
+tests/virhostcpudata/linux-subcores2/node/node17/cpu143 ../../cpu/cpu143
+tests/virhostcpudata/linux-subcores2/node/node17/cpu144 ../../cpu/cpu144
+tests/virhostcpudata/linux-subcores2/node/node17/cpu145 ../../cpu/cpu145
+tests/virhostcpudata/linux-subcores2/node/node17/cpu146 ../../cpu/cpu146
+tests/virhostcpudata/linux-subcores2/node/node17/cpu147 ../../cpu/cpu147
+tests/virhostcpudata/linux-subcores2/node/node17/cpu148 ../../cpu/cpu148
+tests/virhostcpudata/linux-subcores2/node/node17/cpu149 ../../cpu/cpu149
+tests/virhostcpudata/linux-subcores2/node/node17/cpu150 ../../cpu/cpu150
+tests/virhostcpudata/linux-subcores2/node/node17/cpu151 ../../cpu/cpu151
+tests/virhostcpudata/linux-subcores2/node/node17/cpu152 ../../cpu/cpu152
+tests/virhostcpudata/linux-subcores2/node/node17/cpu153 ../../cpu/cpu153
+tests/virhostcpudata/linux-subcores2/node/node17/cpu154 ../../cpu/cpu154
+tests/virhostcpudata/linux-subcores2/node/node17/cpu155 ../../cpu/cpu155
+tests/virhostcpudata/linux-subcores2/node/node17/cpu156 ../../cpu/cpu156
+tests/virhostcpudata/linux-subcores2/node/node17/cpu157 ../../cpu/cpu157
+tests/virhostcpudata/linux-subcores2/node/node17/cpu158 ../../cpu/cpu158
+tests/virhostcpudata/linux-subcores2/node/node17/cpu159 ../../cpu/cpu159
+tests/virhostcpudata/linux-subcores3/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-subcores3/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-subcores3/node/node0/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-subcores3/node/node0/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-subcores3/node/node0/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-subcores3/node/node0/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-subcores3/node/node0/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-subcores3/node/node0/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-subcores3/node/node0/cpu16 ../../cpu/cpu16
+tests/virhostcpudata/linux-subcores3/node/node0/cpu17 ../../cpu/cpu17
+tests/virhostcpudata/linux-subcores3/node/node0/cpu18 ../../cpu/cpu18
+tests/virhostcpudata/linux-subcores3/node/node0/cpu19 ../../cpu/cpu19
+tests/virhostcpudata/linux-subcores3/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-subcores3/node/node0/cpu20 ../../cpu/cpu20
+tests/virhostcpudata/linux-subcores3/node/node0/cpu21 ../../cpu/cpu21
+tests/virhostcpudata/linux-subcores3/node/node0/cpu22 ../../cpu/cpu22
+tests/virhostcpudata/linux-subcores3/node/node0/cpu23 ../../cpu/cpu23
+tests/virhostcpudata/linux-subcores3/node/node0/cpu24 ../../cpu/cpu24
+tests/virhostcpudata/linux-subcores3/node/node0/cpu25 ../../cpu/cpu25
+tests/virhostcpudata/linux-subcores3/node/node0/cpu26 ../../cpu/cpu26
+tests/virhostcpudata/linux-subcores3/node/node0/cpu27 ../../cpu/cpu27
+tests/virhostcpudata/linux-subcores3/node/node0/cpu28 ../../cpu/cpu28
+tests/virhostcpudata/linux-subcores3/node/node0/cpu29 ../../cpu/cpu29
+tests/virhostcpudata/linux-subcores3/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-subcores3/node/node0/cpu30 ../../cpu/cpu30
+tests/virhostcpudata/linux-subcores3/node/node0/cpu31 ../../cpu/cpu31
+tests/virhostcpudata/linux-subcores3/node/node0/cpu32 ../../cpu/cpu32
+tests/virhostcpudata/linux-subcores3/node/node0/cpu33 ../../cpu/cpu33
+tests/virhostcpudata/linux-subcores3/node/node0/cpu34 ../../cpu/cpu34
+tests/virhostcpudata/linux-subcores3/node/node0/cpu35 ../../cpu/cpu35
+tests/virhostcpudata/linux-subcores3/node/node0/cpu36 ../../cpu/cpu36
+tests/virhostcpudata/linux-subcores3/node/node0/cpu37 ../../cpu/cpu37
+tests/virhostcpudata/linux-subcores3/node/node0/cpu38 ../../cpu/cpu38
+tests/virhostcpudata/linux-subcores3/node/node0/cpu39 ../../cpu/cpu39
+tests/virhostcpudata/linux-subcores3/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-subcores3/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-subcores3/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-subcores3/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-subcores3/node/node0/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-subcores3/node/node0/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-subcores3/node/node1/cpu40 ../../cpu/cpu40
+tests/virhostcpudata/linux-subcores3/node/node1/cpu41 ../../cpu/cpu41
+tests/virhostcpudata/linux-subcores3/node/node1/cpu42 ../../cpu/cpu42
+tests/virhostcpudata/linux-subcores3/node/node1/cpu43 ../../cpu/cpu43
+tests/virhostcpudata/linux-subcores3/node/node1/cpu44 ../../cpu/cpu44
+tests/virhostcpudata/linux-subcores3/node/node1/cpu45 ../../cpu/cpu45
+tests/virhostcpudata/linux-subcores3/node/node1/cpu46 ../../cpu/cpu46
+tests/virhostcpudata/linux-subcores3/node/node1/cpu47 ../../cpu/cpu47
+tests/virhostcpudata/linux-subcores3/node/node1/cpu48 ../../cpu/cpu48
+tests/virhostcpudata/linux-subcores3/node/node1/cpu49 ../../cpu/cpu49
+tests/virhostcpudata/linux-subcores3/node/node1/cpu50 ../../cpu/cpu50
+tests/virhostcpudata/linux-subcores3/node/node1/cpu51 ../../cpu/cpu51
+tests/virhostcpudata/linux-subcores3/node/node1/cpu52 ../../cpu/cpu52
+tests/virhostcpudata/linux-subcores3/node/node1/cpu53 ../../cpu/cpu53
+tests/virhostcpudata/linux-subcores3/node/node1/cpu54 ../../cpu/cpu54
+tests/virhostcpudata/linux-subcores3/node/node1/cpu55 ../../cpu/cpu55
+tests/virhostcpudata/linux-subcores3/node/node1/cpu56 ../../cpu/cpu56
+tests/virhostcpudata/linux-subcores3/node/node1/cpu57 ../../cpu/cpu57
+tests/virhostcpudata/linux-subcores3/node/node1/cpu58 ../../cpu/cpu58
+tests/virhostcpudata/linux-subcores3/node/node1/cpu59 ../../cpu/cpu59
+tests/virhostcpudata/linux-subcores3/node/node1/cpu60 ../../cpu/cpu60
+tests/virhostcpudata/linux-subcores3/node/node1/cpu61 ../../cpu/cpu61
+tests/virhostcpudata/linux-subcores3/node/node1/cpu62 ../../cpu/cpu62
+tests/virhostcpudata/linux-subcores3/node/node1/cpu63 ../../cpu/cpu63
+tests/virhostcpudata/linux-subcores3/node/node1/cpu64 ../../cpu/cpu64
+tests/virhostcpudata/linux-subcores3/node/node1/cpu65 ../../cpu/cpu65
+tests/virhostcpudata/linux-subcores3/node/node1/cpu66 ../../cpu/cpu66
+tests/virhostcpudata/linux-subcores3/node/node1/cpu67 ../../cpu/cpu67
+tests/virhostcpudata/linux-subcores3/node/node1/cpu68 ../../cpu/cpu68
+tests/virhostcpudata/linux-subcores3/node/node1/cpu69 ../../cpu/cpu69
+tests/virhostcpudata/linux-subcores3/node/node1/cpu70 ../../cpu/cpu70
+tests/virhostcpudata/linux-subcores3/node/node1/cpu71 ../../cpu/cpu71
+tests/virhostcpudata/linux-subcores3/node/node1/cpu72 ../../cpu/cpu72
+tests/virhostcpudata/linux-subcores3/node/node1/cpu73 ../../cpu/cpu73
+tests/virhostcpudata/linux-subcores3/node/node1/cpu74 ../../cpu/cpu74
+tests/virhostcpudata/linux-subcores3/node/node1/cpu75 ../../cpu/cpu75
+tests/virhostcpudata/linux-subcores3/node/node1/cpu76 ../../cpu/cpu76
+tests/virhostcpudata/linux-subcores3/node/node1/cpu77 ../../cpu/cpu77
+tests/virhostcpudata/linux-subcores3/node/node1/cpu78 ../../cpu/cpu78
+tests/virhostcpudata/linux-subcores3/node/node1/cpu79 ../../cpu/cpu79
+tests/virhostcpudata/linux-subcores3/node/node16/cpu100 ../../cpu/cpu100
+tests/virhostcpudata/linux-subcores3/node/node16/cpu101 ../../cpu/cpu101
+tests/virhostcpudata/linux-subcores3/node/node16/cpu102 ../../cpu/cpu102
+tests/virhostcpudata/linux-subcores3/node/node16/cpu103 ../../cpu/cpu103
+tests/virhostcpudata/linux-subcores3/node/node16/cpu104 ../../cpu/cpu104
+tests/virhostcpudata/linux-subcores3/node/node16/cpu105 ../../cpu/cpu105
+tests/virhostcpudata/linux-subcores3/node/node16/cpu106 ../../cpu/cpu106
+tests/virhostcpudata/linux-subcores3/node/node16/cpu107 ../../cpu/cpu107
+tests/virhostcpudata/linux-subcores3/node/node16/cpu108 ../../cpu/cpu108
+tests/virhostcpudata/linux-subcores3/node/node16/cpu109 ../../cpu/cpu109
+tests/virhostcpudata/linux-subcores3/node/node16/cpu110 ../../cpu/cpu110
+tests/virhostcpudata/linux-subcores3/node/node16/cpu111 ../../cpu/cpu111
+tests/virhostcpudata/linux-subcores3/node/node16/cpu112 ../../cpu/cpu112
+tests/virhostcpudata/linux-subcores3/node/node16/cpu113 ../../cpu/cpu113
+tests/virhostcpudata/linux-subcores3/node/node16/cpu114 ../../cpu/cpu114
+tests/virhostcpudata/linux-subcores3/node/node16/cpu115 ../../cpu/cpu115
+tests/virhostcpudata/linux-subcores3/node/node16/cpu116 ../../cpu/cpu116
+tests/virhostcpudata/linux-subcores3/node/node16/cpu117 ../../cpu/cpu117
+tests/virhostcpudata/linux-subcores3/node/node16/cpu118 ../../cpu/cpu118
+tests/virhostcpudata/linux-subcores3/node/node16/cpu119 ../../cpu/cpu119
+tests/virhostcpudata/linux-subcores3/node/node16/cpu80 ../../cpu/cpu80
+tests/virhostcpudata/linux-subcores3/node/node16/cpu81 ../../cpu/cpu81
+tests/virhostcpudata/linux-subcores3/node/node16/cpu82 ../../cpu/cpu82
+tests/virhostcpudata/linux-subcores3/node/node16/cpu83 ../../cpu/cpu83
+tests/virhostcpudata/linux-subcores3/node/node16/cpu84 ../../cpu/cpu84
+tests/virhostcpudata/linux-subcores3/node/node16/cpu85 ../../cpu/cpu85
+tests/virhostcpudata/linux-subcores3/node/node16/cpu86 ../../cpu/cpu86
+tests/virhostcpudata/linux-subcores3/node/node16/cpu87 ../../cpu/cpu87
+tests/virhostcpudata/linux-subcores3/node/node16/cpu88 ../../cpu/cpu88
+tests/virhostcpudata/linux-subcores3/node/node16/cpu89 ../../cpu/cpu89
+tests/virhostcpudata/linux-subcores3/node/node16/cpu90 ../../cpu/cpu90
+tests/virhostcpudata/linux-subcores3/node/node16/cpu91 ../../cpu/cpu91
+tests/virhostcpudata/linux-subcores3/node/node16/cpu92 ../../cpu/cpu92
+tests/virhostcpudata/linux-subcores3/node/node16/cpu93 ../../cpu/cpu93
+tests/virhostcpudata/linux-subcores3/node/node16/cpu94 ../../cpu/cpu94
+tests/virhostcpudata/linux-subcores3/node/node16/cpu95 ../../cpu/cpu95
+tests/virhostcpudata/linux-subcores3/node/node16/cpu96 ../../cpu/cpu96
+tests/virhostcpudata/linux-subcores3/node/node16/cpu97 ../../cpu/cpu97
+tests/virhostcpudata/linux-subcores3/node/node16/cpu98 ../../cpu/cpu98
+tests/virhostcpudata/linux-subcores3/node/node16/cpu99 ../../cpu/cpu99
+tests/virhostcpudata/linux-subcores3/node/node17/cpu120 ../../cpu/cpu120
+tests/virhostcpudata/linux-subcores3/node/node17/cpu121 ../../cpu/cpu121
+tests/virhostcpudata/linux-subcores3/node/node17/cpu122 ../../cpu/cpu122
+tests/virhostcpudata/linux-subcores3/node/node17/cpu123 ../../cpu/cpu123
+tests/virhostcpudata/linux-subcores3/node/node17/cpu124 ../../cpu/cpu124
+tests/virhostcpudata/linux-subcores3/node/node17/cpu125 ../../cpu/cpu125
+tests/virhostcpudata/linux-subcores3/node/node17/cpu126 ../../cpu/cpu126
+tests/virhostcpudata/linux-subcores3/node/node17/cpu127 ../../cpu/cpu127
+tests/virhostcpudata/linux-subcores3/node/node17/cpu128 ../../cpu/cpu128
+tests/virhostcpudata/linux-subcores3/node/node17/cpu129 ../../cpu/cpu129
+tests/virhostcpudata/linux-subcores3/node/node17/cpu130 ../../cpu/cpu130
+tests/virhostcpudata/linux-subcores3/node/node17/cpu131 ../../cpu/cpu131
+tests/virhostcpudata/linux-subcores3/node/node17/cpu132 ../../cpu/cpu132
+tests/virhostcpudata/linux-subcores3/node/node17/cpu133 ../../cpu/cpu133
+tests/virhostcpudata/linux-subcores3/node/node17/cpu134 ../../cpu/cpu134
+tests/virhostcpudata/linux-subcores3/node/node17/cpu135 ../../cpu/cpu135
+tests/virhostcpudata/linux-subcores3/node/node17/cpu136 ../../cpu/cpu136
+tests/virhostcpudata/linux-subcores3/node/node17/cpu137 ../../cpu/cpu137
+tests/virhostcpudata/linux-subcores3/node/node17/cpu138 ../../cpu/cpu138
+tests/virhostcpudata/linux-subcores3/node/node17/cpu139 ../../cpu/cpu139
+tests/virhostcpudata/linux-subcores3/node/node17/cpu140 ../../cpu/cpu140
+tests/virhostcpudata/linux-subcores3/node/node17/cpu141 ../../cpu/cpu141
+tests/virhostcpudata/linux-subcores3/node/node17/cpu142 ../../cpu/cpu142
+tests/virhostcpudata/linux-subcores3/node/node17/cpu143 ../../cpu/cpu143
+tests/virhostcpudata/linux-subcores3/node/node17/cpu144 ../../cpu/cpu144
+tests/virhostcpudata/linux-subcores3/node/node17/cpu145 ../../cpu/cpu145
+tests/virhostcpudata/linux-subcores3/node/node17/cpu146 ../../cpu/cpu146
+tests/virhostcpudata/linux-subcores3/node/node17/cpu147 ../../cpu/cpu147
+tests/virhostcpudata/linux-subcores3/node/node17/cpu148 ../../cpu/cpu148
+tests/virhostcpudata/linux-subcores3/node/node17/cpu149 ../../cpu/cpu149
+tests/virhostcpudata/linux-subcores3/node/node17/cpu150 ../../cpu/cpu150
+tests/virhostcpudata/linux-subcores3/node/node17/cpu151 ../../cpu/cpu151
+tests/virhostcpudata/linux-subcores3/node/node17/cpu152 ../../cpu/cpu152
+tests/virhostcpudata/linux-subcores3/node/node17/cpu153 ../../cpu/cpu153
+tests/virhostcpudata/linux-subcores3/node/node17/cpu154 ../../cpu/cpu154
+tests/virhostcpudata/linux-subcores3/node/node17/cpu155 ../../cpu/cpu155
+tests/virhostcpudata/linux-subcores3/node/node17/cpu156 ../../cpu/cpu156
+tests/virhostcpudata/linux-subcores3/node/node17/cpu157 ../../cpu/cpu157
+tests/virhostcpudata/linux-subcores3/node/node17/cpu158 ../../cpu/cpu158
+tests/virhostcpudata/linux-subcores3/node/node17/cpu159 ../../cpu/cpu159
+tests/virhostcpudata/linux-test2/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-test2/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-test3/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-test3/node/node0/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-test3/node/node0/cpu16 ../../cpu/cpu16
+tests/virhostcpudata/linux-test3/node/node0/cpu20 ../../cpu/cpu20
+tests/virhostcpudata/linux-test3/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-test3/node/node0/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-test3/node/node1/cpu24 ../../cpu/cpu24
+tests/virhostcpudata/linux-test3/node/node1/cpu28 ../../cpu/cpu28
+tests/virhostcpudata/linux-test3/node/node1/cpu32 ../../cpu/cpu32
+tests/virhostcpudata/linux-test3/node/node1/cpu36 ../../cpu/cpu36
+tests/virhostcpudata/linux-test3/node/node1/cpu40 ../../cpu/cpu40
+tests/virhostcpudata/linux-test3/node/node1/cpu44 ../../cpu/cpu44
+tests/virhostcpudata/linux-test3/node/node2/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-test3/node/node2/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-test3/node/node2/cpu19 ../../cpu/cpu19
+tests/virhostcpudata/linux-test3/node/node2/cpu23 ../../cpu/cpu23
+tests/virhostcpudata/linux-test3/node/node2/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-test3/node/node2/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-test3/node/node3/cpu27 ../../cpu/cpu27
+tests/virhostcpudata/linux-test3/node/node3/cpu31 ../../cpu/cpu31
+tests/virhostcpudata/linux-test3/node/node3/cpu35 ../../cpu/cpu35
+tests/virhostcpudata/linux-test3/node/node3/cpu39 ../../cpu/cpu39
+tests/virhostcpudata/linux-test3/node/node3/cpu43 ../../cpu/cpu43
+tests/virhostcpudata/linux-test3/node/node3/cpu47 ../../cpu/cpu47
+tests/virhostcpudata/linux-test3/node/node4/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-test3/node/node4/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-test3/node/node4/cpu18 ../../cpu/cpu18
+tests/virhostcpudata/linux-test3/node/node4/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-test3/node/node4/cpu22 ../../cpu/cpu22
+tests/virhostcpudata/linux-test3/node/node4/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-test3/node/node5/cpu26 ../../cpu/cpu26
+tests/virhostcpudata/linux-test3/node/node5/cpu30 ../../cpu/cpu30
+tests/virhostcpudata/linux-test3/node/node5/cpu34 ../../cpu/cpu34
+tests/virhostcpudata/linux-test3/node/node5/cpu38 ../../cpu/cpu38
+tests/virhostcpudata/linux-test3/node/node5/cpu42 ../../cpu/cpu42
+tests/virhostcpudata/linux-test3/node/node5/cpu46 ../../cpu/cpu46
+tests/virhostcpudata/linux-test3/node/node6/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-test3/node/node6/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-test3/node/node6/cpu17 ../../cpu/cpu17
+tests/virhostcpudata/linux-test3/node/node6/cpu21 ../../cpu/cpu21
+tests/virhostcpudata/linux-test3/node/node6/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-test3/node/node6/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-test3/node/node7/cpu25 ../../cpu/cpu25
+tests/virhostcpudata/linux-test3/node/node7/cpu29 ../../cpu/cpu29
+tests/virhostcpudata/linux-test3/node/node7/cpu33 ../../cpu/cpu33
+tests/virhostcpudata/linux-test3/node/node7/cpu37 ../../cpu/cpu37
+tests/virhostcpudata/linux-test3/node/node7/cpu41 ../../cpu/cpu41
+tests/virhostcpudata/linux-test3/node/node7/cpu45 ../../cpu/cpu45
+tests/virhostcpudata/linux-test4/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-test4/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-test4/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-test4/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-test4/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-test4/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-test4/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-test4/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-test4/node/node1/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-test4/node/node1/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-test4/node/node1/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-test4/node/node1/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-test4/node/node1/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-test4/node/node1/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-test4/node/node1/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-test4/node/node1/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-test6/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-test6/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-test6/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-test6/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-test6/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-test6/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-test6/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-test6/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-test7/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-test7/node/node0/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-test7/node/node0/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-test7/node/node0/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-test7/node/node0/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-test7/node/node0/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-test7/node/node0/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-test7/node/node0/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-test7/node/node0/cpu16 ../../cpu/cpu16
+tests/virhostcpudata/linux-test7/node/node0/cpu17 ../../cpu/cpu17
+tests/virhostcpudata/linux-test7/node/node0/cpu18 ../../cpu/cpu18
+tests/virhostcpudata/linux-test7/node/node0/cpu19 ../../cpu/cpu19
+tests/virhostcpudata/linux-test7/node/node0/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-test7/node/node0/cpu20 ../../cpu/cpu20
+tests/virhostcpudata/linux-test7/node/node0/cpu21 ../../cpu/cpu21
+tests/virhostcpudata/linux-test7/node/node0/cpu22 ../../cpu/cpu22
+tests/virhostcpudata/linux-test7/node/node0/cpu23 ../../cpu/cpu23
+tests/virhostcpudata/linux-test7/node/node0/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-test7/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-test7/node/node0/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-test7/node/node0/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-test7/node/node0/cpu7 ../../cpu/cpu7
+tests/virhostcpudata/linux-test7/node/node0/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-test7/node/node0/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-test8/node/node0/cpu0 ../../cpu/cpu0
+tests/virhostcpudata/linux-test8/node/node0/cpu12 ../../cpu/cpu12
+tests/virhostcpudata/linux-test8/node/node0/cpu16 ../../cpu/cpu16
+tests/virhostcpudata/linux-test8/node/node0/cpu20 ../../cpu/cpu20
+tests/virhostcpudata/linux-test8/node/node0/cpu24 ../../cpu/cpu24
+tests/virhostcpudata/linux-test8/node/node0/cpu28 ../../cpu/cpu28
+tests/virhostcpudata/linux-test8/node/node0/cpu4 ../../cpu/cpu4
+tests/virhostcpudata/linux-test8/node/node0/cpu8 ../../cpu/cpu8
+tests/virhostcpudata/linux-test8/node/node1/cpu32 ../../cpu/cpu32
+tests/virhostcpudata/linux-test8/node/node1/cpu36 ../../cpu/cpu36
+tests/virhostcpudata/linux-test8/node/node1/cpu40 ../../cpu/cpu40
+tests/virhostcpudata/linux-test8/node/node1/cpu44 ../../cpu/cpu44
+tests/virhostcpudata/linux-test8/node/node1/cpu48 ../../cpu/cpu48
+tests/virhostcpudata/linux-test8/node/node1/cpu52 ../../cpu/cpu52
+tests/virhostcpudata/linux-test8/node/node1/cpu56 ../../cpu/cpu56
+tests/virhostcpudata/linux-test8/node/node1/cpu60 ../../cpu/cpu60
+tests/virhostcpudata/linux-test8/node/node2/cpu1 ../../cpu/cpu1
+tests/virhostcpudata/linux-test8/node/node2/cpu13 ../../cpu/cpu13
+tests/virhostcpudata/linux-test8/node/node2/cpu17 ../../cpu/cpu17
+tests/virhostcpudata/linux-test8/node/node2/cpu21 ../../cpu/cpu21
+tests/virhostcpudata/linux-test8/node/node2/cpu25 ../../cpu/cpu25
+tests/virhostcpudata/linux-test8/node/node2/cpu29 ../../cpu/cpu29
+tests/virhostcpudata/linux-test8/node/node2/cpu5 ../../cpu/cpu5
+tests/virhostcpudata/linux-test8/node/node2/cpu9 ../../cpu/cpu9
+tests/virhostcpudata/linux-test8/node/node3/cpu33 ../../cpu/cpu33
+tests/virhostcpudata/linux-test8/node/node3/cpu37 ../../cpu/cpu37
+tests/virhostcpudata/linux-test8/node/node3/cpu41 ../../cpu/cpu41
+tests/virhostcpudata/linux-test8/node/node3/cpu45 ../../cpu/cpu45
+tests/virhostcpudata/linux-test8/node/node3/cpu49 ../../cpu/cpu49
+tests/virhostcpudata/linux-test8/node/node3/cpu53 ../../cpu/cpu53
+tests/virhostcpudata/linux-test8/node/node3/cpu57 ../../cpu/cpu57
+tests/virhostcpudata/linux-test8/node/node3/cpu61 ../../cpu/cpu61
+tests/virhostcpudata/linux-test8/node/node4/cpu10 ../../cpu/cpu10
+tests/virhostcpudata/linux-test8/node/node4/cpu14 ../../cpu/cpu14
+tests/virhostcpudata/linux-test8/node/node4/cpu18 ../../cpu/cpu18
+tests/virhostcpudata/linux-test8/node/node4/cpu2 ../../cpu/cpu2
+tests/virhostcpudata/linux-test8/node/node4/cpu22 ../../cpu/cpu22
+tests/virhostcpudata/linux-test8/node/node4/cpu26 ../../cpu/cpu26
+tests/virhostcpudata/linux-test8/node/node4/cpu30 ../../cpu/cpu30
+tests/virhostcpudata/linux-test8/node/node4/cpu6 ../../cpu/cpu6
+tests/virhostcpudata/linux-test8/node/node5/cpu34 ../../cpu/cpu34
+tests/virhostcpudata/linux-test8/node/node5/cpu38 ../../cpu/cpu38
+tests/virhostcpudata/linux-test8/node/node5/cpu42 ../../cpu/cpu42
+tests/virhostcpudata/linux-test8/node/node5/cpu46 ../../cpu/cpu46
+tests/virhostcpudata/linux-test8/node/node5/cpu50 ../../cpu/cpu50
+tests/virhostcpudata/linux-test8/node/node5/cpu54 ../../cpu/cpu54
+tests/virhostcpudata/linux-test8/node/node5/cpu58 ../../cpu/cpu58
+tests/virhostcpudata/linux-test8/node/node5/cpu62 ../../cpu/cpu62
+tests/virhostcpudata/linux-test8/node/node6/cpu35 ../../cpu/cpu35
+tests/virhostcpudata/linux-test8/node/node6/cpu39 ../../cpu/cpu39
+tests/virhostcpudata/linux-test8/node/node6/cpu43 ../../cpu/cpu43
+tests/virhostcpudata/linux-test8/node/node6/cpu47 ../../cpu/cpu47
+tests/virhostcpudata/linux-test8/node/node6/cpu51 ../../cpu/cpu51
+tests/virhostcpudata/linux-test8/node/node6/cpu55 ../../cpu/cpu55
+tests/virhostcpudata/linux-test8/node/node6/cpu59 ../../cpu/cpu59
+tests/virhostcpudata/linux-test8/node/node6/cpu63 ../../cpu/cpu63
+tests/virhostcpudata/linux-test8/node/node7/cpu11 ../../cpu/cpu11
+tests/virhostcpudata/linux-test8/node/node7/cpu15 ../../cpu/cpu15
+tests/virhostcpudata/linux-test8/node/node7/cpu19 ../../cpu/cpu19
+tests/virhostcpudata/linux-test8/node/node7/cpu23 ../../cpu/cpu23
+tests/virhostcpudata/linux-test8/node/node7/cpu27 ../../cpu/cpu27
+tests/virhostcpudata/linux-test8/node/node7/cpu3 ../../cpu/cpu3
+tests/virhostcpudata/linux-test8/node/node7/cpu31 ../../cpu/cpu31
+tests/virhostcpudata/linux-test8/node/node7/cpu7 ../../cpu/cpu7
diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec
new file mode 100644
index 0000000..5e65b4e
--- /dev/null
+++ b/SPECS/libvirt.spec
@@ -0,0 +1,3038 @@
+# -*- rpm-spec -*-
+
+# This spec file assumes you are building on a Fedora or RHEL version
+# that's still supported by the vendor. It may work on other distros
+# or versions, but no effort will be made to ensure that going forward.
+%define min_rhel 7
+%define min_fedora 30
+
+%if (0%{?fedora} && 0%{?fedora} >= %{min_fedora}) || (0%{?rhel} && 0%{?rhel} >= %{min_rhel})
+    %define supported_platform 1
+%else
+    %define supported_platform 0
+%endif
+
+# Default to skipping autoreconf.  Distros can change just this one line
+# (or provide a command-line override) if they backport any patches that
+# touch configure.ac or Makefile.am.
+# Always run autoreconf
+%{!?enable_autotools:%global enable_autotools 1}
+
+# The hypervisor drivers that run in libvirtd
+%define with_qemu          0%{!?_without_qemu:1}
+%define with_lxc           0%{!?_without_lxc:1}
+%define with_libxl         0%{!?_without_libxl:1}
+%define with_vbox          0%{!?_without_vbox:1}
+
+%define with_qemu_tcg      %{with_qemu}
+
+%define qemu_kvm_arches %{ix86} x86_64
+
+%if 0%{?fedora}
+    %define qemu_kvm_arches %{ix86} x86_64 %{power64} s390x %{arm} aarch64
+%endif
+
+%if 0%{?rhel}
+    %define with_qemu_tcg 0
+    %define qemu_kvm_arches x86_64 %{power64} aarch64 s390x
+%endif
+
+# On RHEL 7 and older macro _vpath_builddir is not defined.
+%if 0%{?rhel} <= 7
+    %define _vpath_builddir %{_target_platform}
+%endif
+
+%ifarch %{qemu_kvm_arches}
+    %define with_qemu_kvm      %{with_qemu}
+%else
+    %define with_qemu_kvm      0
+%endif
+
+%if ! %{with_qemu_tcg} && ! %{with_qemu_kvm}
+    %define with_qemu 0
+%endif
+
+# Then the hypervisor drivers that run outside libvirtd, in libvirt.so
+%define with_openvz        0%{!?_without_openvz:1}
+%define with_vmware        0%{!?_without_vmware:1}
+%define with_esx           0%{!?_without_esx:1}
+%define with_hyperv        0%{!?_without_hyperv:1}
+
+# Then the secondary host drivers, which run inside libvirtd
+%define with_storage_rbd      0%{!?_without_storage_rbd:1}
+%if 0%{?fedora}
+    %define with_storage_sheepdog 0%{!?_without_storage_sheepdog:1}
+%else
+    %define with_storage_sheepdog 0
+%endif
+
+%define with_storage_gluster 0%{!?_without_storage_gluster:1}
+%ifnarch %{qemu_kvm_arches}
+    # gluster is only built where qemu driver is enabled on RHEL 8
+    %if 0%{?rhel} >= 8
+        %define with_storage_gluster 0
+    %endif
+%endif
+
+%define with_numactl          0%{!?_without_numactl:1}
+
+# F25+ has zfs-fuse
+%if 0%{?fedora}
+    %define with_storage_zfs      0%{!?_without_storage_zfs:1}
+%else
+    %define with_storage_zfs      0
+%endif
+
+# We need a recent enough libiscsi (>= 1.18.0)
+%if 0%{?fedora} || 0%{?rhel} > 7
+    %define with_storage_iscsi_direct 0%{!?_without_storage_iscsi_direct:1}
+%else
+    %define with_storage_iscsi_direct 0
+%endif
+
+# A few optional bits off by default, we enable later
+%define with_fuse          0%{!?_without_fuse:0}
+%define with_sanlock       0%{!?_without_sanlock:0}
+%define with_numad         0%{!?_without_numad:0}
+%define with_firewalld     0%{!?_without_firewalld:0}
+%define with_firewalld_zone 0%{!?_without_firewalld_zone:0}
+%define with_libssh2       0%{!?_without_libssh2:0}
+%define with_wireshark     0%{!?_without_wireshark:0}
+%define with_libssh        0%{!?_without_libssh:0}
+%define with_bash_completion  0%{!?_without_bash_completion:0}
+
+# Finally set the OS / architecture specific special cases
+
+# Xen is available only on i386 x86_64 ia64
+%ifnarch %{ix86} x86_64 ia64
+    %define with_libxl 0
+%endif
+
+# vbox is available only on i386 x86_64
+%ifnarch %{ix86} x86_64
+    %define with_vbox 0
+%endif
+
+# Numactl is not available on many non-x86 archs
+%ifarch s390 s390x %{arm} riscv64
+    %define with_numactl 0
+%endif
+
+# zfs-fuse is not available on some architectures
+%ifarch s390 s390x aarch64 riscv64
+    %define with_storage_zfs 0
+%endif
+
+# Ceph dropping support for 32-bit hosts
+%if 0%{?fedora} >= 30
+    %ifarch %{arm} %{ix86}
+        %define with_storage_rbd 0
+    %endif
+%endif
+
+# RHEL doesn't ship OpenVZ, VBox, PowerHypervisor,
+# VMware, libxenlight (Xen 4.1 and newer),
+# or HyperV.
+%if 0%{?rhel}
+    %define with_openvz 0
+    %define with_vbox 0
+    %define with_vmware 0
+    %define with_libxl 0
+    %define with_hyperv 0
+    %define with_vz 0
+
+    %if 0%{?rhel} > 7
+        %define with_lxc 0
+    %endif
+%endif
+
+%define with_firewalld 1
+
+%if 0%{?fedora} >= 31 || 0%{?rhel} > 7
+    %define with_firewalld_zone 0%{!?_without_firewalld_zone:1}
+%endif
+
+
+# fuse is used to provide virtualized /proc for LXC
+%if %{with_lxc}
+    %define with_fuse      0%{!?_without_fuse:1}
+%endif
+
+# Enable sanlock library for lock management with QEMU
+# Sanlock is available only on arches where kvm is available for RHEL
+%if 0%{?fedora}
+    %define with_sanlock 0%{!?_without_sanlock:1}
+%endif
+%if 0%{?rhel}
+    %ifarch %{qemu_kvm_arches}
+        %define with_sanlock 0%{!?_without_sanlock:1}
+    %endif
+%endif
+
+# Enable libssh2 transport for new enough distros
+%if 0%{?fedora}
+    %define with_libssh2 0%{!?_without_libssh2:1}
+%endif
+
+# Enable wireshark plugins for all distros shipping libvirt 1.2.2 or newer
+%if 0%{?fedora}
+    %define with_wireshark 0%{!?_without_wireshark:1}
+    %define wireshark_plugindir %(pkg-config --variable plugindir wireshark)/epan
+%endif
+
+# Enable libssh transport for new enough distros
+%if 0%{?fedora} || 0%{?rhel} > 7
+    %define with_libssh 0%{!?_without_libssh:1}
+%endif
+
+%define with_bash_completion  0%{!?_without_bash_completion:1}
+
+%if %{with_qemu} || %{with_lxc}
+# numad is used to manage the CPU and memory placement dynamically,
+# it's not available on many non-x86 architectures.
+    %ifnarch s390 s390x %{arm} riscv64
+        %define with_numad    0%{!?_without_numad:1}
+    %endif
+%endif
+
+# Force QEMU to run as non-root
+%define qemu_user  qemu
+%define qemu_group  qemu
+
+
+# RHEL releases provide stable tool chains and so it is safe to turn
+# compiler warning into errors without being worried about frequent
+# changes in reported warnings
+%if 0%{?rhel}
+    %define enable_werror --enable-werror
+%else
+    %define enable_werror --disable-werror
+%endif
+
+%if 0%{?rhel} == 7
+    %define tls_priority "NORMAL"
+%else
+    %define tls_priority "@LIBVIRT,SYSTEM"
+%endif
+
+
+Summary: Library providing a simple virtualization API
+Name: libvirt
+Version: 6.0.0
+Release: 17%{?dist}%{?extra_release}
+License: LGPLv2+
+URL: https://libvirt.org/
+
+%if %(echo %{version} | grep -q "\.0$"; echo $?) == 1
+    %define mainturl stable_updates/
+%endif
+Source: https://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.xz
+Source1: symlinks
+
+Patch1: libvirt-RHEL-Hack-around-changed-Broadwell-Haswell-CPUs.patch
+Patch2: libvirt-RHEL-Add-rhel-machine-types-to-qemuDomainMachineNeedsFDC.patch
+Patch3: libvirt-RHEL-Fix-virConnectGetMaxVcpus-output.patch
+Patch4: libvirt-RHEL-qemu-Add-ability-to-set-sgio-values-for-hostdev.patch
+Patch5: libvirt-RHEL-qemu-Add-check-for-unpriv-sgio-for-SCSI-generic-host-device.patch
+Patch6: libvirt-RHEL-qemu-Alter-val-usage-in-qemuSetUnprivSGIO.patch
+Patch7: libvirt-RHEL-qemu-Alter-qemuSetUnprivSGIO-hostdev-shareable-logic.patch
+Patch8: libvirt-RHEL-qemu-Fix-logic-error-in-qemuSetUnprivSGIO.patch
+Patch9: libvirt-RHEL-qemu-Fix-crash-trying-to-use-iSCSI-hostdev.patch
+Patch10: libvirt-qemuDomainSaveImageStartVM-Use-VIR_AUTOCLOSE-for-intermediatefd.patch
+Patch11: libvirt-qemuDomainSaveImageStartVM-Use-g_autoptr-for-virCommand.patch
+Patch12: libvirt-qemu-Use-g_autoptr-for-qemuDomainSaveCookie.patch
+Patch13: libvirt-qemu-Stop-domain-on-failed-restore.patch
+Patch14: libvirt-qemu-Don-t-emit-SUSPENDED_POSTCOPY-event-on-destination.patch
+Patch15: libvirt-util-storagefile-Properly-set-transport-type-when-parsing-NBD-strings.patch
+Patch16: libvirt-tests-virstorage-Add-tests-for-NBD-URI-style-syntax-over-UNIX.patch
+Patch17: libvirt-qemu-end-the-agent-job-in-qemuDomainSetTimeAgent.patch
+Patch18: libvirt-cpu.c-Check-properly-for-virCapabilitiesGetNodeInfo-retval.patch
+Patch19: libvirt-qemu_conf-Avoid-dereferencing-NULL-in-virQEMUDriverGetHost-NUMACaps-CPU.patch
+Patch20: libvirt-qemu_capabilities-Rework-domain-caps-cache.patch
+Patch21: libvirt-conf-add-support-for-specifying-CPU-dies-parameter.patch
+Patch22: libvirt-conf-remove-unused-virCapabilitiesSetHostCPU-method.patch
+Patch23: libvirt-qemu-add-support-for-specifying-CPU-dies-topology-parameter.patch
+Patch24: libvirt-hostcpu-add-support-for-reporting-die_id-in-NUMA-topology.patch
+Patch25: libvirt-tests-add-host-CPU-data-files-for-validating-die_id.patch
+Patch26: libvirt-qemu-add-capabilities-flag-for-failover-feature.patch
+Patch27: libvirt-conf-parse-format-teaming-subelement-of-interface.patch
+Patch28: libvirt-qemu-support-interface-teaming-functionality.patch
+Patch29: libvirt-qemu-allow-migration-with-assigned-PCI-hostdev-if-teaming-is-set.patch
+Patch30: libvirt-qemu-add-wait-unplug-to-qemu-migration-status-enum.patch
+Patch31: libvirt-docs-document-interface-subelement-teaming.patch
+Patch32: libvirt-qemu-blockcopy-Actually-unplug-unused-images-when-mirror-job-fails-to-start.patch
+Patch33: libvirt-qemu-domain-Extract-code-to-determine-topmost-nodename-to-qemuDomainDiskGetTopNodename.patch
+Patch34: libvirt-qemu-Fix-value-of-device-argument-for-blockdev-mirror.patch
+Patch35: libvirt-qemu-Fix-value-of-device-argument-for-block-commit.patch
+Patch36: libvirt-conf-backup-Allow-configuration-of-names-exported-via-NBD.patch
+Patch37: libvirt-qemu-backup-Implement-support-for-backup-disk-export-name-configuration.patch
+Patch38: libvirt-qemu-backup-Implement-support-for-backup-disk-bitmap-name-configuration.patch
+Patch39: libvirt-util-hash-Improve-debugability-of-Duplicate-key-error-message.patch
+Patch40: libvirt-tests-hash-Test-case-for-adding-duplicate-hash-entry.patch
+Patch41: libvirt-qemu-block-Don-t-skip-creation-of-luks-formatted-images.patch
+Patch42: libvirt-qemu-monitor-Improve-error-message-when-QEMU-reply-is-too-large.patch
+Patch43: libvirt-qemu-snapshot-Always-rewrite-backingStore-data-when-reusing-existing-images.patch
+Patch44: libvirt-qemu-snapshot-Prevent-too-nested-domain-XML-when-doing-inactive-snapshot.patch
+Patch45: libvirt-qemu-checkpoint-Store-whether-deleted-checkpoint-is-current-in-a-variable.patch
+Patch46: libvirt-qemu-checkpoint-split-out-checkpoint-deletion-bitmaps.patch
+Patch47: libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointDiscardBitmaps.patch
+Patch48: libvirt-qemu-checkpoint-rename-disk-chkdisk-in-qemuCheckpointAddActions.patch
+Patch49: libvirt-qemu-checkpoint-Use-disk-definition-directly-when-creating-checkpoint.patch
+Patch50: libvirt-qemu-checkpoint-tolerate-missing-disks-on-checkpoint-deletion.patch
+Patch51: libvirt-qemu-domain-Remove-unused-qemuDomainDiskNodeFormatLookup.patch
+Patch52: libvirt-qemu-checkpoint-Introduce-helper-to-find-checkpoint-disk-definition-in-parents.patch
+Patch53: libvirt-qemu-checkpoint-Extract-calculation-of-bitmap-merging-for-checkpoint-deletion.patch
+Patch54: libvirt-qemu-snapshot-go-through-cleanup-on-error.patch
+Patch55: libvirt-util-hash-Use-g_new0-for-allocating-hash-internals.patch
+Patch56: libvirt-conf-domain-Remove-checking-of-return-value-of-virHashCreateFull.patch
+Patch57: libvirt-Remove-checking-of-return-value-of-virHashNew.patch
+Patch58: libvirt-qemuMigrationCookieAddNBD-Exit-early-if-there-are-no-disks.patch
+Patch59: libvirt-qemuMigrationCookieNBD-Extract-embedded-struct.patch
+Patch60: libvirt-qemuMigrationCookieAddNBD-Use-glib-memory-allocators.patch
+Patch61: libvirt-qemuMigrationCookieAddNBD-Move-monitor-call-out-of-the-loop.patch
+Patch62: libvirt-qemuMigrationCookieAddNBD-Use-virHashNew-and-automatic-freeing-of-virHashTablePtr.patch
+Patch63: libvirt-qemuMigrationCookieAddNBD-Remove-ret-variable-and-cleanup-label.patch
+Patch64: libvirt-qemuMigrationCookieAddNBD-Fix-filling-of-capacity-when-blockdev-is-used.patch
+Patch65: libvirt-tests-qemublock-Add-test-for-checkpoint-deletion-bitmap-merge.patch
+Patch66: libvirt-tests-qemublock-Add-few-more-test-cases-for-checkpoint-deletion.patch
+Patch67: libvirt-tests-qemublock-Add-synthetic-snapshot-checkpoint-test-data.patch
+Patch68: libvirt-qemu-checkpoint-Introduce-support-for-deleting-checkpoints-accross-snapshots.patch
+Patch69: libvirt-tests-qemublock-Add-checkpoint-deletion-test-for-deep-backing-chain.patch
+Patch70: libvirt-tests-qemublock-Add-checkpoint-deletion-tests-for-some-special-cases.patch
+Patch71: libvirt-qemu-checkpoint-Track-and-relabel-images-for-bitmap-merging.patch
+Patch72: libvirt-qemu-block-Extract-calls-of-qemuBlockGetNamedNodeData-into-a-helper-function.patch
+Patch73: libvirt-util-json-Introduce-virJSONValueArrayConcat.patch
+Patch74: libvirt-virJSONValueNewArray-Use-g_new0-to-allocate-and-remove-NULL-checks-from-callers.patch
+Patch75: libvirt-virhash-Fix-the-expectations-of-virHashKeyEqual-implementations.patch
+Patch76: libvirt-virHashAddOrUpdateEntry-Simplify-allocation-of-new-entry.patch
+Patch77: libvirt-qemu-blockjob-Store-jobflags-with-block-job-data.patch
+Patch78: libvirt-qemu-blockjob-Store-flags-for-all-the-block-job-types.patch
+Patch79: libvirt-qemu-block-Add-validator-for-bitmap-chains-accross-backing-chains.patch
+Patch80: libvirt-tests-qemublocktest-Add-another-synthetic-test-case-for-broken-bitmaps.patch
+Patch81: libvirt-qemu-block-Introduce-function-to-calculate-bitmap-handling-for-block-copy.patch
+Patch82: libvirt-tests-qemublock-Add-tests-for-qemuBlockBitmapsHandleBlockcopy.patch
+Patch83: libvirt-qemuDomainBlockPivot-Copy-bitmaps-backing-checkpoints-for-virDomainBlockCopy.patch
+Patch84: libvirt-docs-domaincaps-Mention-VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA.patch
+Patch85: libvirt-qemu-do-not-revert-to-NULL-bandwidth.patch
+Patch86: libvirt-qemu-preserve-error-on-bandwidth-rollback.patch
+Patch87: libvirt-tests-Add-capabilities-for-QEMU-5.0.0-on-aarch64.patch
+Patch88: libvirt-qemu-Use-switch-statement-in-qemuBuildCpuCommandLine.patch
+Patch89: libvirt-qemu-Add-the-QEMU_CAPS_CPU_KVM_NO_ADJVTIME-capability.patch
+Patch90: libvirt-conf-Introduce-VIR_DOMAIN_TIMER_NAME_ARMVTIMER.patch
+Patch91: libvirt-qemu-Validate-configuration-for-the-armvtimer-timer.patch
+Patch92: libvirt-qemu-Format-the-armvtimer-timer-on-the-command-line.patch
+Patch93: libvirt-tests-Add-test-case-for-the-armvtimer-timer.patch
+Patch94: libvirt-docs-List-the-armvtimer-timer-among-all-others.patch
+Patch95: libvirt-qemu_domain-Modify-access-to-a-NVMe-disk-iff-needed.patch
+Patch96: libvirt-qemuBlockStorageSourceGetBackendProps-Report-errors-on-all-switch-cases.patch
+Patch97: libvirt-virDomainDiskAddISCSIPoolSourceHost-Sanitize-handling-of-string-list.patch
+Patch98: libvirt-virDomainDiskAddISCSIPoolSourceHost-use-g_new0-instead-of-VIR_ALLOC_N.patch
+Patch99: libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-cleanup-label.patch
+Patch100: libvirt-virDomainDiskAddISCSIPoolSourceHost-Remove-ternary-operator.patch
+Patch101: libvirt-virDomainDiskAddISCSIPoolSourceHost-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
+Patch102: libvirt-virDomainDiskTranslateSourcePoolAuth-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
+Patch103: libvirt-virDomainDiskTranslateISCSIDirect-Take-virStorageSourcePtr-instead-of-virDomainDiskDefPtr.patch
+Patch104: libvirt-virDomainDiskTranslateSourcePool-split-code-to-setup-one-storage-source.patch
+Patch105: libvirt-virDomainDiskTranslateSourcePool-Translate-volume-disks-in-whole-backing-chain.patch
+Patch106: libvirt-qemuMonitorJSONBlockdevAdd-Refactor-cleanup.patch
+Patch107: libvirt-qemuMonitorJSONBlockdevDel-Refactor-cleanup.patch
+Patch108: libvirt-qemuMonitorBlockdevAdd-Take-double-pointer-argument.patch
+Patch109: libvirt-qemu-hotplug-Fix-handling-of-the-copy-on-read-layer-with-blockdev.patch
+Patch110: libvirt-virStorageSourceParseBackingJSON-Pass-around-original-backing-file-string.patch
+Patch111: libvirt-virStorageSourceParseBackingJSON-Move-deflattening-of-json-URIs-out-of-recursion.patch
+Patch112: libvirt-virStorageSourceJSONDriverParser-annotate-format-drivers.patch
+Patch113: libvirt-virStorageSourceParseBackingJSON-Allow-json-pseudo-URIs-without-file-wrapper.patch
+Patch114: libvirt-virStorageSourceParseBackingJSON-Prevent-arbitrary-nesting-with-format-drivers.patch
+Patch115: libvirt-tests-virstorage-Add-test-cases-for-json-pseudo-URI-without-file-wrapper.patch
+Patch116: libvirt-qemu-domain-Refactor-formatting-of-node-names-into-status-XML.patch
+Patch117: libvirt-docs-formatdomain-Close-source-on-one-of-disk-examples.patch
+Patch118: libvirt-tests-virstorage-Add-test-data-for-json-specified-raw-image-with-offset-size.patch
+Patch119: libvirt-util-virstoragefile-Add-data-structure-for-storing-storage-source-slices.patch
+Patch120: libvirt-qemuBlockStorageSourceGetFormatRawProps-format-offset-and-size-for-slice.patch
+Patch121: libvirt-qemuDomainValidateStorageSource-Reject-unsupported-slices.patch
+Patch122: libvirt-qemu-block-forbid-creation-of-storage-sources-with-slice.patch
+Patch123: libvirt-docs-Document-the-new-slices-sub-element-of-disk-s-source.patch
+Patch124: libvirt-conf-Implement-support-for-slices-of-disk-source.patch
+Patch125: libvirt-qemu-domain-Store-nodenames-of-slice-in-status-XML.patch
+Patch126: libvirt-qemu-block-Properly-format-storage-slice-into-backing-store-strings.patch
+Patch127: libvirt-tests-qemublock-Add-cases-for-creating-image-overlays-on-top-of-disks-with-slice.patch
+Patch128: libvirt-qemu-Add-support-for-slices-of-type-storage.patch
+Patch129: libvirt-tests-qemu-Add-test-data-for-the-new-slice-element.patch
+Patch130: libvirt-virStorageSourceParseBackingJSONRaw-Parse-offset-and-size-attributes.patch
+Patch131: libvirt-qemuDomainGetStatsIOThread-Don-t-leak-array-with-0-iothreads.patch
+Patch132: libvirt-qemuxml2xmltest-Add-case-for-host-model-vendor_id.patch
+Patch133: libvirt-cpu_conf-Format-vendor_id-for-host-model-CPUs.patch
+Patch134: libvirt-qemu-rename-qemuAgentGetFSInfoInternalDisk.patch
+Patch135: libvirt-qemu-store-complete-agent-filesystem-information.patch
+Patch136: libvirt-qemu-Don-t-store-disk-alias-in-qemuAgentDiskInfo.patch
+Patch137: libvirt-qemu-don-t-access-vmdef-within-qemu_agent.c.patch
+Patch138: libvirt-qemu-remove-qemuDomainObjBegin-EndJobWithAgent.patch
+Patch139: libvirt-docs-fix-a-typo.patch
+Patch140: libvirt-virDomainNetDefClear-Free-persistent-name.patch
+Patch141: libvirt-virSecurityManagerMetadataLock-Store-locked-paths.patch
+Patch142: libvirt-security-Don-t-remember-seclabel-for-paths-we-haven-t-locked-successfully.patch
+Patch143: libvirt-security-Don-t-fail-if-locking-a-file-on-NFS-mount-fails.patch
+Patch144: libvirt-util-storagefile-Drop-image-format-probing-by-file-suffix.patch
+Patch145: libvirt-virStorageFileGetMetadataRecurse-Remove-impossible-error-report.patch
+Patch146: libvirt-virStorageFileGetMetadataRecurse-Shuffle-around-assignment-of-backing-chain-depth.patch
+Patch147: libvirt-virStorageFileGetMetadataRecurse-Expect-NULL-src-path.patch
+Patch148: libvirt-virStorageFileGetMetadataRecurse-Use-virHashHasEntry-instead-of-fake-pointers.patch
+Patch149: libvirt-virStorageFileGetMetadataRecurse-Extract-storage-access.patch
+Patch150: libvirt-virStorageFileGetMetadataRecurse-Remove-cleanup-label.patch
+Patch151: libvirt-tests-virstorage-Fix-backing-file-format-of-created-image.patch
+Patch152: libvirt-virStorageSourceUpdateCapacity-Drop-probe-argument.patch
+Patch153: libvirt-util-storage-Store-backing-store-format-in-virStorageSource.patch
+Patch154: libvirt-virStorageSourceNewFromBacking-Also-transfer-the-format.patch
+Patch155: libvirt-virStorageBackendGlusterRefreshVol-Refactor-handling-of-backing-store.patch
+Patch156: libvirt-virStorageFileGetMetadataFromBuf-Remove-backingFormat-argument.patch
+Patch157: libvirt-virStorageFileGetMetadataFromFD-Remove-unused-backingFormat-argument.patch
+Patch158: libvirt-qemu-domain-Convert-detected-iso-image-format-into-raw.patch
+Patch159: libvirt-virStorageFileGetMetadataRecurse-Allow-format-probing-under-special-circumstances.patch
+Patch160: libvirt-kbase-backing_chains-Clarify-some-aspects-of-image-probing.patch
+Patch161: libvirt-kbase-backing_chains-Add-steps-how-to-securely-probe-image-format.patch
+Patch162: libvirt-conf-use-virXMLFormatElement-in-virDomainFSDefFormat.patch
+Patch163: libvirt-qemu-use-def-instead-of-vm-def-in-qemuExtDevicesStart.patch
+Patch164: libvirt-qemu-eliminate-ret-in-qemuExtDevicesStart.patch
+Patch165: libvirt-docs-render-class-literal-with-monospace-font.patch
+Patch166: libvirt-docs-reduce-excessive-spacing-in-ToC-for-RST-files.patch
+Patch167: libvirt-virDomainFSDefFree-Unref-private-data.patch
+Patch168: libvirt-schema-wrap-fsDriver-in-a-choice-group.patch
+Patch169: libvirt-qemuExtDevicesStart-pass-logManager.patch
+Patch170: libvirt-qemu-pass-virDomainObjPtr-to-qemuExtDevicesSetupCgroup.patch
+Patch171: libvirt-qemuxml2xmltest-set-driver-as-privileged.patch
+Patch172: libvirt-qemu-add-QEMU_CAPS_DEVICE_VHOST_USER_FS.patch
+Patch173: libvirt-docs-add-virtiofs-kbase.patch
+Patch174: libvirt-conf-qemu-add-virtiofs-fsdriver-type.patch
+Patch175: libvirt-conf-add-virtiofs-related-elements-and-attributes.patch
+Patch176: libvirt-qemu-add-virtiofsd_debug-to-qemu.conf.patch
+Patch177: libvirt-qemu-validate-virtiofs-filesystems.patch
+Patch178: libvirt-qemu-forbid-migration-with-vhost-user-fs-device.patch
+Patch179: libvirt-qemu-add-code-for-handling-virtiofsd.patch
+Patch180: libvirt-qemu-put-virtiofsd-in-the-emulator-cgroup.patch
+Patch181: libvirt-qemu-use-the-vhost-user-schemas-to-find-binary.patch
+Patch182: libvirt-qemu-build-vhost-user-fs-device-command-line.patch
+Patch183: libvirt-RHEL-virscsi-Check-device-type-before-getting-it-s-dev-node-name.patch
+Patch184: libvirt-RHEL-virscsi-Support-TAPEs-in-virSCSIDeviceGetDevName.patch
+Patch185: libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch
+Patch186: libvirt-RHEL-virutil-Accept-non-block-devices-in-virGetDeviceID.patch
+Patch187: libvirt-RHEL-qemuSetUnprivSGIO-Actually-use-calculated-sysfs_path-to-set-unpriv_sgio.patch
+Patch188: libvirt-RHEL-qemuCheckUnprivSGIO-use-sysfs_path-to-get-unpriv_sgio.patch
+Patch189: libvirt-security-Introduce-VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP-flag.patch
+Patch190: libvirt-qemu-Tell-secdrivers-which-images-are-top-parent.patch
+Patch191: libvirt-virDomainDiskTranslateSourcePool-Check-for-disk-type-correctly.patch
+Patch192: libvirt-virbuftest-remove-extra-G_GNUC_UNUSED-markers.patch
+Patch193: libvirt-virbuftest-use-g_autofree.patch
+Patch194: libvirt-virbuftest-remove-unnecessary-labels.patch
+Patch195: libvirt-virbuftest-declare-testBufAddStrData-earlier.patch
+Patch196: libvirt-virbuftest-use-field-names-when-initalizing-test-info.patch
+Patch197: libvirt-util-add-virBufferTrimChars.patch
+Patch198: libvirt-conf-do-not-generate-machine-names-ending-with-a-dash.patch
+Patch199: libvirt-conf-Don-t-generate-machine-names-with-a-dot.patch
+Patch200: libvirt-qemuAgentFSInfoFormatParams-Remove-pointless-returned-value.patch
+Patch201: libvirt-qemuDomainGetGuestInfo-Don-t-try-to-free-a-negative-number-of-entries.patch
+Patch202: libvirt-qemuDomainBlockPivot-Move-check-prior-to-executing-the-pivot-steps.patch
+Patch203: libvirt-qemuDomainBlockCopyCommon-Record-updated-flags-to-block-job.patch
+Patch204: libvirt-qemu-capabilities-Introduce-QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY.patch
+Patch205: libvirt-qemu-blockcopy-Allow-late-opening-of-the-backing-chain-of-a-shallow-copy.patch
+Patch206: libvirt-qemuBlockStorageSourceDetachPrepare-Get-rid-of-cleanup-section.patch
+Patch207: libvirt-qemu-Don-t-take-double-pointer-in-qemuDomainSecretInfoFree.patch
+Patch208: libvirt-qemuMigrationParamsResetTLS-Adapt-to-modern-memory-management.patch
+Patch209: libvirt-qemuMigrationParamsResetTLS-Fix-comment.patch
+Patch210: libvirt-qemuDomainSecretInfo-Register-autoptr-cleanup-function.patch
+Patch211: libvirt-qemuDomainSecretAESSetup-Automatically-free-non-secret-locals.patch
+Patch212: libvirt-qemuDomainSecretAESSetup-Allocate-and-return-secinfo-here.patch
+Patch213: libvirt-qemuDomainSecretAESSetup-Split-out-lookup-of-secret-data.patch
+Patch214: libvirt-Remove-qemuDomainSecretInfoNew.patch
+Patch215: libvirt-qemu-Introduce-another-helper-for-creating-alias-for-a-secret-object.patch
+Patch216: libvirt-qemuDomainSecretStorageSourcePrepare-Fix-naming-of-alias-variables.patch
+Patch217: libvirt-qemuDomainDeviceDiskDefPostParseRestoreSecAlias-Hardcode-restored-aliases.patch
+Patch218: libvirt-qemu-Split-out-initialization-of-secrets-for-iscsi-hostdevs.patch
+Patch219: libvirt-qemuDomainSecretAESSetupFromSecret-Use-qemuAliasForSecret.patch
+Patch220: libvirt-qemuDomainSecretStorageSourcePrepare-Change-aliases-for-disk-secrets.patch
+Patch221: libvirt-qemuDomainGetSecretAESAlias-Replace-outstanding-uses-with-qemuAliasForSecret.patch
+Patch222: libvirt-conf-Add-support-for-modifying-ssl-validation-for-https-ftps-disks.patch
+Patch223: libvirt-conf-Add-support-for-cookies-for-HTTP-based-disks.patch
+Patch224: libvirt-conf-Add-support-for-setting-timeout-and-readahead-size-for-network-disks.patch
+Patch225: libvirt-qemuDomainValidateStorageSource-Validate-new-network-storage-parameters.patch
+Patch226: libvirt-qemuxml2argvtest-Add-test-case-for-disks-with-http-s-source.patch
+Patch227: libvirt-qemu-block-Implement-ssl-verification-configuration.patch
+Patch228: libvirt-qemu-domain-Store-data-for-secret-object-representing-http-cookies.patch
+Patch229: libvirt-qemuDomainSecretStorageSourcePrepare-Setup-secret-for-http-cookies.patch
+Patch230: libvirt-qemu-Handle-hotplug-and-commandline-for-secret-objects-for-http-cookies.patch
+Patch231: libvirt-qemu-block-Add-support-for-HTTP-cookies.patch
+Patch232: libvirt-qemu-block-Implement-readahead-and-timeout-properties-for-curl-driver.patch
+Patch233: libvirt-virstoragefile-Add-JSON-parser-for-sslverify-readahead-cookies-and-timeout.patch
+Patch234: libvirt-virStorageSourceParseBackingJSONUri-Handle-undocumented-value-off-for-sslverify.patch
+Patch235: libvirt-qemublocktest-Load-QMP-schema-earlier.patch
+Patch236: libvirt-qemublocktest-Extract-schema-root-for-blockdev-add-validation.patch
+Patch237: libvirt-qemublocktest-XMLjsonXML-Test-formatting-parsing-of-modern-JSON.patch
+Patch238: libvirt-qemublocktest-Add-JSON-JSON-test-cases-for-block-device-backends.patch
+Patch239: libvirt-qemu-Pass-through-arguments-of-ssh-block-driver-used-by-libguestfs.patch
+Patch240: libvirt-qemu-capabilities-Add-QEMU_CAPS_BLOCKDEV_REOPEN.patch
+Patch241: libvirt-qemu-monitor-Add-handler-for-blockdev-reopen.patch
+Patch242: libvirt-qemu-block-implement-helpers-for-blockdev-reopen.patch
+Patch243: libvirt-qemuCheckpointDiscardBitmaps-Reopen-images-for-bitmap-modifications.patch
+Patch244: libvirt-qemuCheckpointDiscardBitmaps-Use-correct-field-for-checkpoint-bitmap-name.patch
+Patch245: libvirt-qemuDomainBlockCommit-Move-checks-depending-on-capabilities-after-liveness-check.patch
+Patch246: libvirt-qemu-domain-Extract-formatting-of-commit-blockjob-data-into-a-function.patch
+Patch247: libvirt-qemu-domain-Extract-parsing-of-commit-blockjob-data-into-a-function.patch
+Patch248: libvirt-qemu-blockjob-Store-list-of-bitmaps-disabled-prior-to-commit.patch
+Patch249: libvirt-qemublocktest-Fix-and-optimize-fake-image-chain.patch
+Patch250: libvirt-qemu-block-Implement-helpers-for-dealing-with-bitmaps-during-block-commit.patch
+Patch251: libvirt-qemublocktest-Add-tests-for-handling-of-bitmaps-during-block-commit.patch
+Patch252: libvirt-qemublocktest-Add-more-tests-for-block-commit-bitmap-handling-with-snapshots.patch
+Patch253: libvirt-qemublocktest-Add-tests-of-broken-bitmap-chain-handling-during-block-commit.patch
+Patch254: libvirt-qemuBlockJobDiskNewCommit-Propagate-disabledBitmapsBase.patch
+Patch255: libvirt-qemuDomainBlockCommit-Handle-bitmaps-on-start-of-commit.patch
+Patch256: libvirt-qemuDomainBlockPivot-Handle-merging-of-bitmaps-when-pivoting-an-active-block-commit.patch
+Patch257: libvirt-qemu-blockjob-Handle-bitmaps-after-finish-of-normal-block-commit.patch
+Patch258: libvirt-qemu-blockjob-Re-enable-bitmaps-after-failed-block-commit.patch
+Patch259: libvirt-qemuDomainGetGuestInfo-don-t-assign-NULL-hostname.patch
+Patch260: libvirt-rhel-Enable-usage-of-x-blockdev-reopen.patch
+Patch261: libvirt-qemuBlockBitmapsHandleCommitStart-Fix-allocation-of-string-list.patch
+Patch262: libvirt-qemuBlockBitmapsHandleCommitFinish-Use-proper-variable-to-iterate.patch
+Patch263: libvirt-qemublocktest-Add-tests-for-re-enabling-of-bitmaps-after-commit.patch
+Patch264: libvirt-qemu-Create-multipath-targets-for-PRs.patch
+Patch265: libvirt-qemu-Don-t-crash-when-getting-targets-for-a-multipath.patch
+Patch266: libvirt-virSecretLookupDefCopy-Remove-return-value.patch
+Patch267: libvirt-virStorageEncryptionSecretCopy-Properly-copy-internals.patch
+Patch268: libvirt-vmx-shortcut-earlier-few-ignore-cases-in-virVMXParseDisk.patch
+Patch269: libvirt-vmx-make-fileName-optional-for-CD-ROMs.patch
+Patch270: libvirt-qemublocktest-Backport-cleanups-for-testQemuDiskXMLToProps-from-dd94f36ffbe.patch
+Patch271: libvirt-conf-rename-namespace-property-of-struct-_virStorageSourceNVMeDef.patch
+Patch272: libvirt-qemublocktest-xml-json-Add-test-for-NVMe.patch
+Patch273: libvirt-virDomainDiskSourceNVMeFormat-Format-only-valid-managed-values.patch
+Patch274: libvirt-qemublocktest-xml-json-Refactor-cleanup-in-test-case-functions.patch
+Patch275: libvirt-testQemuDiskXMLToPropsValidateFileSrcOnly-Move-together-with-rest-of-xml-json-code.patch
+Patch276: libvirt-qemuBlockGetBackingStoreString-Add-pretty-argument.patch
+Patch277: libvirt-testQemuDiskXMLToProps-Store-all-per-image-data-in-one-structure.patch
+Patch278: libvirt-qemublocktest-Test-backing-store-strings.patch
+Patch279: libvirt-qemuBlockGetBackingStoreString-Remove-ret-variable.patch
+Patch280: libvirt-storage-Implement-backing-store-support-for-fat-prefix.patch
+Patch281: libvirt-qemuBlockGetBackingStoreString-Add-extra-wrapping-object-to-JSON-strings.patch
+Patch282: libvirt-qemu-block-Extract-formatting-of-cookie-string.patch
+Patch283: libvirt-qemuBlockGetBackingStoreString-Properly-handle-http-s-with-cookies-and-others.patch
+Patch284: libvirt-storage-Parse-nvme-disk-source-properties-from-json-pseudo-uri.patch
+Patch285: libvirt-qemu-virtiofs-shorten-pid-filename.patch
+Patch286: libvirt-qemu-virtiofs-shorten-socket-filename.patch
+Patch287: libvirt-api-disallow-virDomainAgentSetResponseTimeout-on-read-only-connections.patch
+Patch288: libvirt-qemuBackupBegin-Fix-monitor-access-when-rolling-back-due-to-failure.patch
+Patch289: libvirt-qemuxml2xmltest-Wire-up-disk-network-http-case.patch
+Patch290: libvirt-virStorageSourceNetCookieValidate-Accept-quoted-cookie-value.patch
+Patch291: libvirt-qemu-block-Support-VIR_DOMAIN_BLOCK_COMMIT-PULL-REBASE_RELATIVE-with-blockdev.patch
+Patch292: libvirt-qemuDomainSnapshotDiskPrepareOne-Don-t-load-the-relative-path-with-blockdev.patch
+Patch293: libvirt-docs-formatdomain-Mention-missing-protocols.patch
+Patch294: libvirt-schemas-rng-Use-interleave-in-the-disk-source-element.patch
+Patch295: libvirt-conf-Add-support-for-http-s-query-strings.patch
+Patch296: libvirt-qemuBlockStorageSourceGetURI-Pass-through-query-component.patch
+Patch297: libvirt-virStorageSourceParseBackingURI-Preserve-query-string-of-URI-for-http-s.patch
+Patch298: libvirt-qemuDomainSnapshotDiskPrepareOne-Fix-logic-of-relative-backing-store-update.patch
+Patch299: libvirt-qemuCheckpointCreateXML-Check-VM-liveness-first.patch
+Patch300: libvirt-qemu-checkpoint-Allow-checkpoint-redefine-for-offline-VMs.patch
+Patch301: libvirt-virDomainCheckpointRedefinePrep-Set-current-checkpoint-if-there-isn-t-any.patch
+
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-daemon-config-network = %{version}-%{release}
+Requires: libvirt-daemon-config-nwfilter = %{version}-%{release}
+%if %{with_libxl}
+Requires: libvirt-daemon-driver-libxl = %{version}-%{release}
+%endif
+%if %{with_lxc}
+Requires: libvirt-daemon-driver-lxc = %{version}-%{release}
+%endif
+%if %{with_qemu}
+Requires: libvirt-daemon-driver-qemu = %{version}-%{release}
+%endif
+# We had UML driver, but we've removed it.
+Obsoletes: libvirt-daemon-driver-uml <= 5.0.0
+Obsoletes: libvirt-daemon-uml <= 5.0.0
+%if %{with_vbox}
+Requires: libvirt-daemon-driver-vbox = %{version}-%{release}
+%endif
+Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
+
+Requires: libvirt-daemon-driver-interface = %{version}-%{release}
+Requires: libvirt-daemon-driver-secret = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage = %{version}-%{release}
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+Requires: libvirt-daemon-driver-nodedev = %{version}-%{release}
+Requires: libvirt-client = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+
+# All build-time requirements. Run-time requirements are
+# listed against each sub-RPM
+%if 0%{?enable_autotools}
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: gettext-devel
+BuildRequires: libtool
+%endif
+%if 0%{?rhel} == 7
+BuildRequires: python36-docutils
+%else
+BuildRequires: python3-docutils
+%endif
+BuildRequires: gcc
+BuildRequires: git
+%if 0%{?fedora} || 0%{?rhel} > 7
+BuildRequires: perl-interpreter
+%else
+BuildRequires: perl
+%endif
+%if 0%{?rhel} > 7
+BuildRequires: python3-devel
+%else
+BuildRequires: python3
+%endif
+BuildRequires: systemd-units
+%if %{with_libxl}
+BuildRequires: xen-devel
+%endif
+BuildRequires: glib2-devel >= 2.48
+BuildRequires: libxml2-devel
+BuildRequires: libxslt
+BuildRequires: readline-devel
+%if %{with_bash_completion}
+BuildRequires: bash-completion >= 2.0
+%endif
+BuildRequires: ncurses-devel
+BuildRequires: gettext
+BuildRequires: libtasn1-devel
+BuildRequires: gnutls-devel
+BuildRequires: libattr-devel
+# For pool-build probing for existing pools
+BuildRequires: libblkid-devel >= 2.17
+# for augparse, optionally used in testing
+BuildRequires: augeas
+BuildRequires: systemd-devel >= 185
+BuildRequires: libpciaccess-devel >= 0.10.9
+BuildRequires: yajl-devel
+%if %{with_sanlock}
+BuildRequires: sanlock-devel >= 2.4
+%endif
+BuildRequires: libpcap-devel
+BuildRequires: libnl3-devel
+BuildRequires: libselinux-devel
+BuildRequires: dnsmasq >= 2.41
+BuildRequires: iptables
+BuildRequires: radvd
+BuildRequires: ebtables
+BuildRequires: module-init-tools
+BuildRequires: cyrus-sasl-devel
+BuildRequires: polkit >= 0.112
+# For mount/umount in FS driver
+BuildRequires: util-linux
+%if %{with_qemu}
+# For managing ACLs
+BuildRequires: libacl-devel
+# From QEMU RPMs
+BuildRequires: /usr/bin/qemu-img
+%endif
+# For LVM drivers
+BuildRequires: lvm2
+# For pool type=iscsi
+BuildRequires: iscsi-initiator-utils
+%if %{with_storage_iscsi_direct}
+# For pool type=iscsi-direct
+BuildRequires: libiscsi-devel
+%endif
+# For disk driver
+BuildRequires: parted-devel
+# For Multipath support
+BuildRequires: device-mapper-devel
+# For XFS reflink clone support
+BuildRequires: xfsprogs-devel
+%if %{with_storage_rbd}
+    %if 0%{?fedora} || 0%{?rhel} > 7
+BuildRequires: librados-devel
+BuildRequires: librbd-devel
+    %else
+BuildRequires: librados2-devel
+BuildRequires: librbd1-devel
+    %endif
+%endif
+%if %{with_storage_gluster}
+BuildRequires: glusterfs-api-devel >= 3.4.1
+BuildRequires: glusterfs-devel >= 3.4.1
+%endif
+%if %{with_storage_sheepdog}
+BuildRequires: sheepdog
+%endif
+%if %{with_storage_zfs}
+# Support any conforming implementation of zfs. On stock Fedora
+# this is zfs-fuse, but could be zfsonlinux upstream RPMs
+BuildRequires: /sbin/zfs
+BuildRequires: /sbin/zpool
+%endif
+%if %{with_numactl}
+# For QEMU/LXC numa info
+BuildRequires: numactl-devel
+%endif
+BuildRequires: libcap-ng-devel >= 0.5.0
+%if %{with_fuse}
+BuildRequires: fuse-devel >= 2.8.6
+%endif
+%if %{with_libssh2}
+BuildRequires: libssh2-devel >= 1.3.0
+%endif
+
+BuildRequires: netcf-devel >= 0.2.2
+%if %{with_esx}
+BuildRequires: libcurl-devel
+%endif
+%if %{with_hyperv}
+BuildRequires: libwsman-devel >= 2.2.3
+%endif
+BuildRequires: audit-libs-devel
+# we need /usr/sbin/dtrace
+BuildRequires: systemtap-sdt-devel
+
+# For mount/umount in FS driver
+BuildRequires: util-linux
+# For showmount in FS driver (netfs discovery)
+BuildRequires: nfs-utils
+
+# Communication with the firewall and polkit daemons use DBus
+BuildRequires: dbus-devel
+
+# Fedora build root suckage
+BuildRequires: gawk
+
+# For storage wiping with different algorithms
+BuildRequires: scrub
+
+%if %{with_numad}
+BuildRequires: numad
+%endif
+
+%if %{with_wireshark}
+BuildRequires: wireshark-devel >= 2.4.0
+%endif
+
+%if %{with_libssh}
+BuildRequires: libssh-devel >= 0.7.0
+%endif
+
+%if 0%{?fedora} || 0%{?rhel} > 7
+BuildRequires: rpcgen
+BuildRequires: libtirpc-devel
+%endif
+
+%if %{with_firewalld_zone}
+BuildRequires: firewalld-filesystem
+%endif
+
+Provides: bundled(gnulib)
+
+%description
+Libvirt is a C toolkit to interact with the virtualization capabilities
+of recent versions of Linux (and other OSes). The main package includes
+the libvirtd server exporting the virtualization support.
+
+%package docs
+Summary: API reference and website documentation
+
+%description docs
+Includes the API reference for the libvirt C library, and a complete
+copy of the libvirt.org website documentation.
+
+%package daemon
+Summary: Server side daemon and supporting files for libvirt library
+
+# All runtime requirements for the libvirt package (runtime requrements
+# for subpackages are listed later in those subpackages)
+
+# The client side, i.e. shared libs are in a subpackage
+Requires: %{name}-libs = %{version}-%{release}
+
+# (client invokes 'nc' against the UNIX socket on the server)
+Requires: /usr/bin/nc
+
+# for modprobe of pci devices
+Requires: module-init-tools
+
+# for /sbin/ip & /sbin/tc
+Requires: iproute
+# tc is provided by iproute-tc since at least Fedora 26
+%if 0%{?fedora} || 0%{?rhel} > 7
+Requires: iproute-tc
+%endif
+
+Requires: polkit >= 0.112
+%ifarch %{ix86} x86_64 ia64
+# For virConnectGetSysinfo
+Requires: dmidecode
+%endif
+# For service management
+Requires(post): systemd-units
+Requires(post): systemd-sysv
+Requires(preun): systemd-units
+Requires(postun): systemd-units
+%if %{with_numad}
+Requires: numad
+%endif
+# libvirtd depends on 'messagebus' service
+Requires: dbus
+# For uid creation during pre
+Requires(pre): shadow-utils
+
+%description daemon
+Server side daemon required to manage the virtualization capabilities
+of recent versions of Linux. Requires a hypervisor specific sub-RPM
+for specific drivers.
+
+%package daemon-config-network
+Summary: Default configuration files for the libvirtd daemon
+
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+
+%description daemon-config-network
+Default configuration files for setting up NAT based networking
+
+%package daemon-config-nwfilter
+Summary: Network filter configuration files for the libvirtd daemon
+
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
+
+%description daemon-config-nwfilter
+Network filter configuration files for cleaning guest traffic
+
+%package daemon-driver-network
+Summary: Network driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: dnsmasq >= 2.41
+Requires: radvd
+Requires: iptables
+
+%description daemon-driver-network
+The network driver plugin for the libvirtd daemon, providing
+an implementation of the virtual network APIs using the Linux
+bridge capabilities.
+
+
+%package daemon-driver-nwfilter
+Summary: Nwfilter driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: iptables
+Requires: ebtables
+
+%description daemon-driver-nwfilter
+The nwfilter driver plugin for the libvirtd daemon, providing
+an implementation of the firewall APIs using the ebtables,
+iptables and ip6tables capabilities
+
+
+%package daemon-driver-nodedev
+Summary: Nodedev driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+# needed for device enumeration
+Requires: systemd >= 185
+
+%description daemon-driver-nodedev
+The nodedev driver plugin for the libvirtd daemon, providing
+an implementation of the node device APIs using the udev
+capabilities.
+
+
+%package daemon-driver-interface
+Summary: Interface driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: netcf-libs >= 0.2.2
+
+%description daemon-driver-interface
+The interface driver plugin for the libvirtd daemon, providing
+an implementation of the network interface APIs using the
+netcf library
+
+
+%package daemon-driver-secret
+Summary: Secret driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+
+%description daemon-driver-secret
+The secret driver plugin for the libvirtd daemon, providing
+an implementation of the secret key APIs.
+
+%package daemon-driver-storage-core
+Summary: Storage driver plugin including base backends for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: nfs-utils
+# For mkfs
+Requires: util-linux
+%if %{with_qemu}
+# From QEMU RPMs
+Requires: /usr/bin/qemu-img
+%endif
+%if !%{with_storage_rbd}
+Obsoletes: libvirt-daemon-driver-storage-rbd < %{version}-%{release}
+%endif
+
+%description daemon-driver-storage-core
+The storage driver plugin for the libvirtd daemon, providing
+an implementation of the storage APIs using files, local disks, LVM, SCSI,
+iSCSI, and multipath storage.
+
+%package daemon-driver-storage-logical
+Summary: Storage driver plugin for lvm volumes
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: lvm2
+
+%description daemon-driver-storage-logical
+The storage driver backend adding implementation of the storage APIs for block
+volumes using lvm.
+
+
+%package daemon-driver-storage-disk
+Summary: Storage driver plugin for disk
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: parted
+Requires: device-mapper
+
+%description daemon-driver-storage-disk
+The storage driver backend adding implementation of the storage APIs for block
+volumes using the host disks.
+
+
+%package daemon-driver-storage-scsi
+Summary: Storage driver plugin for local scsi devices
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+
+%description daemon-driver-storage-scsi
+The storage driver backend adding implementation of the storage APIs for scsi
+host devices.
+
+
+%package daemon-driver-storage-iscsi
+Summary: Storage driver plugin for iscsi
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: iscsi-initiator-utils
+
+%description daemon-driver-storage-iscsi
+The storage driver backend adding implementation of the storage APIs for iscsi
+volumes using the host iscsi stack.
+
+
+%if %{with_storage_iscsi_direct}
+%package daemon-driver-storage-iscsi-direct
+Summary: Storage driver plugin for iscsi-direct
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: libiscsi
+
+%description daemon-driver-storage-iscsi-direct
+The storage driver backend adding implementation of the storage APIs for iscsi
+volumes using libiscsi direct connection.
+%endif
+
+
+%package daemon-driver-storage-mpath
+Summary: Storage driver plugin for multipath volumes
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: device-mapper
+
+%description daemon-driver-storage-mpath
+The storage driver backend adding implementation of the storage APIs for
+multipath storage using device mapper.
+
+
+%if %{with_storage_gluster}
+%package daemon-driver-storage-gluster
+Summary: Storage driver plugin for gluster
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+    %if 0%{?fedora}
+Requires: glusterfs-client >= 2.0.1
+    %endif
+    %if (0%{?fedora} || 0%{?with_storage_gluster})
+Requires: /usr/sbin/gluster
+    %endif
+
+%description daemon-driver-storage-gluster
+The storage driver backend adding implementation of the storage APIs for gluster
+volumes using libgfapi.
+%endif
+
+
+%if %{with_storage_rbd}
+%package daemon-driver-storage-rbd
+Summary: Storage driver plugin for rbd
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+
+%description daemon-driver-storage-rbd
+The storage driver backend adding implementation of the storage APIs for rbd
+volumes using the ceph protocol.
+%endif
+
+
+%if %{with_storage_sheepdog}
+%package daemon-driver-storage-sheepdog
+Summary: Storage driver plugin for sheepdog
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: sheepdog
+
+%description daemon-driver-storage-sheepdog
+The storage driver backend adding implementation of the storage APIs for
+sheepdog volumes using.
+%endif
+
+
+%if %{with_storage_zfs}
+%package daemon-driver-storage-zfs
+Summary: Storage driver plugin for ZFS
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+# Support any conforming implementation of zfs
+Requires: /sbin/zfs
+Requires: /sbin/zpool
+
+%description daemon-driver-storage-zfs
+The storage driver backend adding implementation of the storage APIs for
+ZFS volumes.
+%endif
+
+
+%package daemon-driver-storage
+Summary: Storage driver plugin including all backends for the libvirtd daemon
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage-disk = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage-logical = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage-scsi = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage-iscsi = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage-mpath = %{version}-%{release}
+%if %{with_storage_iscsi_direct}
+Requires: libvirt-daemon-driver-storage-iscsi-direct = %{version}-%{release}
+%endif
+%if %{with_storage_gluster}
+Requires: libvirt-daemon-driver-storage-gluster = %{version}-%{release}
+%endif
+%if %{with_storage_rbd}
+Requires: libvirt-daemon-driver-storage-rbd = %{version}-%{release}
+%endif
+%if %{with_storage_sheepdog}
+Requires: libvirt-daemon-driver-storage-sheepdog = %{version}-%{release}
+%endif
+%if %{with_storage_zfs}
+Requires: libvirt-daemon-driver-storage-zfs = %{version}-%{release}
+%endif
+
+%description daemon-driver-storage
+The storage driver plugin for the libvirtd daemon, providing
+an implementation of the storage APIs using LVM, iSCSI,
+parted and more.
+
+
+%if %{with_qemu}
+%package daemon-driver-qemu
+Summary: QEMU driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Requires: /usr/bin/qemu-img
+# For image compression
+Requires: gzip
+Requires: bzip2
+Requires: lzop
+Requires: xz
+    %if 0%{?fedora} || 0%{?rhel} > 7
+Requires: systemd-container
+    %endif
+
+%description daemon-driver-qemu
+The qemu driver plugin for the libvirtd daemon, providing
+an implementation of the hypervisor driver APIs using
+QEMU
+%endif
+
+
+%if %{with_lxc}
+%package daemon-driver-lxc
+Summary: LXC driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+# There really is a hard cross-driver dependency here
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+    %if 0%{?fedora} || 0%{?rhel} > 7
+Requires: systemd-container
+    %endif
+
+%description daemon-driver-lxc
+The LXC driver plugin for the libvirtd daemon, providing
+an implementation of the hypervisor driver APIs using
+the Linux kernel
+%endif
+
+
+%if %{with_vbox}
+%package daemon-driver-vbox
+Summary: VirtualBox driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+
+%description daemon-driver-vbox
+The vbox driver plugin for the libvirtd daemon, providing
+an implementation of the hypervisor driver APIs using
+VirtualBox
+%endif
+
+
+%if %{with_libxl}
+%package daemon-driver-libxl
+Summary: Libxl driver plugin for the libvirtd daemon
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-libs = %{version}-%{release}
+Obsoletes: libvirt-daemon-driver-xen < 4.3.0
+
+%description daemon-driver-libxl
+The Libxl driver plugin for the libvirtd daemon, providing
+an implementation of the hypervisor driver APIs using
+Libxl
+%endif
+
+
+
+%if %{with_qemu_tcg}
+%package daemon-qemu
+Summary: Server side daemon & driver required to run QEMU guests
+
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-daemon-driver-qemu = %{version}-%{release}
+Requires: libvirt-daemon-driver-interface = %{version}-%{release}
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+Requires: libvirt-daemon-driver-nodedev = %{version}-%{release}
+Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
+Requires: libvirt-daemon-driver-secret = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage = %{version}-%{release}
+Requires: qemu
+
+%description daemon-qemu
+Server side daemon and driver required to manage the virtualization
+capabilities of the QEMU TCG emulators
+%endif
+
+
+%if %{with_qemu_kvm}
+%package daemon-kvm
+Summary: Server side daemon & driver required to run KVM guests
+
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-daemon-driver-qemu = %{version}-%{release}
+Requires: libvirt-daemon-driver-interface = %{version}-%{release}
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+Requires: libvirt-daemon-driver-nodedev = %{version}-%{release}
+Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
+Requires: libvirt-daemon-driver-secret = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage = %{version}-%{release}
+Requires: qemu-kvm
+
+%description daemon-kvm
+Server side daemon and driver required to manage the virtualization
+capabilities of the KVM hypervisor
+%endif
+
+
+%if %{with_lxc}
+%package daemon-lxc
+Summary: Server side daemon & driver required to run LXC guests
+
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-daemon-driver-lxc = %{version}-%{release}
+Requires: libvirt-daemon-driver-interface = %{version}-%{release}
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+Requires: libvirt-daemon-driver-nodedev = %{version}-%{release}
+Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
+Requires: libvirt-daemon-driver-secret = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage = %{version}-%{release}
+
+%description daemon-lxc
+Server side daemon and driver required to manage the virtualization
+capabilities of LXC
+%endif
+
+
+%if %{with_libxl}
+%package daemon-xen
+Summary: Server side daemon & driver required to run XEN guests
+
+Requires: libvirt-daemon = %{version}-%{release}
+    %if %{with_libxl}
+Requires: libvirt-daemon-driver-libxl = %{version}-%{release}
+    %endif
+Requires: libvirt-daemon-driver-interface = %{version}-%{release}
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+Requires: libvirt-daemon-driver-nodedev = %{version}-%{release}
+Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
+Requires: libvirt-daemon-driver-secret = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage = %{version}-%{release}
+Requires: xen
+
+%description daemon-xen
+Server side daemon and driver required to manage the virtualization
+capabilities of XEN
+%endif
+
+%if %{with_vbox}
+%package daemon-vbox
+Summary: Server side daemon & driver required to run VirtualBox guests
+
+Requires: libvirt-daemon = %{version}-%{release}
+Requires: libvirt-daemon-driver-vbox = %{version}-%{release}
+Requires: libvirt-daemon-driver-interface = %{version}-%{release}
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+Requires: libvirt-daemon-driver-nodedev = %{version}-%{release}
+Requires: libvirt-daemon-driver-nwfilter = %{version}-%{release}
+Requires: libvirt-daemon-driver-secret = %{version}-%{release}
+Requires: libvirt-daemon-driver-storage = %{version}-%{release}
+
+%description daemon-vbox
+Server side daemon and driver required to manage the virtualization
+capabilities of VirtualBox
+%endif
+
+%package client
+Summary: Client side utilities of the libvirt library
+Requires: %{name}-libs = %{version}-%{release}
+Requires: readline
+Requires: ncurses
+# Needed by /usr/libexec/libvirt-guests.sh script.
+Requires: gettext
+# Needed by virt-pki-validate script.
+Requires: gnutls-utils
+%if %{with_bash_completion}
+Requires: %{name}-bash-completion = %{version}-%{release}
+%endif
+
+%description client
+The client binaries needed to access the virtualization
+capabilities of recent versions of Linux (and other OSes).
+
+%package libs
+Summary: Client side libraries
+# So remote clients can access libvirt over SSH tunnel
+Requires: cyrus-sasl
+# Needed by default sasl.conf - no onerous extra deps, since
+# 100's of other things on a system already pull in krb5-libs
+Requires: cyrus-sasl-gssapi
+
+%description libs
+Shared libraries for accessing the libvirt daemon.
+
+%package admin
+Summary: Set of tools to control libvirt daemon
+Requires: %{name}-libs = %{version}-%{release}
+Requires: readline
+%if %{with_bash_completion}
+Requires: %{name}-bash-completion = %{version}-%{release}
+%endif
+
+%description admin
+The client side utilities to control the libvirt daemon.
+
+%if %{with_bash_completion}
+%package bash-completion
+Summary: Bash completion script
+
+%description bash-completion
+Bash completion script stub.
+%endif
+
+%if %{with_wireshark}
+%package wireshark
+Summary: Wireshark dissector plugin for libvirt RPC transactions
+Requires: wireshark >= 2.4.0
+Requires: %{name}-libs = %{version}-%{release}
+
+%description wireshark
+Wireshark dissector plugin for better analysis of libvirt RPC traffic.
+%endif
+
+%if %{with_lxc}
+%package login-shell
+Summary: Login shell for connecting users to an LXC container
+Requires: %{name}-libs = %{version}-%{release}
+
+%description login-shell
+Provides the set-uid virt-login-shell binary that is used to
+connect a user to an LXC container when they login, by switching
+namespaces.
+%endif
+
+%package devel
+Summary: Libraries, includes, etc. to compile with the libvirt library
+Requires: %{name}-libs = %{version}-%{release}
+Requires: pkgconfig
+
+%description devel
+Include header files & development libraries for the libvirt C library.
+
+%if %{with_sanlock}
+%package lock-sanlock
+Summary: Sanlock lock manager plugin for QEMU driver
+Requires: sanlock >= 2.4
+#for virt-sanlock-cleanup require augeas
+Requires: augeas
+Requires: %{name}-daemon = %{version}-%{release}
+Requires: %{name}-libs = %{version}-%{release}
+
+%description lock-sanlock
+Includes the Sanlock lock manager plugin for the QEMU
+driver
+%endif
+
+%package nss
+Summary: Libvirt plugin for Name Service Switch
+Requires: libvirt-daemon-driver-network = %{version}-%{release}
+
+%description nss
+Libvirt plugin for NSS for translating domain names into IP addresses.
+
+
+%prep
+
+%autosetup -S git_am -N
+
+# "make dist" replaces all symlinks with a copy of the linked files;
+# we need to replace all of them with the original symlinks
+echo "Restoring symlinks"
+while read lnk target; do
+    if [ -e $lnk ]; then
+        rm -rf $lnk
+        ln -s $target $lnk
+    fi
+done <%{_sourcedir}/symlinks || exit 1
+git add .
+git commit -q -a --author 'rpm-build <rpm-build>' -m symlinks
+
+
+git config gc.auto 0
+
+%autopatch
+
+%build
+%if ! %{supported_platform}
+echo "This RPM requires either Fedora >= %{min_fedora} or RHEL >= %{min_rhel}"
+exit 1
+%endif
+
+%if %{with_qemu}
+    %define arg_qemu --with-qemu
+%else
+    %define arg_qemu --without-qemu
+%endif
+
+%if %{with_openvz}
+    %define arg_openvz --with-openvz
+%else
+    %define arg_openvz --without-openvz
+%endif
+
+%if %{with_lxc}
+    %define arg_lxc --with-lxc
+    %define arg_login_shell --with-login-shell
+%else
+    %define arg_lxc --without-lxc
+    %define arg_login_shell --without-login-shell
+%endif
+
+%if %{with_vbox}
+    %define arg_vbox --with-vbox
+%else
+    %define arg_vbox --without-vbox
+%endif
+
+%if %{with_libxl}
+    %define arg_libxl --with-libxl
+%else
+    %define arg_libxl --without-libxl
+%endif
+
+%if %{with_esx}
+    %define arg_esx --with-esx
+%else
+    %define arg_esx --without-esx
+%endif
+
+%if %{with_hyperv}
+    %define arg_hyperv --with-hyperv
+%else
+    %define arg_hyperv --without-hyperv
+%endif
+
+%if %{with_vmware}
+    %define arg_vmware --with-vmware
+%else
+    %define arg_vmware --without-vmware
+%endif
+
+%if %{with_storage_rbd}
+    %define arg_storage_rbd --with-storage-rbd
+%else
+    %define arg_storage_rbd --without-storage-rbd
+%endif
+
+%if %{with_storage_sheepdog}
+    %define arg_storage_sheepdog --with-storage-sheepdog
+%else
+    %define arg_storage_sheepdog --without-storage-sheepdog
+%endif
+
+%if %{with_storage_gluster}
+    %define arg_storage_gluster --with-storage-gluster
+%else
+    %define arg_storage_gluster --without-storage-gluster
+%endif
+
+%if %{with_storage_zfs}
+    %define arg_storage_zfs --with-storage-zfs
+%else
+    %define arg_storage_zfs --without-storage-zfs
+%endif
+
+%if %{with_numactl}
+    %define arg_numactl --with-numactl
+%else
+    %define arg_numactl --without-numactl
+%endif
+
+%if %{with_numad}
+    %define arg_numad --with-numad
+%else
+    %define arg_numad --without-numad
+%endif
+
+%if %{with_fuse}
+    %define arg_fuse --with-fuse
+%else
+    %define arg_fuse --without-fuse
+%endif
+
+%if %{with_sanlock}
+    %define arg_sanlock --with-sanlock
+%else
+    %define arg_sanlock --without-sanlock
+%endif
+
+%if %{with_firewalld}
+    %define arg_firewalld --with-firewalld
+%else
+    %define arg_firewalld --without-firewalld
+%endif
+
+%if %{with_firewalld_zone}
+    %define arg_firewalld_zone --with-firewalld-zone
+%else
+    %define arg_firewalld_zone --without-firewalld-zone
+%endif
+
+%if %{with_wireshark}
+    %define arg_wireshark --with-wireshark-dissector
+%else
+    %define arg_wireshark --without-wireshark-dissector
+%endif
+
+%if %{with_storage_iscsi_direct}
+    %define arg_storage_iscsi_direct --with-storage-iscsi-direct
+%else
+    %define arg_storage_iscsi_direct --without-storage-iscsi-direct
+%endif
+
+%define when  %(date +"%%F-%%T")
+%define where %(hostname)
+%define who   %{?packager}%{!?packager:Unknown}
+%define arg_packager --with-packager="%{who}, %{when}, %{where}"
+%define arg_packager_version --with-packager-version="%{release}"
+
+%define arg_selinux_mount --with-selinux-mount="/sys/fs/selinux"
+
+# place macros above and build commands below this comment
+
+export SOURCE_DATE_EPOCH=$(stat --printf='%Y' %{_specdir}/%{name}.spec)
+
+%if 0%{?enable_autotools}
+ autoreconf -if
+%endif
+
+rm -f po/stamp-po
+
+%define _configure ../configure
+mkdir %{_vpath_builddir}
+cd %{_vpath_builddir}
+
+%configure --enable-dependency-tracking \
+           --with-runstatedir=%{_rundir} \
+           %{?arg_qemu} \
+           %{?arg_openvz} \
+           %{?arg_lxc} \
+           %{?arg_vbox} \
+           %{?arg_libxl} \
+           --with-sasl \
+           --with-polkit \
+           --with-libvirtd \
+           %{?arg_esx} \
+           %{?arg_hyperv} \
+           %{?arg_vmware} \
+           --without-vz \
+           --without-bhyve \
+           --with-remote-default-mode=legacy \
+           --with-interface \
+           --with-network \
+           --with-storage-fs \
+           --with-storage-lvm \
+           --with-storage-iscsi \
+           %{?arg_storage_iscsi_direct} \
+           --with-storage-scsi \
+           --with-storage-disk \
+           --with-storage-mpath \
+           %{?arg_storage_rbd} \
+           %{?arg_storage_sheepdog} \
+           %{?arg_storage_gluster} \
+           %{?arg_storage_zfs} \
+           --without-storage-vstorage \
+           %{?arg_numactl} \
+           %{?arg_numad} \
+           --with-capng \
+           %{?arg_fuse} \
+           --with-netcf \
+           --with-selinux \
+           %{?arg_selinux_mount} \
+           --without-apparmor \
+           --without-hal \
+           --with-udev \
+           --with-yajl \
+           %{?arg_sanlock} \
+           --with-libpcap \
+           --with-macvtap \
+           --with-audit \
+           --with-dtrace \
+           --with-driver-modules \
+           %{?arg_firewalld} \
+           %{?arg_firewalld_zone} \
+           %{?arg_wireshark} \
+           --without-pm-utils \
+           --with-nss-plugin \
+           %{arg_packager} \
+           %{arg_packager_version} \
+           --with-qemu-user=%{qemu_user} \
+           --with-qemu-group=%{qemu_group} \
+           --with-tls-priority=%{tls_priority} \
+           %{?enable_werror} \
+           --enable-expensive-tests \
+           --with-init-script=systemd \
+           %{?arg_login_shell}
+make %{?_smp_mflags} V=1
+
+%install
+rm -fr %{buildroot}
+
+export SOURCE_DATE_EPOCH=$(stat --printf='%Y' %{_specdir}/%{name}.spec)
+
+cd %{_vpath_builddir}
+%make_install %{?_smp_mflags} SYSTEMD_UNIT_DIR=%{_unitdir} V=1
+
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/lock-driver/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/lock-driver/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/connection-driver/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/connection-driver/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-backend/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-backend/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-file/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/libvirt/storage-file/*.a
+%if %{with_wireshark}
+rm -f $RPM_BUILD_ROOT%{wireshark_plugindir}/libvirt.la
+%endif
+
+install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/lib/libvirt/dnsmasq/
+# We don't want to install /etc/libvirt/qemu/networks in the main %files list
+# because if the admin wants to delete the default network completely, we don't
+# want to end up re-incarnating it on every RPM upgrade.
+install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/
+cp $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/default.xml \
+   $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/default.xml
+# libvirt saves this file with mode 0600
+chmod 0600 $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu/networks/default.xml
+
+# nwfilter files are installed in /usr/share/libvirt and copied to /etc in %post
+# to avoid verification errors on changed files in /etc
+install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/libvirt/nwfilter/
+cp -a $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/nwfilter/*.xml \
+    $RPM_BUILD_ROOT%{_datadir}/libvirt/nwfilter/
+# libvirt saves these files with mode 600
+chmod 600 $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/nwfilter/*.xml
+
+# Strip auto-generated UUID - we need it generated per-install
+sed -i -e "/<uuid>/d" $RPM_BUILD_ROOT%{_datadir}/libvirt/networks/default.xml
+%if ! %{with_qemu}
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_qemu.aug
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
+%endif
+%find_lang %{name}
+
+%if ! %{with_sanlock}
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirt_sanlock.aug
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirt_sanlock.aug
+%endif
+
+%if ! %{with_lxc}
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_lxc.aug
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug
+%endif
+
+%if ! %{with_qemu}
+rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu.conf
+rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.qemu
+%endif
+%if ! %{with_lxc}
+rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/lxc.conf
+rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.lxc
+%endif
+%if ! %{with_libxl}
+rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/libxl.conf
+rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.libxl
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_libxl.aug
+rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug
+%endif
+
+# Copied into libvirt-docs subpackage eventually
+mv $RPM_BUILD_ROOT%{_datadir}/doc/libvirt libvirt-docs
+
+%ifarch %{power64} s390x x86_64 ia64 alpha sparc64
+mv $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes.stp \
+   $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes-64.stp
+
+    %if %{with_qemu}
+mv $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_qemu_probes.stp \
+   $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_qemu_probes-64.stp
+    %endif
+%endif
+
+%check
+# The gnulib's test test-nonblocking-pipe.sh depends on timing and fails
+# on AArch64. Let's just disable it until we get rid of gnulib completely.
+for t in gnulib/tests/test-nonblocking-pipe.sh; do
+    rm -f $t
+    printf '#!/bin/sh\nexit 77\n' > $t
+    chmod a+x $t
+done
+
+cd %{_vpath_builddir}
+if ! make %{?_smp_mflags} check VIR_TEST_DEBUG=1
+then
+  cat tests/test-suite.log || true
+  exit 1
+fi
+
+%post libs
+%if 0%{?rhel} == 7
+/sbin/ldconfig
+%endif
+
+%postun libs
+%if 0%{?rhel} == 7
+/sbin/ldconfig
+%endif
+
+%pre daemon
+# 'libvirt' group is just to allow password-less polkit access to
+# libvirtd. The uid number is irrelevant, so we use dynamic allocation
+# described at the above link.
+getent group libvirt >/dev/null || groupadd -r libvirt
+
+exit 0
+
+%post daemon
+
+%systemd_post virtlockd.socket virtlockd-admin.socket
+%systemd_post virtlogd.socket virtlogd-admin.socket
+%systemd_post libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket
+%systemd_post libvirtd-tcp.socket libvirtd-tls.socket
+%systemd_post libvirtd.service
+
+# request daemon restart in posttrans
+mkdir -p %{_localstatedir}/lib/rpm-state/libvirt || :
+touch %{_localstatedir}/lib/rpm-state/libvirt/restart || :
+
+%preun daemon
+%systemd_preun libvirtd.service
+%systemd_preun libvirtd-tcp.socket libvirtd-tls.socket
+%systemd_preun libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket
+%systemd_preun virtlogd.socket virtlogd-admin.socket virtlogd.service
+%systemd_preun virtlockd.socket virtlockd-admin.socket virtlockd.service
+
+%postun daemon
+/bin/systemctl daemon-reload >/dev/null 2>&1 || :
+if [ $1 -ge 1 ] ; then
+    /bin/systemctl reload-or-try-restart virtlockd.service >/dev/null 2>&1 || :
+    /bin/systemctl reload-or-try-restart virtlogd.service >/dev/null 2>&1 || :
+fi
+
+# In upgrade scenario we must explicitly enable virtlockd/virtlogd
+# sockets, if libvirtd is already enabled and start them if
+# libvirtd is running, otherwise you'll get failures to start
+# guests
+%triggerpostun daemon -- libvirt-daemon < 1.3.0
+if [ $1 -ge 1 ] ; then
+    /bin/systemctl is-enabled libvirtd.service 1>/dev/null 2>&1 &&
+        /bin/systemctl enable virtlogd.socket virtlogd-admin.socket || :
+    /bin/systemctl is-active libvirtd.service 1>/dev/null 2>&1 &&
+        /bin/systemctl start virtlogd.socket virtlogd-admin.socket || :
+fi
+
+%posttrans daemon
+if [ -f %{_localstatedir}/lib/rpm-state/libvirt/restart ]; then
+    # See if user has previously modified their install to
+    # tell libvirtd to use --listen
+    grep -E '^LIBVIRTD_ARGS=.*--listen' /etc/sysconfig/libvirtd 1>/dev/null 2>&1
+    if test $? = 0
+    then
+        # Then lets keep honouring --listen and *not* use
+        # systemd socket activation, because switching things
+        # might confuse mgmt tool like puppet/ansible that
+        # expect the old style libvirtd
+        /bin/systemctl mask libvirtd.socket >/dev/null 2>&1 || :
+        /bin/systemctl mask libvirtd-ro.socket >/dev/null 2>&1 || :
+        /bin/systemctl mask libvirtd-admin.socket >/dev/null 2>&1 || :
+        /bin/systemctl mask libvirtd-tls.socket >/dev/null 2>&1 || :
+        /bin/systemctl mask libvirtd-tcp.socket >/dev/null 2>&1 || :
+    else
+        # Old libvirtd owns the sockets and will delete them on
+        # shutdown. Can't use a try-restart as libvirtd will simply
+        # own the sockets again when it comes back up. Thus we must
+        # do this particular ordering, so that we get libvirtd
+        # running with socket activation in use
+        /bin/systemctl is-active libvirtd.service 1>/dev/null 2>&1
+        if test $? = 0
+        then
+            /bin/systemctl stop libvirtd.service >/dev/null 2>&1 || :
+
+            /bin/systemctl try-restart libvirtd.socket >/dev/null 2>&1 || :
+            /bin/systemctl try-restart libvirtd-ro.socket >/dev/null 2>&1 || :
+            /bin/systemctl try-restart libvirtd-admin.socket >/dev/null 2>&1 || :
+
+            /bin/systemctl start libvirtd.service >/dev/null 2>&1 || :
+        fi
+    fi
+fi
+rm -rf %{_localstatedir}/lib/rpm-state/libvirt || :
+
+%post daemon-driver-network
+%if %{with_firewalld_zone}
+    %firewalld_reload
+%endif
+
+%postun daemon-driver-network
+%if %{with_firewalld_zone}
+    %firewalld_reload
+%endif
+
+%post daemon-config-network
+if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ; then
+    # see if the network used by default network creates a conflict,
+    # and try to resolve it
+    # NB: 192.168.122.0/24 is used in the default.xml template file;
+    # do not modify any of those values here without also modifying
+    # them in the template.
+    orig_sub=122
+    sub=${orig_sub}
+    nl='
+'
+    routes="${nl}$(ip route show | cut -d' ' -f1)${nl}"
+    case ${routes} in
+      *"${nl}192.168.${orig_sub}.0/24${nl}"*)
+        # there was a match, so we need to look for an unused subnet
+        for new_sub in $(seq 124 254); do
+          case ${routes} in
+          *"${nl}192.168.${new_sub}.0/24${nl}"*)
+            ;;
+          *)
+            sub=$new_sub
+            break;
+            ;;
+          esac
+        done
+        ;;
+      *)
+        ;;
+    esac
+
+    UUID=`/usr/bin/uuidgen`
+    sed -e "s/${orig_sub}/${sub}/g" \
+        -e "s,</name>,</name>\n  <uuid>$UUID</uuid>," \
+         < %{_datadir}/libvirt/networks/default.xml \
+         > %{_sysconfdir}/libvirt/qemu/networks/default.xml
+    ln -s ../default.xml %{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml
+    # libvirt saves this file with mode 0600
+    chmod 0600 %{_sysconfdir}/libvirt/qemu/networks/default.xml
+
+    # Make sure libvirt picks up the new network defininiton
+    mkdir -p %{_localstatedir}/lib/rpm-state/libvirt || :
+    touch %{_localstatedir}/lib/rpm-state/libvirt/restart || :
+fi
+
+%posttrans daemon-config-network
+if [ -f %{_localstatedir}/lib/rpm-state/libvirt/restart ]; then
+    /bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 || :
+fi
+rm -rf %{_localstatedir}/lib/rpm-state/libvirt || :
+
+%post daemon-config-nwfilter
+cp %{_datadir}/libvirt/nwfilter/*.xml %{_sysconfdir}/libvirt/nwfilter/
+# libvirt saves these files with mode 600
+chmod 600 %{_sysconfdir}/libvirt/nwfilter/*.xml
+# Make sure libvirt picks up the new nwfilter defininitons
+mkdir -p %{_localstatedir}/lib/rpm-state/libvirt || :
+touch %{_localstatedir}/lib/rpm-state/libvirt/restart || :
+
+%posttrans daemon-config-nwfilter
+if [ -f %{_localstatedir}/lib/rpm-state/libvirt/restart ]; then
+    /bin/systemctl try-restart libvirtd.service >/dev/null 2>&1 || :
+fi
+rm -rf %{_localstatedir}/lib/rpm-state/libvirt || :
+
+
+%if %{with_qemu}
+%pre daemon-driver-qemu
+# We want soft static allocation of well-known ids, as disk images
+# are commonly shared across NFS mounts by id rather than name; see
+# https://fedoraproject.org/wiki/Packaging:UsersAndGroups
+getent group kvm >/dev/null || groupadd -f -g 36 -r kvm
+getent group qemu >/dev/null || groupadd -f -g 107 -r qemu
+if ! getent passwd qemu >/dev/null; then
+  if ! getent passwd 107 >/dev/null; then
+    useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin -c "qemu user" qemu
+  else
+    useradd -r -g qemu -G kvm -d / -s /sbin/nologin -c "qemu user" qemu
+  fi
+fi
+exit 0
+%endif
+
+%preun client
+
+%systemd_preun libvirt-guests.service
+
+%post client
+%systemd_post libvirt-guests.service
+
+%postun client
+%systemd_postun libvirt-guests.service
+
+%if %{with_lxc}
+%pre login-shell
+getent group virtlogin >/dev/null || groupadd -r virtlogin
+exit 0
+%endif
+
+%files
+
+%files docs
+%doc AUTHORS ChangeLog NEWS README README.md
+%doc %{_vpath_builddir}/libvirt-docs/*
+
+%files daemon
+
+%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/
+
+%{_unitdir}/libvirtd.service
+%{_unitdir}/libvirtd.socket
+%{_unitdir}/libvirtd-ro.socket
+%{_unitdir}/libvirtd-admin.socket
+%{_unitdir}/libvirtd-tcp.socket
+%{_unitdir}/libvirtd-tls.socket
+%{_unitdir}/virtproxyd.service
+%{_unitdir}/virtproxyd.socket
+%{_unitdir}/virtproxyd-ro.socket
+%{_unitdir}/virtproxyd-admin.socket
+%{_unitdir}/virtproxyd-tcp.socket
+%{_unitdir}/virtproxyd-tls.socket
+%{_unitdir}/virt-guest-shutdown.target
+%{_unitdir}/virtlogd.service
+%{_unitdir}/virtlogd.socket
+%{_unitdir}/virtlogd-admin.socket
+%{_unitdir}/virtlockd.service
+%{_unitdir}/virtlockd.socket
+%{_unitdir}/virtlockd-admin.socket
+%config(noreplace) %{_sysconfdir}/sysconfig/libvirtd
+%config(noreplace) %{_sysconfdir}/sysconfig/virtlogd
+%config(noreplace) %{_sysconfdir}/sysconfig/virtlockd
+%config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf
+%config(noreplace) %{_sysconfdir}/libvirt/virtproxyd.conf
+%config(noreplace) %{_sysconfdir}/libvirt/virtlogd.conf
+%config(noreplace) %{_sysconfdir}/libvirt/virtlockd.conf
+%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf
+%config(noreplace) %{_prefix}/lib/sysctl.d/60-libvirtd.conf
+
+%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd
+%dir %{_datadir}/libvirt/
+
+%ghost %dir %{_rundir}/libvirt/
+
+%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/images/
+%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/filesystems/
+%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/boot/
+%dir %attr(0711, root, root) %{_localstatedir}/cache/libvirt/
+
+
+%dir %attr(0755, root, root) %{_libdir}/libvirt/
+%dir %attr(0755, root, root) %{_libdir}/libvirt/connection-driver/
+%dir %attr(0755, root, root) %{_libdir}/libvirt/lock-driver
+%attr(0755, root, root) %{_libdir}/libvirt/lock-driver/lockd.so
+
+%{_datadir}/augeas/lenses/libvirtd.aug
+%{_datadir}/augeas/lenses/tests/test_libvirtd.aug
+%{_datadir}/augeas/lenses/virtlogd.aug
+%{_datadir}/augeas/lenses/tests/test_virtlogd.aug
+%{_datadir}/augeas/lenses/virtlockd.aug
+%{_datadir}/augeas/lenses/tests/test_virtlockd.aug
+%{_datadir}/augeas/lenses/virtproxyd.aug
+%{_datadir}/augeas/lenses/tests/test_virtproxyd.aug
+%{_datadir}/augeas/lenses/libvirt_lockd.aug
+%if %{with_qemu}
+%{_datadir}/augeas/lenses/tests/test_libvirt_lockd.aug
+%endif
+
+%{_datadir}/polkit-1/actions/org.libvirt.unix.policy
+%{_datadir}/polkit-1/actions/org.libvirt.api.policy
+%{_datadir}/polkit-1/rules.d/50-libvirt.rules
+
+%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/
+
+%attr(0755, root, root) %{_libexecdir}/libvirt_iohelper
+
+%attr(0755, root, root) %{_sbindir}/libvirtd
+%attr(0755, root, root) %{_sbindir}/virtproxyd
+%attr(0755, root, root) %{_sbindir}/virtlogd
+%attr(0755, root, root) %{_sbindir}/virtlockd
+
+%{_mandir}/man8/libvirtd.8*
+%{_mandir}/man8/virtlogd.8*
+%{_mandir}/man8/virtlockd.8*
+%{_mandir}/man7/virkey*.7*
+
+%files daemon-config-network
+%dir %{_datadir}/libvirt/networks/
+%{_datadir}/libvirt/networks/default.xml
+%ghost %{_sysconfdir}/libvirt/qemu/networks/default.xml
+%ghost %{_sysconfdir}/libvirt/qemu/networks/autostart/default.xml
+
+%files daemon-config-nwfilter
+%dir %{_datadir}/libvirt/nwfilter/
+%{_datadir}/libvirt/nwfilter/*.xml
+%ghost %{_sysconfdir}/libvirt/nwfilter/*.xml
+
+%files daemon-driver-interface
+%config(noreplace) %{_sysconfdir}/libvirt/virtinterfaced.conf
+%{_datadir}/augeas/lenses/virtinterfaced.aug
+%{_datadir}/augeas/lenses/tests/test_virtinterfaced.aug
+%{_unitdir}/virtinterfaced.service
+%{_unitdir}/virtinterfaced.socket
+%{_unitdir}/virtinterfaced-ro.socket
+%{_unitdir}/virtinterfaced-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtinterfaced
+%{_libdir}/%{name}/connection-driver/libvirt_driver_interface.so
+
+%files daemon-driver-network
+%config(noreplace) %{_sysconfdir}/libvirt/virtnetworkd.conf
+%{_datadir}/augeas/lenses/virtnetworkd.aug
+%{_datadir}/augeas/lenses/tests/test_virtnetworkd.aug
+%{_unitdir}/virtnetworkd.service
+%{_unitdir}/virtnetworkd.socket
+%{_unitdir}/virtnetworkd-ro.socket
+%{_unitdir}/virtnetworkd-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtnetworkd
+%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/
+%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/
+%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/autostart
+%ghost %dir %{_rundir}/libvirt/network/
+%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/
+%dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/dnsmasq/
+%attr(0755, root, root) %{_libexecdir}/libvirt_leaseshelper
+%{_libdir}/%{name}/connection-driver/libvirt_driver_network.so
+
+%if %{with_firewalld_zone}
+%{_prefix}/lib/firewalld/zones/libvirt.xml
+%endif
+
+%files daemon-driver-nodedev
+%config(noreplace) %{_sysconfdir}/libvirt/virtnodedevd.conf
+%{_datadir}/augeas/lenses/virtnodedevd.aug
+%{_datadir}/augeas/lenses/tests/test_virtnodedevd.aug
+%{_unitdir}/virtnodedevd.service
+%{_unitdir}/virtnodedevd.socket
+%{_unitdir}/virtnodedevd-ro.socket
+%{_unitdir}/virtnodedevd-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtnodedevd
+%{_libdir}/%{name}/connection-driver/libvirt_driver_nodedev.so
+
+%files daemon-driver-nwfilter
+%config(noreplace) %{_sysconfdir}/libvirt/virtnwfilterd.conf
+%{_datadir}/augeas/lenses/virtnwfilterd.aug
+%{_datadir}/augeas/lenses/tests/test_virtnwfilterd.aug
+%{_unitdir}/virtnwfilterd.service
+%{_unitdir}/virtnwfilterd.socket
+%{_unitdir}/virtnwfilterd-ro.socket
+%{_unitdir}/virtnwfilterd-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtnwfilterd
+%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/nwfilter/
+%ghost %dir %{_rundir}/libvirt/network/
+%{_libdir}/%{name}/connection-driver/libvirt_driver_nwfilter.so
+
+%files daemon-driver-secret
+%config(noreplace) %{_sysconfdir}/libvirt/virtsecretd.conf
+%{_datadir}/augeas/lenses/virtsecretd.aug
+%{_datadir}/augeas/lenses/tests/test_virtsecretd.aug
+%{_unitdir}/virtsecretd.service
+%{_unitdir}/virtsecretd.socket
+%{_unitdir}/virtsecretd-ro.socket
+%{_unitdir}/virtsecretd-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtsecretd
+%{_libdir}/%{name}/connection-driver/libvirt_driver_secret.so
+
+%files daemon-driver-storage
+
+%files daemon-driver-storage-core
+%config(noreplace) %{_sysconfdir}/libvirt/virtstoraged.conf
+%{_datadir}/augeas/lenses/virtstoraged.aug
+%{_datadir}/augeas/lenses/tests/test_virtstoraged.aug
+%{_unitdir}/virtstoraged.service
+%{_unitdir}/virtstoraged.socket
+%{_unitdir}/virtstoraged-ro.socket
+%{_unitdir}/virtstoraged-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtstoraged
+%attr(0755, root, root) %{_libexecdir}/libvirt_parthelper
+%{_libdir}/%{name}/connection-driver/libvirt_driver_storage.so
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_fs.so
+%{_libdir}/%{name}/storage-file/libvirt_storage_file_fs.so
+
+%files daemon-driver-storage-disk
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_disk.so
+
+%files daemon-driver-storage-logical
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_logical.so
+
+%files daemon-driver-storage-scsi
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_scsi.so
+
+%files daemon-driver-storage-iscsi
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_iscsi.so
+
+%if %{with_storage_iscsi_direct}
+%files daemon-driver-storage-iscsi-direct
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_iscsi-direct.so
+%endif
+
+%files daemon-driver-storage-mpath
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_mpath.so
+
+%if %{with_storage_gluster}
+%files daemon-driver-storage-gluster
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_gluster.so
+%{_libdir}/%{name}/storage-file/libvirt_storage_file_gluster.so
+%endif
+
+%if %{with_storage_rbd}
+%files daemon-driver-storage-rbd
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_rbd.so
+%endif
+
+%if %{with_storage_sheepdog}
+%files daemon-driver-storage-sheepdog
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_sheepdog.so
+%endif
+
+%if %{with_storage_zfs}
+%files daemon-driver-storage-zfs
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_zfs.so
+%endif
+
+%if %{with_qemu}
+%files daemon-driver-qemu
+%config(noreplace) %{_sysconfdir}/libvirt/virtqemud.conf
+%{_datadir}/augeas/lenses/virtqemud.aug
+%{_datadir}/augeas/lenses/tests/test_virtqemud.aug
+%{_unitdir}/virtqemud.service
+%{_unitdir}/virtqemud.socket
+%{_unitdir}/virtqemud-ro.socket
+%{_unitdir}/virtqemud-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtqemud
+%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/
+%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
+%config(noreplace) %{_sysconfdir}/libvirt/qemu.conf
+%config(noreplace) %{_sysconfdir}/libvirt/qemu-lockd.conf
+%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.qemu
+%ghost %dir %{_rundir}/libvirt/qemu/
+%dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
+%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
+%{_datadir}/augeas/lenses/libvirtd_qemu.aug
+%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
+%{_libdir}/%{name}/connection-driver/libvirt_driver_qemu.so
+%dir %attr(0711, root, root) %{_localstatedir}/lib/libvirt/swtpm/
+%dir %attr(0711, root, root) %{_localstatedir}/log/swtpm/libvirt/qemu/
+%endif
+
+%if %{with_lxc}
+%files daemon-driver-lxc
+%config(noreplace) %{_sysconfdir}/libvirt/virtlxcd.conf
+%{_datadir}/augeas/lenses/virtlxcd.aug
+%{_datadir}/augeas/lenses/tests/test_virtlxcd.aug
+%{_unitdir}/virtlxcd.service
+%{_unitdir}/virtlxcd.socket
+%{_unitdir}/virtlxcd-ro.socket
+%{_unitdir}/virtlxcd-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtlxcd
+%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/lxc/
+%config(noreplace) %{_sysconfdir}/libvirt/lxc.conf
+%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.lxc
+%ghost %dir %{_rundir}/libvirt/lxc/
+%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/lxc/
+%{_datadir}/augeas/lenses/libvirtd_lxc.aug
+%{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug
+%attr(0755, root, root) %{_libexecdir}/libvirt_lxc
+%{_libdir}/%{name}/connection-driver/libvirt_driver_lxc.so
+%endif
+
+%if %{with_libxl}
+%files daemon-driver-libxl
+%config(noreplace) %{_sysconfdir}/libvirt/virtxend.conf
+%{_datadir}/augeas/lenses/virtxend.aug
+%{_datadir}/augeas/lenses/tests/test_virtxend.aug
+%{_unitdir}/virtxend.service
+%{_unitdir}/virtxend.socket
+%{_unitdir}/virtxend-ro.socket
+%{_unitdir}/virtxend-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtxend
+%config(noreplace) %{_sysconfdir}/libvirt/libxl.conf
+%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.libxl
+%config(noreplace) %{_sysconfdir}/libvirt/libxl-lockd.conf
+%{_datadir}/augeas/lenses/libvirtd_libxl.aug
+%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug
+%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/libxl/
+%ghost %dir %{_rundir}/libvirt/libxl/
+%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/
+%{_libdir}/%{name}/connection-driver/libvirt_driver_libxl.so
+%endif
+
+%if %{with_vbox}
+%files daemon-driver-vbox
+%config(noreplace) %{_sysconfdir}/libvirt/virtvboxd.conf
+%{_datadir}/augeas/lenses/virtvboxd.aug
+%{_datadir}/augeas/lenses/tests/test_virtvboxd.aug
+%{_unitdir}/virtvboxd.service
+%{_unitdir}/virtvboxd.socket
+%{_unitdir}/virtvboxd-ro.socket
+%{_unitdir}/virtvboxd-admin.socket
+%attr(0755, root, root) %{_sbindir}/virtvboxd
+%{_libdir}/%{name}/connection-driver/libvirt_driver_vbox.so
+%endif
+
+%if %{with_qemu_tcg}
+%files daemon-qemu
+%endif
+
+%if %{with_qemu_kvm}
+%files daemon-kvm
+%endif
+
+%if %{with_lxc}
+%files daemon-lxc
+%endif
+
+%if %{with_libxl}
+%files daemon-xen
+%endif
+
+%if %{with_vbox}
+%files daemon-vbox
+%endif
+
+%if %{with_sanlock}
+%files lock-sanlock
+    %if %{with_qemu}
+%config(noreplace) %{_sysconfdir}/libvirt/qemu-sanlock.conf
+    %endif
+    %if %{with_libxl}
+%config(noreplace) %{_sysconfdir}/libvirt/libxl-sanlock.conf
+    %endif
+%attr(0755, root, root) %{_libdir}/libvirt/lock-driver/sanlock.so
+%{_datadir}/augeas/lenses/libvirt_sanlock.aug
+%{_datadir}/augeas/lenses/tests/test_libvirt_sanlock.aug
+%dir %attr(0770, root, sanlock) %{_localstatedir}/lib/libvirt/sanlock
+%{_sbindir}/virt-sanlock-cleanup
+%{_mandir}/man8/virt-sanlock-cleanup.8*
+%attr(0755, root, root) %{_libexecdir}/libvirt_sanlock_helper
+%endif
+
+%files client
+%{_mandir}/man1/virsh.1*
+%{_mandir}/man1/virt-xml-validate.1*
+%{_mandir}/man1/virt-pki-validate.1*
+%{_mandir}/man1/virt-host-validate.1*
+%{_bindir}/virsh
+%{_bindir}/virt-xml-validate
+%{_bindir}/virt-pki-validate
+%{_bindir}/virt-host-validate
+
+%{_datadir}/systemtap/tapset/libvirt_probes*.stp
+%{_datadir}/systemtap/tapset/libvirt_functions.stp
+%if %{with_qemu}
+%{_datadir}/systemtap/tapset/libvirt_qemu_probes*.stp
+%endif
+
+%if %{with_bash_completion}
+%{_datadir}/bash-completion/completions/virsh
+%endif
+
+
+%{_unitdir}/libvirt-guests.service
+%config(noreplace) %{_sysconfdir}/sysconfig/libvirt-guests
+%attr(0755, root, root) %{_libexecdir}/libvirt-guests.sh
+
+%files libs -f %{_vpath_builddir}/%{name}.lang
+%license COPYING COPYING.LESSER
+%config(noreplace) %{_sysconfdir}/libvirt/libvirt.conf
+%config(noreplace) %{_sysconfdir}/libvirt/libvirt-admin.conf
+%{_libdir}/libvirt.so.*
+%{_libdir}/libvirt-qemu.so.*
+%{_libdir}/libvirt-lxc.so.*
+%{_libdir}/libvirt-admin.so.*
+%dir %{_datadir}/libvirt/
+%dir %{_datadir}/libvirt/schemas/
+%dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/
+
+%{_datadir}/libvirt/schemas/basictypes.rng
+%{_datadir}/libvirt/schemas/capability.rng
+%{_datadir}/libvirt/schemas/cputypes.rng
+%{_datadir}/libvirt/schemas/domain.rng
+%{_datadir}/libvirt/schemas/domainbackup.rng
+%{_datadir}/libvirt/schemas/domaincaps.rng
+%{_datadir}/libvirt/schemas/domaincheckpoint.rng
+%{_datadir}/libvirt/schemas/domaincommon.rng
+%{_datadir}/libvirt/schemas/domainsnapshot.rng
+%{_datadir}/libvirt/schemas/interface.rng
+%{_datadir}/libvirt/schemas/network.rng
+%{_datadir}/libvirt/schemas/networkcommon.rng
+%{_datadir}/libvirt/schemas/networkport.rng
+%{_datadir}/libvirt/schemas/nodedev.rng
+%{_datadir}/libvirt/schemas/nwfilter.rng
+%{_datadir}/libvirt/schemas/nwfilter_params.rng
+%{_datadir}/libvirt/schemas/nwfilterbinding.rng
+%{_datadir}/libvirt/schemas/secret.rng
+%{_datadir}/libvirt/schemas/storagecommon.rng
+%{_datadir}/libvirt/schemas/storagepool.rng
+%{_datadir}/libvirt/schemas/storagepoolcaps.rng
+%{_datadir}/libvirt/schemas/storagevol.rng
+
+%{_datadir}/libvirt/cpu_map/*.xml
+
+%{_datadir}/libvirt/test-screenshot.png
+
+%files admin
+%{_mandir}/man1/virt-admin.1*
+%{_bindir}/virt-admin
+%if %{with_bash_completion}
+%{_datadir}/bash-completion/completions/virt-admin
+%endif
+
+%if %{with_bash_completion}
+%files bash-completion
+%{_datadir}/bash-completion/completions/vsh
+%endif
+
+%if %{with_wireshark}
+%files wireshark
+%{wireshark_plugindir}/libvirt.so
+%endif
+
+%files nss
+%{_libdir}/libnss_libvirt.so.2
+%{_libdir}/libnss_libvirt_guest.so.2
+
+%if %{with_lxc}
+%files login-shell
+%attr(4750, root, virtlogin) %{_bindir}/virt-login-shell
+%{_libexecdir}/virt-login-shell-helper
+%config(noreplace) %{_sysconfdir}/libvirt/virt-login-shell.conf
+%{_mandir}/man1/virt-login-shell.1*
+%endif
+
+%files devel
+%{_libdir}/libvirt.so
+%{_libdir}/libvirt-admin.so
+%{_libdir}/libvirt-qemu.so
+%{_libdir}/libvirt-lxc.so
+%dir %{_includedir}/libvirt
+%{_includedir}/libvirt/virterror.h
+%{_includedir}/libvirt/libvirt.h
+%{_includedir}/libvirt/libvirt-admin.h
+%{_includedir}/libvirt/libvirt-common.h
+%{_includedir}/libvirt/libvirt-domain.h
+%{_includedir}/libvirt/libvirt-domain-checkpoint.h
+%{_includedir}/libvirt/libvirt-domain-snapshot.h
+%{_includedir}/libvirt/libvirt-event.h
+%{_includedir}/libvirt/libvirt-host.h
+%{_includedir}/libvirt/libvirt-interface.h
+%{_includedir}/libvirt/libvirt-network.h
+%{_includedir}/libvirt/libvirt-nodedev.h
+%{_includedir}/libvirt/libvirt-nwfilter.h
+%{_includedir}/libvirt/libvirt-secret.h
+%{_includedir}/libvirt/libvirt-storage.h
+%{_includedir}/libvirt/libvirt-stream.h
+%{_includedir}/libvirt/libvirt-qemu.h
+%{_includedir}/libvirt/libvirt-lxc.h
+%{_libdir}/pkgconfig/libvirt.pc
+%{_libdir}/pkgconfig/libvirt-admin.pc
+%{_libdir}/pkgconfig/libvirt-qemu.pc
+%{_libdir}/pkgconfig/libvirt-lxc.pc
+
+%dir %{_datadir}/libvirt/api/
+%{_datadir}/libvirt/api/libvirt-api.xml
+%{_datadir}/libvirt/api/libvirt-admin-api.xml
+%{_datadir}/libvirt/api/libvirt-qemu-api.xml
+%{_datadir}/libvirt/api/libvirt-lxc-api.xml
+
+
+%changelog
+* Mon Apr 27 2020 Danilo C. L. de Paula <ddepaula@redhat.com> - 6.0.0
+- Resolves: bz#1810193
+  (Upgrade components in virt:rhel module:stream for RHEL-8.3 release)
+
+* Mon Mar 16 2020 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-42
+- RHEL: virscsi: Check device type before getting it's /dev node name (rhbz#1808388)
+- RHEL: virscsi: Support TAPEs in virSCSIDeviceGetDevName() (rhbz#1808388)
+- RHEL: virscsi: Introduce and use virSCSIDeviceGetUnprivSGIOSysfsPath() (rhbz#1808388)
+- RHEL: virutil: Accept non-block devices in virGetDeviceID() (rhbz#1808388)
+- RHEL: qemuSetUnprivSGIO: Actually use calculated @sysfs_path to set unpriv_sgio (rhbz#1808388)
+- RHEL: qemuCheckUnprivSGIO: use @sysfs_path to get unpriv_sgio (rhbz#1808399)
+
+* Wed Mar  4 2020 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-41
+- qemu: Translate features in virQEMUCapsGetCPUFeatures (rhbz#1804224)
+
+* Mon Feb 17 2020 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-40
+- process: wait longer on kill per assigned Hostdev (rhbz#1785338)
+- process: wait longer 5->30s on hard shutdown (rhbz#1785338)
+
+* Mon Feb 10 2020 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-39
+- selinux: Do not report an error when not returning -1 (rhbz#1788096)
+- qemu: Fix hyperv features with QEMU 4.1 (rhbz#1794868)
+- qemu: Prefer dashes for hyperv features (rhbz#1794868)
+- cpu: Drop KVM_ from hyperv feature macros (rhbz#1794868)
+- cpu: Drop unused KVM features (rhbz#1794868)
+- qemu: Fix KVM features with QEMU 4.1 (rhbz#1794868)
+- cpu: Drop CPUID definition for hv-spinlocks (rhbz#1794868)
+
+* Tue Jan 14 2020 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-38
+- cpu_map/x86: Add support for BFLOAT16 data type (rhbz#1749516)
+
+* Fri Dec 13 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-37
+- cpu_map: Add TAA_NO bit for IA32_ARCH_CAPABILITIES MSR (CVE-2019-11135)
+- cpu_map: Add TSX_CTRL bit for IA32_ARCH_CAPABILITIES MSR (CVE-2019-11135)
+
+* Thu Nov 21 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-36
+- cpu_conf: Pass policy to CPU feature filtering callbacks (rhbz#1749672, rhbz#1756156, rhbz#1721608)
+- qemuxml2*test: Add tests for Icelake-Server, -pconfig (rhbz#1749672, rhbz#1756156, rhbz#1721608)
+- qemu: Drop disabled CPU features unknown to QEMU (rhbz#1749672, rhbz#1756156, rhbz#1721608)
+- cputest: Add data for Ice Lake Server CPU (rhbz#1749672, rhbz#1756156, rhbz#1721608)
+- cpu_map: Drop pconfig from Icelake-Server CPU model (rhbz#1749672, rhbz#1756156, rhbz#1721608)
+- qemu: Fix NULL ptr dereference caused by qemuDomainDefFormatBufInternal (rhbz#1749672, rhbz#1756156, rhbz#1721608)
+
+* Mon Sep 16 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-35
+- vircgroupv2: fix setting cpu.max period (rhbz#1749227)
+
+* Wed Sep  4 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-34
+- vircgroupv2: fix abort in VIR_AUTOFREE (rhbz#1747440)
+
+* Mon Aug 26 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-33
+- vircgroupv2: fix parsing multiple values in single file (rhbz#1741825)
+- vircgroupv2: fix virCgroupV2GetCpuCfsQuota for "max" value (rhbz#1741837)
+
+* Mon Aug 19 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-32
+- virDomainObjListAddLocked: Produce better error message than 'Duplicate key' (rhbz#1737790)
+- virdbus: Grab a ref as long as the while loop is executed (rhbz#1741900)
+
+* Tue Jul 30 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-31
+- virDomainObjListAddLocked: fix double free (rhbz#1728530)
+- docs: schemas: Decouple the virtio options from each other (rhbz#1729675)
+- util: command: use VIR_AUTOFREE instead of VIR_FREE for scalar types (rhbz#1721434)
+- util: command: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC (rhbz#1721434)
+- util: netdevopenvswitch: use VIR_AUTOFREE instead of VIR_FREE for scalar types (rhbz#1721434)
+- util: virnetdevopenvswitch: Drop an unused variable @ovs_timeout (rhbz#1721434)
+- util: netdevopenvswitch: use VIR_AUTOPTR for aggregate types (rhbz#1721434)
+- util: suppress unimportant ovs-vsctl errors when getting interface stats (rhbz#1721434)
+- virNetDevOpenvswitchInterfaceStats: Optimize for speed (rhbz#1721434)
+- test: Introduce virnetdevopenvswitchtest (rhbz#1721434)
+- vircommand: Separate mass FD closing into a function (rhbz#1721434)
+- virCommand: use procfs to learn opened FDs (rhbz#1721434)
+- util: command: Ignore bitmap errors when enumerating file descriptors to close (rhbz#1721434)
+- util: Avoid possible error in virCommandMassClose (rhbz#1721434)
+- vircgroup: fix cgroups v2 controllers detection (rhbz#1689297)
+- vircgroupv2: store enabled controllers (rhbz#1689297)
+
+* Wed Jul  3 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-30
+- virWaitForDevices: Drop confusing part of comment (rhbz#1710575)
+- lib: Drop UDEVSETTLE (rhbz#1710575)
+- m4: Provide default value fore UDEVADM (rhbz#1710575)
+- m4: Drop needless string checks (rhbz#1710575)
+- util: vircgroup: introduce virCgroup(Get|Set)ValueRaw (rhbz#1658890)
+- util: vircgroup: move virCgroupGetValueStr out of virCgroupGetValueForBlkDev (rhbz#1658890)
+- util: vircgroupv1: add support for BFQ blkio files (rhbz#1658890)
+- util: vircgroupv2: add support for BFQ files (rhbz#1658890)
+- Handle copying bitmaps to larger data buffers (rhbz#1703160)
+
+* Tue Jul  2 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-29
+- cpu: allow include files for CPU definition (rhbz#1686895)
+- cpu: fix cleanup when signature parsing fails (rhbz#1686895)
+- cpu: push more parsing logic into common code (rhbz#1686895)
+- cpu: simplify failure cleanup paths (rhbz#1686895)
+- cpu_map: Add support for arch-capabilities feature (rhbz#1693433)
+- cputest: Add data for Intel(R) Xeon(R) CPU E5-2630 v4 (rhbz#1686895)
+- cputest: Add data for Intel(R) Core(TM) i7-7600U (rhbz#1686895)
+- cputest: Add data for Intel(R) Xeon(R) CPU E7540 (rhbz#1686895)
+- cputest: Add data for Intel(R) Xeon(R) CPU E5-2650 (rhbz#1686895)
+- cputest: Add data for Intel(R) Core(TM) i7-8700 (rhbz#1686895)
+- cpu_x86: Separate ancestor model parsing from x86ModelParse (rhbz#1686895)
+- cpu_x86: Separate signature parsing from x86ModelParse (rhbz#1686895)
+- cpu_x86: Separate vendor parsing from x86ModelParse (rhbz#1686895)
+- cpu_x86: Separate feature list parsing from x86ModelParse (rhbz#1686895)
+- cpu_x86: Make sure CPU model names are unique in cpu_map (rhbz#1686895)
+- cpu_x86: Add x86ModelCopySignatures helper (rhbz#1686895)
+- cpu_x86: Store CPU signature in an array (rhbz#1686895)
+- cpu_x86: Allow multiple signatures for a CPU model (rhbz#1686895)
+- cpu_x86: Log decoded CPU model and signatures (rhbz#1686895)
+- qemu_capabilities: Inroduce virQEMUCapsGetCPUModelX86Data (rhbz#1686895)
+- qemu_capabilities: Introduce virQEMUCapsGetCPUModelInfo (rhbz#1686895)
+- qemu_capabilities: Use virQEMUCapsGetCPUModelInfo (rhbz#1686895)
+- cpu_x86: Add virCPUx86DataGetSignature for tests (rhbz#1686895)
+- cpu_map: Add hex representation of signatures (rhbz#1686895)
+- cputest: Test CPU signatures (rhbz#1686895)
+- cpu_map: Add more signatures for Conroe CPU model (rhbz#1686895)
+- cpu_map: Add more signatures for Penryn CPU model (rhbz#1686895)
+- cpu_map: Add more signatures for Nehalem CPU models (rhbz#1686895)
+- cpu_map: Add more signatures for Westmere CPU model (rhbz#1686895)
+- cpu_map: Add more signatures for SandyBridge CPU models (rhbz#1686895)
+- cpu_map: Add more signatures for IvyBridge CPU models (rhbz#1686895)
+- cpu_map: Add more signatures for Haswell CPU models (rhbz#1686895)
+- cpu_map: Add more signatures for Broadwell CPU models (rhbz#1686895)
+- cpu_map: Add more signatures for Skylake-Client CPU models (rhbz#1686895)
+- cpu: Don't access invalid memory in virCPUx86Translate (rhbz#1686895)
+- cpu_x86: Require <cpuid> within <feature> in CPU map (rhbz#1697627)
+- cputest: Add data for Intel(R) Xeon(R) Platinum 8268 CPU (rhbz#1693433)
+- cpu_map: Add Cascadelake-Server CPU model (rhbz#1693433)
+- cpu_x86: Introduce virCPUx86DataItem container struct (rhbz#1697627)
+- cpu_x86: Rename virCPUx86Vendor.cpuid (rhbz#1697627)
+- cpu_x86: Rename virCPUx86DataItem variables (rhbz#1697627)
+- cpu_x86: Rename x86DataCpuidNext function (rhbz#1697627)
+- cpu_x86: Rename x86DataCpuid (rhbz#1697627)
+- cpu_x86: Rename virCPUx86CPUIDSorter (rhbz#1697627)
+- cpu_x86: Rename virCPUx86DataAddCPUIDInt (rhbz#1697627)
+- cpu_x86: Rename virCPUx86DataAddCPUID (rhbz#1697627)
+- cpu_x86: Rename virCPUx86VendorToCPUID (rhbz#1697627)
+- cpu_x86: Simplify x86DataAdd (rhbz#1697627)
+- cpu_x86: Introduce virCPUx86DataCmp (rhbz#1697627)
+- cpu_x86: Make x86cpuidSetBits more general (rhbz#1697627)
+- cpu_x86: Make x86cpuidClearBits more general (rhbz#1697627)
+- cpu_x86: Make x86cpuidAndBits more general (rhbz#1697627)
+- cpu_x86: Make x86cpuidMatchMasked more general (rhbz#1697627)
+- cpu_x86: Make x86cpuidMatch more general (rhbz#1697627)
+- cpu_x86: Store virCPUx86DataItem content in union (rhbz#1697627)
+- cpu_x86: Add support for storing MSR features in CPU map (rhbz#1697627)
+- cpu_x86: Move *CheckFeature functions (rhbz#1697627)
+- cputest: Add support for MSR features to cpu-parse.sh (rhbz#1697627)
+- util: file: introduce VIR_AUTOCLOSE macro to close fd of the file automatically (rhbz#1697627)
+- vircpuhost: Add support for reading MSRs (rhbz#1697627)
+- virhostcpu: Make virHostCPUGetMSR() work only on x86 (rhbz#1697627)
+- cpu_x86: Fix placement of *CheckFeature functions (rhbz#1697627)
+- cpu_conf: Introduce virCPUDefFilterFeatures (rhbz#1697627)
+- qemu_command: Use consistent syntax for CPU features (rhbz#1697627)
+- tests: Add QEMU caps data for future 4.1.0 (rhbz#1697627)
+- tests: Add domain capabilities case for QEMU 4.1.0 (rhbz#1697627)
+- qemuxml2argvtest: Add test for CPU features translation (rhbz#1697627)
+- qemu: Add APIs for translating CPU features (rhbz#1697627)
+- qemu: Probe for max-x86_64-cpu type (rhbz#1697627)
+- qemu: Probe for "unavailable-features" CPU property (rhbz#1697627)
+- qemu: Probe host CPU after capabilities (rhbz#1697627)
+- qemu_command: Use canonical names of CPU features (rhbz#1697627)
+- qemu: Translate feature names from query-cpu-model-expansion (rhbz#1697627)
+- qemu: Don't use full CPU model expansion (rhbz#1697627)
+- qemu: Make qemuMonitorGetGuestCPU usable on x86 only (rhbz#1697627)
+- cpu: Introduce virCPUDataAddFeature (rhbz#1697627)
+- qemu: Add type filter to qemuMonitorJSONParsePropsList (rhbz#1697627)
+- util: string: Introduce macro for automatic string lists (rhbz#1697627)
+- util: json: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC (rhbz#1697627)
+- qemu: Introduce generic qemuMonitorGetGuestCPU (rhbz#1697627)
+- qemu_process: Prefer generic qemuMonitorGetGuestCPU (rhbz#1697627)
+- util: Rework virStringListAdd (rhbz#1697627)
+- conf: Introduce virCPUDefCheckFeatures (rhbz#1697627)
+- cpu_x86: Turn virCPUx86DataIteratorInit into a function (rhbz#1697627)
+- cpu_x86: Introduce virCPUx86FeatureFilter*MSR (rhbz#1697627)
+- cpu_x86: Read CPU features from IA32_ARCH_CAPABILITIES MSR (rhbz#1697627)
+- cpu_map: Introduce IA32_ARCH_CAPABILITIES MSR features (rhbz#1697627)
+- qemu: Forbid MSR features with old QEMU (rhbz#1697627)
+- qemu: Drop MSR features from host-model with old QEMU (rhbz#1697627)
+- cpu_x86: Fix memory leak - virCPUx86GetHost (rhbz#1697627)
+- qemu: Use @tmpChr in qemuDomainDetachChrDevice to build device string (rhbz#1624204)
+- qemu: Drop "user-" prefix for guestfwd netdev (rhbz#1624204)
+- qemu_hotplug: Attach guestfwd using netdev_add (rhbz#1624204)
+- qemu_hotplug: Detach guestfwd using netdev_del (rhbz#1624204)
+- qemuhotplugtest: Test guestfwd attach and detach (rhbz#1624204)
+- daemon: Register secret driver before storage driver (rhbz#1685151)
+- bhyve: Move autostarting of domains into bhyveStateInitialize (rhbz#1685151)
+- Revert "virStateDriver - Separate AutoStart from Initialize" (rhbz#1685151)
+- Revert "Separate out StateAutoStart from StateInitialize" (rhbz#1685151)
+- util: moving 'type' argument to avoid issues with mount() syscall. (rhbz#1689297)
+- util: cgroup: use VIR_AUTOFREE instead of VIR_FREE for scalar types (rhbz#1689297)
+- vircgroup: Rename structs to start with underscore (rhbz#1689297)
+- vircgroup: Introduce standard set of typedefs and use them (rhbz#1689297)
+- vircgroup: Extract file link resolving into separate function (rhbz#1689297)
+- vircgroup: Remove unused function virCgroupKill() (rhbz#1689297)
+- vircgroup: Unexport unused function virCgroupAddTaskController() (rhbz#1689297)
+- vircgroup: Unexport unused function virCgroupRemoveRecursively (rhbz#1689297)
+- vircgroup: Move function used in tests into vircgrouppriv.h (rhbz#1689297)
+- vircgroup: Remove pointless bool parameter (rhbz#1689297)
+- vircgroup: Extract mount options matching into function (rhbz#1689297)
+- vircgroup: Use virCgroupMountOptsMatchController in virCgroupDetectPlacement (rhbz#1689297)
+- vircgroup: Introduce virCgroupEnableMissingControllers (rhbz#1689297)
+- vircgroup: machinename will never be NULL (rhbz#1689297)
+- vircgroup: Remove virCgroupAddTaskController (rhbz#1689297)
+- vircgroup: Introduce virCgroupGetMemoryStat (rhbz#1689297)
+- lxc: Use virCgroupGetMemoryStat (rhbz#1689297)
+- vircgroup: fix MinGW build (rhbz#1689297)
+- vircgroup: Duplicate string before modifying (rhbz#1689297)
+- vircgroup: Extract controller detection into function (rhbz#1689297)
+- vircgroup: Extract placement validation into function (rhbz#1689297)
+- vircgroup: Split virCgroupPathOfController into two functions (rhbz#1689297)
+- vircgroup: Call virCgroupRemove inside virCgroupMakeGroup (rhbz#1689297)
+- vircgroup: Simplify if conditions in virCgroupMakeGroup (rhbz#1689297)
+- vircgroup: Remove obsolete sa_assert (rhbz#1689297)
+- tests: Resolve possible overrun (rhbz#1689297)
+- vircgroup: cleanup controllers not managed by systemd on error (rhbz#1689297)
+- vircgroup: fix bug in virCgroupEnableMissingControllers (rhbz#1689297)
+- vircgroup: rename virCgroupAdd.*Task to virCgroupAdd.*Process (rhbz#1689297)
+- vircgroup: introduce virCgroupTaskFlags (rhbz#1689297)
+- vircgroup: introduce virCgroupAddThread (rhbz#1689297)
+- vircgroupmock: cleanup unused cgroup files (rhbz#1689297)
+- vircgroupmock: rewrite cgroup fopen mocking (rhbz#1689297)
+- vircgrouptest: call virCgroupDetectMounts directly (rhbz#1689297)
+- vircgrouptest: call virCgroupNewSelf instead virCgroupDetectMounts (rhbz#1689297)
+- util: introduce vircgroupbackend files (rhbz#1689297)
+- vircgroup: introduce cgroup v1 backend files (rhbz#1689297)
+- vircgroup: extract virCgroupV1Available (rhbz#1689297)
+- vircgroup: detect available backend for cgroup (rhbz#1689297)
+- vircgroup: extract virCgroupV1ValidateMachineGroup (rhbz#1689297)
+- vircgroup: extract virCgroupV1CopyMounts (rhbz#1689297)
+- vircgroup: extract v1 detect functions (rhbz#1689297)
+- vircgroup: extract virCgroupV1CopyPlacement (rhbz#1689297)
+- vircgroup: extract virCgroupV1ValidatePlacement (rhbz#1689297)
+- vircgroup: extract virCgroupV1StealPlacement (rhbz#1689297)
+- vircgroup: extract virCgroupV1DetectControllers (rhbz#1689297)
+- vircgroup: extract virCgroupV1HasController (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetAnyController (rhbz#1689297)
+- vircgroup: extract virCgroupV1PathOfController (rhbz#1689297)
+- vircgroup: extract virCgroupV1MakeGroup (rhbz#1689297)
+- vircgroup: extract virCgroupV1Remove (rhbz#1689297)
+- vircgroup: extract virCgroupV1AddTask (rhbz#1689297)
+- vircgroup: extract virCgroupV1HasEmptyTasks (rhbz#1689297)
+- vircgroup: extract virCgroupV1BindMount (rhbz#1689297)
+- vircgroup: extract virCgroupV1SetOwner (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)BlkioWeight (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetBlkioIoServiced (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetBlkioIoDeviceServiced (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWeight (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceReadIops (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWriteIops (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceReadBps (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWriteBps (rhbz#1689297)
+- vircgroup: extract virCgroupV1SetMemory (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetMemoryStat (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetMemoryUsage (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)Memory*Limit (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetMemSwapUsage (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Allow|Deny)Device (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Allow|Deny)AllDevices (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)CpuShares (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)CpuCfsPeriod (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)CpuCfsQuota (rhbz#1689297)
+- vircgroup: extract virCgroupV1SupportsCpuBW (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetCpuacct*Usage (rhbz#1689297)
+- vircgroup: extract virCgroupV1GetCpuacctStat (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)FreezerState (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)CpusetMems (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)CpusetMemoryMigrate (rhbz#1689297)
+- vircgroup: extract virCgroupV1(Set|Get)CpusetCpus (rhbz#1689297)
+- vircgroup: rename virCgroupController into virCgroupV1Controller (rhbz#1689297)
+- vircgroup: rename controllers to legacy (rhbz#1689297)
+- vircgroup: remove VIR_CGROUP_SUPPORTED (rhbz#1689297)
+- vircgroup: include system headers only on linux (rhbz#1689297)
+- vircgroupv1: fix build on non-linux OSes (rhbz#1689297)
+- Revert "vircgroup: cleanup controllers not managed by systemd on error" (rhbz#1689297)
+- util: introduce cgroup v2 files (rhbz#1689297)
+- vircgroup: introduce virCgroupV2Available (rhbz#1689297)
+- vircgroup: introduce virCgroupV2ValidateMachineGroup (rhbz#1689297)
+- vircgroup: introduce virCgroupV2CopyMounts (rhbz#1689297)
+- vircgroup: introduce virCgroupV2CopyPlacement (rhbz#1689297)
+- vircgroup: introduce virCgroupV2DetectMounts (rhbz#1689297)
+- vircgroup: introduce virCgroupV2DetectPlacement (rhbz#1689297)
+- vircgroup: introduce virCgroupV2ValidatePlacement (rhbz#1689297)
+- vircgroup: introduce virCgroupV2StealPlacement (rhbz#1689297)
+- vircgroup: introduce virCgroupV2DetectControllers (rhbz#1689297)
+- vircgroup: introduce virCgroupV2HasController (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetAnyController (rhbz#1689297)
+- vircgroup: introduce virCgroupV2PathOfController (rhbz#1689297)
+- vircgroup: introduce virCgroupV2MakeGroup (rhbz#1689297)
+- vircgroup: introduce virCgroupV2Remove (rhbz#1689297)
+- vircgroup: introduce virCgroupV2AddTask (rhbz#1689297)
+- vircgroup: introduce virCgroupV2HasEmptyTasks (rhbz#1689297)
+- vircgroup: introduce virCgroupV2BindMount (rhbz#1689297)
+- vircgroup: introduce virCgroupV2SetOwner (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)BlkioWeight (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetBlkioIoServiced (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetBlkioIoDeviceServiced (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWeight (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceReadIops (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWriteIops (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceReadBps (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWriteBps (rhbz#1689297)
+- vircgroup: introduce virCgroupV2SetMemory (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetMemoryStat (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetMemoryUsage (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)MemoryHardLimit (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)MemorySoftLimit (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)MemSwapHardLimit (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetMemSwapUsage (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)CpuShares (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)CpuCfsPeriod (rhbz#1689297)
+- vircgroup: introduce virCgroupV2(Set|Get)CpuCfsQuota (rhbz#1689297)
+- vircgroup: introduce virCgroupV2SupportsCpuBW (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetCpuacctUsage (rhbz#1689297)
+- vircgroup: introduce virCgroupV2GetCpuacctStat (rhbz#1689297)
+- vircgroup: register cgroup v2 backend (rhbz#1689297)
+- vircgroup: add support for hybrid configuration (rhbz#1689297)
+- vircgroupmock: change cgroup prefix (rhbz#1689297)
+- vircgroupmock: add support to test cgroup v2 (rhbz#1689297)
+- vircgrouptest: introduce initFakeFS and cleanupFakeFS helpers (rhbz#1689297)
+- vircgrouptest: prepare testCgroupDetectMounts for cgroup v2 (rhbz#1689297)
+- vircgrouptest: add detect mounts test for cgroup v2 (rhbz#1689297)
+- vircgrouptest: add detect mounts test for hybrid cgroups (rhbz#1689297)
+- vircgrouptest: prepare validateCgroup for cgroupv2 (rhbz#1689297)
+- vircgrouptest: add cgroup v2 tests (rhbz#1689297)
+- vircgrouptest: add hybrid tests (rhbz#1689297)
+- virt-host-validate: rewrite cgroup detection to use util/vircgroup (rhbz#1689297)
+- virt-host-validate: require freezer for LXC (rhbz#1689297)
+- virt-host-validate: Fix build on non-Linux (rhbz#1689297)
+- tests: Use correct function name in error path (rhbz#1689297)
+- util: Fix virCgroupGetMemoryStat (rhbz#1689297)
+- tests: Augment vcgrouptest to add virCgroupGetMemoryStat (rhbz#1689297)
+- vircgroup: introduce virCgroupKillRecursiveCB (rhbz#1689297)
+- vircgroupv2: fix virCgroupV2ValidateMachineGroup (rhbz#1689297)
+- util: implement virCgroupV2(Set|Get)CpusetMems (rhbz#1689297)
+- util: implement virCgroupV2(Set|Get)CpusetMemoryMigrate (rhbz#1689297)
+- util: implement virCgroupV2(Set|Get)CpusetCpus (rhbz#1689297)
+- util: enable cgroups v2 cpuset controller for threads (rhbz#1689297)
+- util: vircgroup: pass parent cgroup into virCgroupDetectControllersCB (rhbz#1689297)
+- internal: introduce a family of NULLSTR macros (rhbz#1689297)
+- util: vircgroup: improve controller detection (rhbz#1689297)
+- util: vircgroupv2: use any controller to create thread directory (rhbz#1689297)
+- util: vircgroupv2: enable CPU controller only if it's available (rhbz#1689297)
+- util: vircgroupv2: separate return values of virCgroupV2EnableController (rhbz#1689297)
+- util: vircgroupv2: don't error out if enabling controller fails (rhbz#1689297)
+- util: vircgroupv2: mark only requested controllers as available (rhbz#1689297)
+- Revert "util: vircgroup: pass parent cgroup into virCgroupDetectControllersCB" (rhbz#1689297)
+- util: vircgroupv2: stop enabling missing controllers with systemd (rhbz#1689297)
+
+* Fri Jun 28 2019 Danilo de Paula <ddepaula@redhat.com> - 4.5.0-28
+- Rebuild all virt packages to fix RHEL's upgrade path
+- Resolves: rhbz#1695587
+  (Ensure modular RPM upgrade path)
+
+* Fri Jun 21 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-27
+- RHEL: spec: Disable gluster on i686 (rhbz#1722668)
+- rpc: virnetlibsshsession: update deprecated functions (rhbz#1722735)
+
+* Thu Jun 20 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-26
+- api: disallow virDomainSaveImageGetXMLDesc on read-only connections (CVE-2019-10161)
+- api: disallow virDomainManagedSaveDefineXML on read-only connections (CVE-2019-10166)
+- api: disallow virConnectGetDomainCapabilities on read-only connections (CVE-2019-10167)
+- api: disallow virConnect*HypervisorCPU on read-only connections (CVE-2019-10168)
+
+* Fri Jun 14 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-25
+- admin: reject clients unless their UID matches the current UID (CVE-2019-10132)
+- locking: restrict sockets to mode 0600 (CVE-2019-10132)
+- logging: restrict sockets to mode 0600 (CVE-2019-10132)
+- util: skip RDMA detection for non-PCI network devices (rhbz#1693299)
+- virfile: Detect ceph as shared FS (rhbz#1698133)
+- virfile: added GPFS as shared fs (rhbz#1698133)
+- util: bitmap: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC (rhbz#1716943)
+- qemu: Rework setting process affinity (rhbz#1716943)
+- qemu: Set up EMULATOR thread and cpuset.mems before exec()-ing qemu (rhbz#1716943)
+- conf: Add definitions for 'uid' and 'fid' PCI address attributes (rhbz#1508149)
+- qemu: Introduce zPCI capability (rhbz#1508149)
+- qemu: Enable PCI multi bus for S390 guests (rhbz#1508149)
+- conf: Introduce extension flag and zPCI member for PCI address (rhbz#1508149)
+- conf: Introduce address caching for PCI extensions (rhbz#1508149)
+- qemu: Auto add pci-root for s390/s390x guests (rhbz#1508149)
+- conf: use virXMLFormatElement() in virDomainDeviceInfoFormat() (rhbz#1508149)
+- conf: Introduce parser, formatter for uid and fid (rhbz#1508149)
+- qemu: Add zPCI address definition check (rhbz#1508149)
+- conf: Allocate/release 'uid' and 'fid' in PCI address (rhbz#1508149)
+- qemu: Generate and use zPCI device in QEMU command line (rhbz#1508149)
+- qemu: Add hotpluging support for PCI devices on S390 guests (rhbz#1508149)
+- qemuDomainRemoveRNGDevice: Remove associated chardev too (rhbz#1508149)
+- qemu_hotplug: remove erroneous call to qemuDomainDetachExtensionDevice() (rhbz#1508149)
+- qemu_hotplug: remove another erroneous qemuDomainDetachExtensionDevice() call (rhbz#1508149)
+- util: Propagate numad failures correctly (rhbz#1716907)
+- util: Introduce virBitmapUnion() (rhbz#1716908)
+- util: Introduce virNumaNodesetToCPUset() (rhbz#1716908)
+- qemu: Fix qemuProcessInitCpuAffinity() (rhbz#1716908)
+- qemu: Fix leak in qemuProcessInitCpuAffinity() (rhbz#1716908)
+- qemu: Drop cleanup label from qemuProcessInitCpuAffinity() (rhbz#1716908)
+- qemu: Fix NULL pointer access in qemuProcessInitCpuAffinity() (rhbz#1716908)
+- qemuBuildMemoryBackendProps: Pass @priv instead of its individual members (rhbz#1624223)
+- qemu: Don't use -mem-prealloc among with .prealloc=yes (rhbz#1624223)
+- nwfilter: fix adding std MAC and IP values to filter binding (rhbz#1691356)
+- qemuProcessBuildDestroyMemoryPathsImpl: Don't overwrite error (rhbz#1658112)
+- qemu_security: Fully implement qemuSecurityDomainSetPathLabel (rhbz#1658112)
+- qemu: process: SEV: Assume libDir to be the directory to create files in (rhbz#1658112)
+- qemu: process: SEV: Relabel guest owner's SEV files created before start (rhbz#1658112)
+
+* Tue May 14 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-24
+- tests: qemuxml2argv: add CAPS_ARCH_LATEST macro (rhbz#1698855)
+- qemu: Add ccw support for vhost-vsock (rhbz#1698855)
+- qemu: Allow creating ppc64 guests with graphics and no USB mouse (rhbz#1683681)
+- conf: Expose virDomainSCSIDriveAddressIsUsed (rhbz#1692354)
+- qemuhotplugtest: Don't plug a SCSI disk at unit 7 (rhbz#1692354)
+- qemu_hotplug: Check for duplicate drive addresses (rhbz#1692354)
+- cpu_map: Add support for cldemote CPU feature (rhbz#1537731)
+- util: alloc: add macros for implementing automatic cleanup functionality (rhbz#1505998)
+- qemu: domain: Simplify non-VFIO memLockLimit calculation for PPC64 (rhbz#1505998)
+- qemu_domain: add a PPC64 memLockLimit helper (rhbz#1505998)
+- qemu_domain: NVLink2 bridge detection function for PPC64 (rhbz#1505998)
+- PPC64 support for NVIDIA V100 GPU with NVLink2 passthrough (rhbz#1505998)
+- cpu_x86: Do not cache microcode version (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130)
+- qemu: Don't cache microcode version (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130)
+- cputest: Add data for Intel(R) Xeon(R) CPU E3-1225 v5 (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130)
+- cpu_map: Define md-clear CPUID bit (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130)
+
+* Fri Feb 15 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-23
+- network: explicitly allow icmp/icmpv6 in libvirt zonefile (rhbz#1650320)
+
+* Fri Feb 15 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-22
+- util: fix memory leak in virFirewallDInterfaceSetZone() (rhbz#1650320)
+
+* Fri Feb  8 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-21
+- docs: Drop /dev/net/tun from the list of shared devices (rhbz#1665400)
+- qemu: conf: Remove /dev/sev from the default cgroup device acl list (rhbz#1665400)
+- qemu: cgroup: Expose /dev/sev/ only to domains that require SEV (rhbz#1665400)
+- qemu: domain: Add /dev/sev into the domain mount namespace selectively (rhbz#1665400)
+- security: dac: Relabel /dev/sev in the namespace (rhbz#1665400)
+- qemu: caps: Use CAP_DAC_OVERRIDE for probing to avoid permission issues (rhbz#1665400)
+- qemu: caps: Don't try to ask for CAP_DAC_OVERRIDE if non-root (rhbz#1665400)
+- Revert "RHEL: Require firewalld-filesystem for firewalld rpm macros" (rhbz#1650320)
+- Revert "RHEL: network: regain guest network connectivity after firewalld switch to nftables" (rhbz#1650320)
+- configure: change HAVE_FIREWALLD to WITH_FIREWALLD (rhbz#1650320)
+- util: move all firewalld-specific stuff into its own files (rhbz#1650320)
+- util: new virFirewallD APIs + docs (rhbz#1650320)
+- configure: selectively install a firewalld 'libvirt' zone (rhbz#1650320)
+- network: set firewalld zone of bridges to "libvirt" zone when appropriate (rhbz#1650320)
+- network: allow configuring firewalld zone for virtual network bridge device (rhbz#1650320)
+- util: remove test code accidentally committed to virFirewallDZoneExists (rhbz#1650320)
+- qemu: command: Don't skip 'readonly' and throttling info for empty drive (rhbz#1670337)
+
+* Mon Jan 28 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-20
+- RHEL: qemu: Fix crash trying to use iSCSI hostdev (rhbz#1669424)
+
+* Thu Jan 24 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-19
+- qemu: Fix logic error in qemuSetUnprivSGIO (rhbz#1666605)
+- tests: qemuxml2argv: Add test case for empty CDROM with cache mode (rhbz#1553255)
+- qemu: command: Don't format image properties for empty -drive (rhbz#1553255)
+
+* Mon Jan 14 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-18
+- conf: correct false boot order error during domain parse (rhbz#1630393)
+- qemu: Remove duplicated qemuAgentCheckError (rhbz#1665000)
+- qemu: require reply from guest agent in qemuAgentGetInterfaces (rhbz#1665000)
+- qemu: Filter non SCSI hostdevs in qemuHostdevPrepareSCSIDevices (rhbz#1665244)
+- util: remove const specifier from nlmsghdr arg to virNetlinkDumpCallback() (rhbz#1583131)
+- util: add a function to insert new interfaces to IPv6CheckForwarding list (rhbz#1583131)
+- util: use nlmsg_find_attr() instead of an open-coded loop (rhbz#1583131)
+- util: check accept_ra for all nexthop interfaces of multipath routes (rhbz#1583131)
+- util: make forgotten changes suggested during review of commit d40b820c (rhbz#1583131)
+
+* Mon Jan  7 2019 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-17
+- virsh: Strip XML declaration when extracting CPU XMLs (rhbz#1659048)
+- RHEL: qemu: Add ability to set sgio values for hostdev (rhbz#1582424)
+- RHEL: qemu: Add check for unpriv sgio for SCSI generic host device (rhbz#1582424)
+- qemu: Alter @val usage in qemuSetUnprivSGIO (rhbz#1656362)
+- qemu: Alter qemuSetUnprivSGIO hostdev shareable logic (rhbz#1656362)
+
+* Mon Dec 17 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-16
+- util: Don't overflow in virRandomBits (rhbz#1655586)
+- virrandom: Avoid undefined behaviour in virRandomBits (rhbz#1655586)
+- spec: remove libcgroup and cgconfig (rhbz#1602407)
+- qemu: Drop duplicated code from qemuDomainDefValidateFeatures() (rhbz#1647822)
+- tests: Add capabilities data for QEMU 3.1.0 on ppc64 (rhbz#1647822)
+- qemu: Introduce QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV (rhbz#1647822)
+- conf: Parse and format nested-hv feature (rhbz#1647822)
+- qemu: Format nested-hv feature on the command line (rhbz#1647822)
+- qemu: Add check for whether KVM nesting is enabled (rhbz#1645139)
+- secret: Add check/validation for correct usage when LookupByUUID (rhbz#1656255)
+- cpu: Add support for "stibp" x86_64 feature (rhbz#1655032)
+
+* Mon Dec  3 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-15
+- virfile: Take symlink into account in virFileIsSharedFixFUSE (rhbz#1634782)
+- qemu: Ignore nwfilter binding instantiation issues during reconnect (rhbz#1648544)
+- qemu: Set identity for the reconnect all thread (rhbz#1648546)
+- Revert "access: Modify the VIR_ERR_ACCESS_DENIED to include driverName" (rhbz#1631608)
+- access: Modify the VIR_ERR_ACCESS_DENIED to include driverName (rhbz#1631608)
+- qemu: add vfio-ap capability (rhbz#1508146)
+- qemu: vfio-ap device support (rhbz#1508146)
+- qemu: Extract MDEV VFIO PCI validation code into a separate helper (rhbz#1508146)
+- conf: Move VFIO AP validation from post parse to QEMU validation code (rhbz#1508146)
+- qemu: Fix post-copy migration on the source (rhbz#1649169)
+
+* Fri Nov  9 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-14
+- storage: Remove secretPath from _virStorageBackendQemuImgInfo (rhbz#1645459)
+- storage: Allow for inputvol to have any format for encryption (rhbz#1645459)
+- storage: Allow inputvol to be encrypted (rhbz#1645459)
+- access: Modify the VIR_ERR_ACCESS_DENIED to include driverName (rhbz#1631608)
+- docs: Enhance polkit documentation to describe secondary connection (rhbz#1631608)
+- qemu: Don't ignore resume events (rhbz#1634758, rhbz#1643338)
+
+* Thu Nov  1 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-13
+- Revert "spec: Temporarily drop gluster support" (rhbz#1599339)
+
+* Wed Oct 17 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-12
+- RHEL: Require firewalld-filesystem for firewalld rpm macros (rhbz#1639932)
+
+* Tue Oct 16 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-11
+- virfile: fix cast-align error (rhbz#1634782)
+- virfiletest: Fix test name prefix for virFileInData test (rhbz#1634782)
+- virfiletst: Test virFileIsSharedFS (rhbz#1634782)
+- virFileIsSharedFSType: Detect direct mount points (rhbz#1634782)
+- virfile: Rework virFileIsSharedFixFUSE (rhbz#1634782)
+- RHEL: network: regain guest network connectivity after firewalld switch to nftables (rhbz#1638864)
+
+* Mon Oct  8 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-10
+- conf: Fix check for chardev source path (rhbz#1609723)
+- tests: Reuse qemucapabilities data for qemucaps2xml (rhbz#1629862)
+- tests: Add more tests to qemucaps2xml (rhbz#1629862)
+- qemu: Drop QEMU_CAPS_ENABLE_KVM (rhbz#1629862)
+- qemu: Avoid probing non-native binaries all the time (rhbz#1629862)
+- qemu: Clarify QEMU_CAPS_KVM (rhbz#1629862)
+- qemu: Don't check for /dev/kvm presence (rhbz#1629862)
+- tests: Follow up on qemucaps2xmldata rename (rhbz#1629862)
+- security: dac: also label listen UNIX sockets (rhbz#1634775)
+- spec: Set correct TLS priority (rhbz#1632269)
+- spec: Build ceph and gluster support everywhere (rhbz#1599546)
+- virsh: Require explicit --domain for domxml-to-native (rhbz#1634769)
+- virFileIsSharedFSType: Check for fuse.glusterfs too (rhbz#1634782)
+- qemu: fix up permissions for pre-created UNIX sockets (rhbz#1634775)
+- cpu_map: Add features for Icelake CPUs (rhbz#1527657, rhbz#1526625)
+- cpu_map: Add Icelake CPU models (rhbz#1526625)
+- qemu: Properly report VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT (rhbz#1634758)
+- qemu: Report more appropriate running reasons (rhbz#1634758)
+- qemu: Pass running reason to RESUME event handler (rhbz#1634758)
+- qemu: Map running reason to resume event detail (rhbz#1634758)
+- qemu: Avoid duplicate resume events and state changes (rhbz#1634758)
+- conf: qemu: add support for Hyper-V frequency MSRs (rhbz#1589702)
+- conf: qemu: add support for Hyper-V reenlightenment notifications (rhbz#1589702)
+- conf: qemu: add support for Hyper-V PV TLB flush (rhbz#1589702)
+
+* Wed Sep  5 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-9
+- RHEL: Fix virConnectGetMaxVcpus output (rhbz#1582222)
+- storage: Add --shrink to qemu-img command when shrinking vol (rhbz#1622534)
+- access: Fix nwfilter-binding ACL access API name generation (rhbz#1622540)
+- conf: Add validation of input devices (rhbz#1591240)
+- tests: qemu: Remove disk from graphics-vnc-tls (rhbz#1598167)
+- tests: qemu: test more versions for graphics-vnc-tls (rhbz#1598167)
+- qemu: vnc: switch to tls-creds-x509 (rhbz#1598167)
+- qemu: mdev: Use vfio-pci 'display' property only with vfio-pci mdevs (rhbz#1624740)
+- virDomainDefCompatibleDevice: Relax alias change check (rhbz#1603133)
+- virDomainDetachDeviceFlags: Clarify update semantics (rhbz#1603133)
+- virDomainNetDefCheckABIStability: Check for MTU change too (rhbz#1623158)
+- RHEL: spec: Require python3-devel on RHEL-8 (rhbz#1518446)
+- qemu: monitor: Remove qemuMonitorJSONExtractCPUArchInfo wrapper (rhbz#1598829)
+- qemu: monitor: Use 'target' instead of 'arch' in reply of 'query-cpus-fast' (rhbz#1598829)
+
+* Tue Aug 21 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-8
+- tests: Add missing thread_siblings_list files (rhbz#1608479)
+- util: Rewrite virHostCPUCountThreadSiblings() (rhbz#1608479)
+- utils: Remove arbitrary limit on socket_id/core_id (rhbz#1608479)
+- tests: Add linux-high-ids test (rhbz#1608479)
+- qemu: hotplug: Fix asynchronous unplug of 'shmem' (rhbz#1618680)
+- tests: rename hugepages to hugepages-default (rhbz#1615461)
+- tests: extract hugepages-numa-default-dimm out of hugepages-numa (rhbz#1615461)
+- tests: rename hugepages-numa into hugepages-numa-default (rhbz#1615461)
+- tests: remove unnecessary XML elements from hugepages-numa-default (rhbz#1615461)
+- tests: extract pages-discard out of hugepages-pages (rhbz#1615461)
+- tests: rename hugepages-pages into hugepages-numa-nodeset (rhbz#1615461)
+- tests: rename hugepages-pages2 into hugepages-numa-default-2M (rhbz#1615461)
+- tests: extract pages-discard-hugepages out of hugepages-pages3 (rhbz#1615461)
+- tests: rename hugepages-pages3 into hugepages-numa-nodeset-part (rhbz#1615461)
+- tests: rename hugepages-pages4 into hugepages-numa-nodeset-nonexist (rhbz#1615461)
+- tests: rename hugepages-pages5 into hugepages-default-2M (rhbz#1615461)
+- tests: rename hugepages-pages6 into hugepages-default-system-size (rhbz#1615461)
+- tests: rename hugepages-pages7 into pages-dimm-discard (rhbz#1615461)
+- tests: rename hugepages-pages8 into hugepages-nodeset-nonexist (rhbz#1615461)
+- tests: introduce hugepages-default-1G-nodeset-2M (rhbz#1615461)
+- tests: introduce hugepages-nodeset (rhbz#1615461)
+- conf: Move hugepage XML validation check out of qemu_command (rhbz#1615461)
+- conf: Move hugepages validation out of XML parser (rhbz#1615461)
+- conf: Introduce virDomainDefPostParseMemtune (rhbz#1615461)
+- tests: sev: Test launch-security with specific QEMU version (rhbz#1619150)
+- qemu: Fix probing of AMD SEV support (rhbz#1619150)
+- qemu: caps: Format SEV platform data into qemuCaps cache (rhbz#1619150)
+- conf: Parse guestfwd channel device info again (rhbz#1610072)
+
+* Thu Aug 16 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-7
+- qemu_migration: Avoid writing to freed memory (rhbz#1615854)
+
+* Thu Aug  2 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-6
+- qemu: Exempt video model 'none' from getting a PCI address on Q35
+- conf: Fix a error msg typo in virDomainVideoDefValidate
+
+* Tue Jul 31 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-5
+- esx storage: Fix typo lsilogic -> lsiLogic
+- networkGetDHCPLeases: Don't always report error if unable to read leases file
+- nwfilter: Resolve SEGV for NWFilter Snoop processing
+- qemu: Remove unused bypassSecurityDriver from qemuOpenFileAs
+- qemuDomainSaveMemory: Don't enforce dynamicOwnership
+- domain_nwfilter: Return early if net has no name in virDomainConfNWFilterTeardownImpl
+- examples: Add clean-traffic-gateway into nwfilters
+
+* Mon Jul 23 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-4
+- qemu: hotplug: don't overwrite error message in qemuDomainAttachNetDevice
+- qemu: hotplug: report error when changing rom enabled attr for net iface
+- qemu: Fix setting global_period cputune element
+- tests: qemucaps: Add test data for upcoming qemu 3.0.0
+- qemu: capabilities: Add capability for werror/rerror for 'usb-device' frontend
+- qemu: command: Move graphics iteration to its own function
+- qemu: address: Handle all the video devices within a single loop
+- conf: Introduce virDomainVideoDefClear helper
+- conf: Introduce virDomainDefPostParseVideo helper
+- qemu: validate: Enforce compile time switch type checking for videos
+- tests: Add capabilities data for QEMU 2.11 x86_64
+- tests: Update capabilities data for QEMU 3.0.0 x86_64
+- qemu: qemuBuildHostdevCommandLine: Use a helper variable mdevsrc
+- qemu: caps: Introduce a capability for egl-headless
+- qemu: Introduce a new graphics display type 'headless'
+- qemu: caps: Add vfio-pci.display capability
+- conf: Introduce virDomainGraphicsDefHasOpenGL helper
+- conf: Replace 'error' with 'cleanup' in virDomainHostdevDefParseXMLSubsys
+- conf: Introduce new <hostdev> attribute 'display'
+- qemu: command: Enable formatting vfio-pci.display option onto cmdline
+- docs: Rephrase the mediated devices hostdev section a bit
+- conf: Introduce new video type 'none'
+- virt-xml-validate: Add schema for nwfilterbinding
+- tools: Fix typo generating adapter_wwpn field
+- src: Fix memory leak in virNWFilterBindingDispose
+
+* Mon Jul 23 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-3
+- qemu: hotplug: Do not try to add secret object for TLS if it does not exist
+- qemu: monitor: Make qemuMonitorAddObject more robust against programming errors
+- spec: Explicitly require matching libvirt-libs
+- virDomainConfNWFilterInstantiate: initialize @xml to avoid random crash
+- qemuProcessStartPRDaemonHook: Try to set NS iff domain was started with one
+- qemuDomainValidateStorageSource: Relax PR validation
+- virStoragePRDefFormat: Suppress path formatting for migratable XML
+- qemu: Wire up PR_MANAGER_STATUS_CHANGED event
+- qemu_monitor: Introduce qemuMonitorJSONGetPRManagerInfo
+- qemu: Fetch pr-helper process info on reconnect
+- qemu: Fix ATTRIBUTE_NONNULL for qemuMonitorAddObject
+- virsh.pod: Fix a command name typo in nwfilter-binding-undefine
+- docs: schema: Add missing <alias> to vsock device
+- virnetdevtap: Don't crash on !ifname in virNetDevTapInterfaceStats
+- tests: fix TLS handshake failure with TLS 1.3
+
+* Mon Jul  9 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-2
+- qemu: Add capability for the HTM pSeries feature
+- conf: Parse and format the HTM pSeries feature
+- qemu: Format the HTM pSeries feature
+- qemu: hotplug: Don't access srcPriv when it's not allocated
+- qemuDomainNestedJobAllowed: Allow QEMU_JOB_NONE
+- src: Mention DEVICE_REMOVAL_FAILED event in virDomainDetachDeviceAlias docs
+- virsh.pod: Drop --persistent for detach-device-alias
+- qemu: don't use chardev FD passing with standalone args
+- qemu: remove chardevStdioLogd param from vhostuser code path
+- qemu: consolidate parameters of qemuBuildChrChardevStr into flags
+- qemu: don't use chardev FD passing for vhostuser backend
+- qemu: fix UNIX socket chardevs operating in client mode
+- qemuDomainDeviceDefValidateNetwork: Check for range only if IP prefix set
+- spec: Temporarily drop gluster support
+
+* Tue Jul  3 2018 Jiri Denemark <jdenemar@redhat.com> - 4.5.0-1
+- Rebased to libvirt-4.5.0
+
+* Fri May 25 2018 Jiri Denemark <jdenemar@redhat.com> - 4.3.0-1
+- Rebased to libvirt-4.3.0
+
+* Wed Mar 21 2018 Daniel P. Berrangé <berrange@redhat.com> - 4.1.0-2
+- Fix systemd macro argument with line continuations (rhbz#1558648)
+
+* Mon Mar  5 2018 Daniel Berrange <berrange@redhat.com> - 4.1.0-1
+- Rebase to version 4.1.0
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Fri Jan 19 2018 Daniel P. Berrange <berrange@redhat.com> - 4.0.0-1
+- Rebase to version 4.0.0
+
+* Wed Dec 20 2017 Cole Robinson <crobinso@redhat.com> - 3.10.0-2
+- Rebuild for xen 4.10
+
+* Tue Dec  5 2017 Daniel P. Berrange <berrange@redhat.com> - 3.10.0-1
+- Rebase to version 3.10.0
+
+* Fri Nov  3 2017 Daniel P. Berrange <berrange@redhat.com> - 3.9.0-1
+- Rebase to version 3.9.0
+
+* Wed Oct  4 2017 Daniel P. Berrange <berrange@redhat.com> - 3.8.0-1
+- Rebase to version 3.8.0
+
+* Mon Sep  4 2017 Daniel P. Berrange <berrange@redhat.com> - 3.7.0-1
+- Rebase to version 3.7.0
+
+* Wed Aug  2 2017 Daniel P. Berrange <berrange@redhat.com> - 3.6.0-1
+- Rebase to version 3.6.0
+
+* Sun Jul 30 2017 Florian Weimer <fweimer@redhat.com> - 3.5.0-4
+- Rebuild with binutils fix for ppc64le (#1475636)
+
+* Tue Jul 25 2017 Daniel P. Berrange <berrange@redhat.com> - 3.5.0-3
+- Disabled RBD on i386, arm, ppc64 (rhbz #1474743)
+
+* Mon Jul 17 2017 Cole Robinson <crobinso@redhat.com> - 3.5.0-2
+- Rebuild for xen 4.9
+
+* Thu Jul  6 2017 Daniel P. Berrange <berrange@redhat.com> - 3.5.0-1
+- Rebase to version 3.5.0
+
+* Fri Jun  2 2017 Daniel P. Berrange <berrange@redhat.com> - 3.4.0-1
+- Rebase to version 3.4.0
+
+* Mon May  8 2017 Daniel P. Berrange <berrange@redhat.com> - 3.3.0-1
+- Rebase to version 3.3.0
+
+* Mon Apr  3 2017 Daniel P. Berrange <berrange@redhat.com> - 3.2.0-1
+- Rebase to version 3.2.0
+
+* Fri Mar  3 2017 Daniel P. Berrange <berrange@redhat.com> - 3.1.0-1
+- Rebase to version 3.1.0
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.0.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Jan 19 2017 Daniel P. Berrange <berrange@redhat.com> - 3.0.0-1
+- Rebase to version 3.0.0