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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +--- + 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?= +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 + +https: //bugzilla.redhat.com/show_bug.cgi?id=1582222 +Reviewed-by: Andrea Bolognani +--- + 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 +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 +--- + 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: +From: John Ferlan +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 +Signed-off-by: Jiri Denemark +(cherry picked from commit f2cf0ae7bc371c75f6c0e79192711f2b1d201b10) +Reviewed-by: Ján Tomko +--- + 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 +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 +Signed-off-by: Jiri Denemark +(cherry picked from commit 712005bcf26190dc6fd1fe56283377987909cc4b) +Reviewed-by: Ján Tomko +--- + 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: +From: John Ferlan +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 element +was removed from the domain , 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 +Reviewed-by: Ján Tomko +--- + 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 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: +From: John Ferlan +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 +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +--- + 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: +From: John Ferlan +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: + + + + + + + +Signed-off-by: John Ferlan +Reviewed-by: Ján Tomko +--- + 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 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Signed-off-by: Andrea Bolognani +Message-Id: <20200306145226.1610708-7-abologna@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 +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 +Signed-off-by: Andrea Bolognani +Message-Id: <20200306145226.1610708-6-abologna@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Michal Privoznik +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 +Signed-off-by: Andrea Bolognani +Message-Id: <20200306145226.1610708-2-abologna@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Michal Privoznik +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 +Signed-off-by: Andrea Bolognani +Message-Id: <20200306145226.1610708-4-abologna@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Michal Privoznik +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 +Signed-off-by: Andrea Bolognani +Message-Id: <20200306145226.1610708-3-abologna@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Michal Privoznik +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 +Signed-off-by: Andrea Bolognani +Message-Id: <20200306145226.1610708-5-abologna@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit f742461389c11a7d4cc8bda941814c4128eadf94) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Michal Privoznik +(cherry picked from commit 4cc90c2e62df653e909ad31fd810224bf8bcf913) + +https://bugzilla.redhat.com/show_bug.cgi?id=1814508 + +Signed-off-by: Jonathon Jongsma +Message-Id: <20200325162119.9047-2-jjongsma@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ + <driver name='qemu' type='raw'/> + <source protocol="http" name="url_path"> + <host name="hostname" port="80"/> ++ <cookies> ++ <cookie name="test">somevalue</cookie> ++ </cookies> + </source> + <target dev='hde' bus='ide' tray='open'/> + <readonly/> +@@ -3382,6 +3385,13 @@ + certificate validation. Supported values are yes and + no. Since 6.2.0 + ++
cookies
++
++ For http and https accessed storage it's ++ possible to pass one or more cookies. The cookie name and value ++ must conform to the HTTP specification. ++ Since 6.2.0 ++
+ + +

+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 @@ + + + ++ ++ ++ ++ ++ ++ ++ [!#$%&'*+\-.0-9A-Z\^_`a-z|~]+ ++ ++ ++ ++ [!#$%&'()*+\-./0-9:>=<?@A-Z\^_`\[\]a-z|~]+ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1833,6 +1851,9 @@ + + + ++ ++ ++ + + + +@@ -1849,6 +1870,9 @@ + + + ++ ++ ++ + + + +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, "", src->cookies[i]->name); ++ virBufferEscapeString(&childBuf, "%s\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 @@ + + + ++ ++ testcookievalue ++ blurb ++ + + + +@@ -41,6 +45,10 @@ + + + ++ ++ testcookievalue ++ blurb ++ + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 56368124728f0d65dde07244c741b459fcd6b939) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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 @@ + </disk> + <disk type='network' device='cdrom'> + <driver name='qemu' type='raw'/> +- <source protocol="http" name="url_path"> ++ <source protocol="http" name="url_path" query="foo=bar&amp;baz=flurb> + <host name="hostname" port="80"/> + <cookies> + <cookie name="test">somevalue</cookie> +@@ -3103,6 +3103,11 @@ + ('tls' Since 4.5.0) +

+ ++

For protocols http and https an ++ optional attribute query specifies the query string. ++ (Since 6.2.0) ++

++ +

For "iscsi" (since 1.0.4), the + name 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 @@ + + + ++ ++ ++ + + + +@@ -1894,6 +1897,9 @@ + + + ++ ++ ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +-- +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: +From: Peter Krempa +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 + to the disk source XML which will allow configuring the validation +process using the 'verify' attribute. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 25481e25b14108373bf2e5e95c04fe30bff96bb4) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 @@ + <driver name='qemu' type='raw'/> + <source protocol="https" name="url_path"> + <host name="hostname" port="443"/> ++ <ssl verify="no"/> + </source> + <target dev='hdf' bus='ide' tray='open'/> + <readonly/> +@@ -3373,6 +3374,14 @@ + The offset and size values are in bytes. + Since 6.1.0 + ++

ssl
++
++ For https and ftps accessed storage it's ++ possible to tweak the SSL transport parameters with this element. ++ The verify attribute allows to turn on or off SSL ++ certificate validation. Supported values are yes and ++ no. Since 6.2.0 ++
+ + +

+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 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ https ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + http +- https + + + +@@ -1825,13 +1852,31 @@ + + + ++ ++ ++ ++ ++ ftps ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + sheepdog + ftp +- ftps + tftp + + +@@ -1909,6 +1954,8 @@ + + + ++ ++ + + + +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, "\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 @@ + + + ++ + + + +@@ -35,6 +36,14 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ + <cookies> + <cookie name="test">somevalue</cookie> + </cookies> ++ <readahead size='65536'/> ++ <timeout seconds='6'/> + </source> + <target dev='hde' bus='ide' tray='open'/> + <readonly/> +@@ -3392,6 +3394,20 @@ + must conform to the HTTP specification. + Since 6.2.0 + ++

readahead
++
++ 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. ++ Since 6.2.0 ++
++
timeout
++
++ Specifies the connection timeout for protocols which support it. ++ Note that '0' is considered as if the value is not provided. ++ Since 6.2.0 ++
+ + +

+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 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1854,6 +1873,7 @@ + + + ++ + + + +@@ -1873,6 +1893,7 @@ + + + ++ + + + +@@ -1892,6 +1913,7 @@ + + + ++ + + + +@@ -1910,6 +1932,7 @@ + + + ++ + + + +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, "\n", src->readahead); ++ ++ if (src->timeout) ++ virBufferAsprintf(childBuf, "\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 @@ + testcookievalue + blurb + ++ ++ + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 2695191a44eb7375225b4ad073825ed3563a172a) +Signed-off-by: Michal Privoznik +Message-Id: <355e05e31ec98522fa0e03a0c2c7af8ca097070d.1584101247.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +Date: Wed, 19 Feb 2020 15:10:20 +0100 +Subject: [PATCH] conf: Implement support for 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 +Reviewed-by: Ján Tomko +(cherry picked from commit bbf5d05cfd003e33600009cac7ea98ef1539dd7c) + +https://bugzilla.redhat.com/show_bug.cgi?id=1791788 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Andrea Bolognani +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 +Reviewed-by: Masayoshi Mizuma +Reviewed-by: Ján Tomko +(cherry picked from commit 3809e88a87e5898c9cf3a277cb32e20fca8fb2d0) + +https://bugzilla.redhat.com/show_bug.cgi?id=1762634 + +Signed-off-by: Andrea Bolognani +Message-Id: <20200214121237.623948-5-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 @@ + + hpet + pit ++ armvtimer + + + +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: +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +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 + + + +Reviewed-by: Jiri Denemark +Reviewed-by: Daniel Henrique Barboza +Signed-off-by: Daniel P. Berrangé +(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 +--- + 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 @@ + </features> + <model>core2duo</model> + <vendor>Intel</vendor> +- <topology sockets="1" cores="2" threads="1"/> ++ <topology sockets="1" dies="1" cores="2" threads="1"/> + <feature name="lahf_lm"/> + <feature name='xtpr'/> + ... +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 @@ + <cpu match='exact'> + <model fallback='allow'>core2duo</model> + <vendor>Intel</vendor> +- <topology sockets='1' cores='2' threads='1'/> ++ <topology sockets='1' dies='1' cores='2' threads='1'/> + <cache level='3' mode='emulate'/> + <feature policy='disable' name='lahf_lm'/> + </cpu> +@@ -1479,7 +1479,7 @@ +

+ <cpu mode='host-model'>
+   <model fallback='forbid'/>
+-  <topology sockets='1' cores='2' threads='1'/>
++  <topology sockets='1' dies='1' cores='2' threads='1'/>
+ </cpu>
+ ...
+ +@@ -1498,7 +1498,7 @@ +
+ ...
+ <cpu>
+-  <topology sockets='1' cores='2' threads='1'/>
++  <topology sockets='1' dies='1' cores='2' threads='1'/>
+ </cpu>
+ ...
+ +@@ -1673,13 +1673,15 @@ + +
topology
+
The topology element specifies requested topology of +- virtual CPU provided to the guest. Three non-zero values have to be +- given for sockets, cores, and +- threads: 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 +- cpus element equals to the number of vcpus resulting +- from the topology.
++ virtual CPU provided to the guest. Four attributes, sockets, ++ dies, cores, and threads, ++ 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 dies ++ 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 cpus element equals to ++ the number of vcpus resulting from the topology. + +
feature
+
The cpu 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 @@ + + + ++ ++ ++ ++ ++ + + + +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, "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 @@ + + 486 +- ++ + + + +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 @@ + + Nehalem +- ++ + + + +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 @@ + + Penryn +- ++ + + + +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 @@ + + Penryn +- ++ + + + +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 @@ + + Penryn + Intel +- ++ + + + +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 @@ + + Haswell +- ++ + + + +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 @@ + + Haswell +- ++ + + + +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 @@ + + Haswell-noTSX +- ++ + +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 @@ + + Penryn +- ++ + + + +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + hvm + + +- ++ + + + /usr/bin/qemu-system-ppc64 +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + destroy +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 @@ + + + core2duo +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + core2duo + Intel +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + hvm + + +- ++ + + + +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 @@ + hvm + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + hvm + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + core2duo + Intel +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + destroy +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + + destroy +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 @@ + hvm + + +- ++ + + + destroy +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 @@ + hvm + + +- ++ + + + destroy +-- +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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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: + + + + + + + + +Signed-off-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Masayoshi Mizuma +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit 66079339847dc942b9b673e3040b56b055a8d8f5) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <506d0532c6043a9b8c946bdc42c3d9c5529f6fb8.1583322090.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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 @@ + <readonly/> + </filesystem> + <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='on' flock='on'/> ++ </binary> + <source dir='/path'/> + <target dir='mount_tag'/> + </filesystem> +@@ -4063,9 +4067,28 @@ + Virtio-specific options can also be + set. (Since 3.5.0) + ++
  • ++ For virtiofs, the queue attribute can be used ++ to specify the queue size (i.e. how many requests can the queue fit). ++ (Since 6.2.0) ++
  • + +
    + ++
    binary
    ++
    ++ The optional binary element can tune the options for virtiofsd. ++ All of the following attributes and elements are optional. ++ The attribute path can be used to override the path to the daemon. ++ Attribute xattr enables the use of filesystem extended attributes. ++ Caching can be tuned via the cache element, possible mode ++ values being none and always. ++ Locking can be controlled via the lock ++ element - attributes posix and flock both accepting ++ values on or off. ++ (Since 6.2.0) ++
    ++ +
    source
    +
    + 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 @@ + + + ++ ++ ++ + + + +@@ -2649,12 +2652,57 @@ + + virtiofs + ++ ++ ++ ++ ++ + + + + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ none ++ always ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +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, "\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 @@ + + + +- ++ ++ ++ ++ ++ + + +
    +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 @@ + + + ++ + + +
    +-- +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 +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 +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Eric Blake +(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 +--- + 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 @@ +
    Setting this attribute to yes(default) specifies + that the disk should take part in the backup and using + no excludes the disk from the backup.
    ++
    exportname
    ++
    Allows modification of the NBD export name for the given disk. ++ By default equal to disk target. ++ Valid only for pull mode backups.
    ++
    exportbitmap
    ++
    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.
    +
    type
    +
    A mandatory attribute to describe the type of the + disk, except when backup='no' 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 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ + + + +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, "\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 1525889631 + + +- ++ + + + +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 @@ + 1525889631 + + +- ++ + + + +-- +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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +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 +Reviewed-by: Erik Skultety +(cherry picked from commit 45464db8ba502764cf37ec9335770248bdb3d9a8) + +Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +Date: Thu, 30 Jan 2020 14:12:40 -0500 +Subject: [PATCH] conf: parse/format subelement of +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The subelement of devices is used to configure a +simple teaming association between two interfaces in a domain. Example: + + + + + + + + + + +
    + + + + + +The interface with 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 +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit fb0509d06ac57434c2edbd81ee63deb32a0e598a) + +https://bugzilla.redhat.com/1693587 +Signed-off-by: Laine Stump +Message-Id: <20200130191244.24174-3-laine@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 @@ + + + ++ ++ ++ ++ ++ ++ persistent ++ ++ ++ ++ ++ transient ++ ++ ++ ++ ++ ++ ++ ++ + + + +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, "\n"); + } + ++ if (def->teaming.type != VIR_DOMAIN_NET_TEAMING_TYPE_NONE) { ++ virBufferAsprintf(buf, "teaming.type)); ++ virBufferEscapeString(buf, " persistent='%s'", def->teaming.persistent); ++ virBufferAddLit(buf, "/>\n"); ++ } + if (def->linkstate) { + virBufferAsprintf(buf, "\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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++
    ++ ++ ++
    ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++
    ++ ++ ++ +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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++
    ++ ++ ++
    ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++
    ++ ++ ++
    ++ ++ ++ ++ ++
    ++ ++ ++
    ++ ++ ++ ++ ++
    ++ ++ ++ +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?= +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. + + + + + +
    + + +Signed-off-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit ecc6ad6b90ad674a903c95d2a637f8b1b5833be2) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: +Reviewed-by: Michal Privoznik +--- + 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 @@ + <target dir='/import/from/host'/> + <readonly/> + </filesystem> ++ <filesystem type='mount' accessmode='passthrough'> ++ <driver type='virtiofs'/> ++ <source dir='/path'/> ++ <target dir='mount_tag'/> ++ </filesystem> + ... + </devices> + ... +@@ -3963,6 +3968,9 @@ + while the value immediate means that a host writeback + is immediately triggered for all pages touched during a guest file + write operation (since 0.9.10). ++ Since 6.2.0, type='virtiofs' ++ is also supported. Using virtiofs requires setting up shared memory, ++ see the guide: Virtio-FS +
    +
    template
    +
    +@@ -3998,7 +4006,9 @@ + The filesystem element has an optional attribute accessmode + which specifies the security mode for accessing the source + (since 0.8.5). Currently this only works +- with type='mount' for the QEMU/KVM driver. The possible ++ with type='mount' for the QEMU/KVM driver. ++ For driver type virtiofs, only passthrough is ++ supported. For other driver types, the possible + values are: + +
    +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 @@ + + + ++ ++ ++ virtiofs ++ ++ ++ + + + +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 @@ ++ ++ guest ++ 126f2720-6f8e-45ab-a886-ec9277079a67 ++ 14680064 ++ 14680064 ++ ++ ++ ++ ++ 2 ++ ++ hvm ++ ++ ++ ++ qemu64 ++ ++ ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ guest ++ 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 ++ 4194304 ++ 4194304 ++ ++ ++ ++ ++ ++ ++ 2 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ qemu64 ++ ++ ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++
    ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ +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?= +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 +Reviewed-by: Jiri Denemark +Signed-off-by: Daniel P. Berrangé +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 5793b8baa75747860f6ba97470969047e60c8579) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804617 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Peter Krempa +(cherry picked from commit 3efdbae5bf054d1a2bdc98fdccff0273abe54c88) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <966ad0eebcb1ae5f20f59fc6cc84008bbfa6426f.1583322090.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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, "\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 +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 +Reviewed-by: Peter Krempa +(cherry picked from commit 609acf1f5d5d666148355719346c8ee05f911e33) + +https://bugzilla.redhat.com/show_bug.cgi?id=1794691 + +Signed-off-by: Michal Privoznik +Message-Id: <033f07f79bc9fa26f669c83f9aa790bfaef25b93.1579874719.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 0905f222f1bfd9d741e94a8d653e05bb174846d3) +Signed-off-by: Jiri Denemark +Message-Id: <0b46ae9e26d1c7dbaa7f2dd58fd1156db237a853.1582186015.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + 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, "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\n", def->model); ++ if (def->type == VIR_CPU_TYPE_GUEST) ++ virBufferEscapeString(buf, " vendor_id='%s'", def->vendor_id); ++ ++ if (def->model) ++ virBufferEscapeString(buf, ">%s\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 @@ + hvm + + +- ++ ++ ++ + + destroy + restart +-- +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 +Date: Wed, 19 Feb 2020 15:10:19 +0100 +Subject: [PATCH] docs: Document the new sub-element of disk's + +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 element filled with either a for the +offset of the image format data. + +Add the XML documentation and RNG schema. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ + <disk type='block' device='lun'> + <driver name='qemu' type='raw'/> + <source dev='/dev/sda'> ++ <slices> ++ <slice type='storage' offset='12345' size='123'/> ++ </slices> + <reservations managed='no'> + <source type='unix' path='/path/to/qemu-pr-helper' mode='client'/> + </reservations> +@@ -3360,6 +3363,16 @@ + controller. + Since 6.0.0 +
    ++
    slices
    ++
    The slices element using its slice ++ sub-elements allows configuring offset and size of either the ++ location of the image format (slice type='storage') ++ inside the storage source or the guest data inside the image format ++ container (future expansion). ++ ++ The offset and size values are in bytes. ++ Since 6.1.0 ++
    + + +

    +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 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + + ++ ++ ++ ++ ++ storage ++ ++ ++ ++ ++ + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 1d742a8772848a72667e1e5e0fa0841abf0af647) + +https://bugzilla.redhat.com/show_bug.cgi?id=1762634 + +Signed-off-by: Andrea Bolognani +Message-Id: <20200214135034.719753-1-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 - +- since 3.2.0) +- or "hypervclock" +- (qemu - since 1.2.2). ++ since 3.2.0), "hypervclock" ++ (qemu - since 1.2.2) or ++ "armvtimer" (qemu - since 6.1.0). + + The hypervclock 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit aecf1f5d702ad710aed99a688f38f05cc304b03a) +Signed-off-by: Ján Tomko + +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: +Reviewed-by: Michal Privoznik +--- + 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 @@ +

    Backing chain management
    +
    Explanation of how disk backing chain specification impacts libvirt's + behaviour and basic troubleshooting steps of disk problems.
    ++ ++
    Virtio-FS
    ++
    Share a filesystem between the guest and the host
    + + + +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: ++ ++ :: ++ ++ ++ ... ++ ++ ++ ++ ++ ++ ... ++ ++ ++ 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 ++ ++ :: ++ ++ ++ ... ++ ++ ++ ++ ... ++ ++ ++ This will create a file in the directory specified in ``qemu.conf`` ++ ++ * Hugepage-backed memory ++ ++ :: ++ ++ ++ ... ++ ++ ++ ++ ++ ++ ++ ... ++ ++ ++#. Add the ``vhost-user-fs`` QEMU device via the ``filesystem`` element ++ ++ :: ++ ++ ++ ... ++ ++ ... ++ ++ ++ ++ ++ ++ ... ++ ++ ++ ++ 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 ++ ++:: ++ ++ ++ ++ ++ ++ +-- +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: +From: Laine Stump +Date: Thu, 30 Jan 2020 14:12:44 -0500 +Subject: [PATCH] docs: document subelement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Laine Stump +Reviewed-by: Daniel P. Berrangé +(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 +Message-Id: <20200130191244.24174-7-laine@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 @@ + </devices> + ... + ++
    Teaming a virtio/hostdev NIC pair
    ++ ++

    ++ 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) ++ ++ The <teaming> 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). ++

    ++ ++
    ++...
    ++<devices>
    ++  <interface type='network'>
    ++    <source network='mybridge'/>
    ++    <mac address='00:11:22:33:44:55'/>
    ++    <model type='virtio'/>
    ++    <teaming type='persistent'/>
    ++    <alias name='ua-backup0'/>
    ++  </interface>
    ++  <interface type='network'>
    ++    <source network='hostdev-pool'/>
    ++    <mac address='00:11:22:33:44:55'/>
    ++    <model type='virtio'/>
    ++    <teaming type='transient' persistent='ua-backup0'/>
    ++  </interface>
    ++</devices>
    ++...
    ++ ++

    ++ The <teaming> element required ++ attribute type will be set to ++ either "persistent" to indicate a device that ++ should always be present in the domain, ++ or "transient" 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 <teaming> called "persistent" ++ - this attribute should be set to the alias name of the other ++ device in the pair (the one that has <teaming ++ type="persistent'/>). ++

    ++

    ++ In the particular case of QEMU, ++ libvirt's <teaming> element is used to setup ++ a virtio-net "failover" device pair. For this setup, the ++ persistent device must be an interface with <model ++ type="virtio"/>, and the transient device must ++ be <interface type='hostdev'/> ++ (or <interface type='network'/> 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). ++

    ++

    ++ 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-"). ++

    ++

    ++ 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. ++

    ++

    ++ 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 <source> of the ++ hostdev NIC (<interface type='hostdev'>) 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. ++

    + +
    Multicast tunnel
    + +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 @@ + + +
    ++ ++ ++ support for virtio+hostdev NIC <teaming> ++ ++ ++ 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 <teaming> subelement ++ "type" and "persistent" attributes. ++ ++ + + + 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 +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 . Mention it in the docs. + +Signed-off-by: Peter Krempa +Reviewed-by: Pavel Hrdina +(cherry picked from commit 7d7e7e2c197782ce06525b0a63cd43e452c3a711) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 @@ + +

    Reports whether the hypervisor supports the backup, checkpoint, and + related features. (virDomainBackupBegin, +- virDomainCheckpointCreateXML etc). ++ virDomainCheckpointCreateXML etc). The presence of the ++ backup element even if supported='no' implies that ++ the VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA flag for ++ virDomainUndefine is supported. +

    + +

    SEV capabilities

    +-- +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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Fixes: f0f34056ab26eaa9f903a51cd1fa155088fd640f +(cherry picked from commit 5b63cb5abff09882feda8e333285259aecc8e9e8) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1805742 +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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 @@ + +

    + 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) + +-- +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 +Date: Wed, 19 Feb 2020 15:10:13 +0100 +Subject: [PATCH] docs: formatdomain: Close 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 +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ + <reservations managed='no'> + <source type='unix' path='/path/to/qemu-pr-helper' mode='client'/> + </reservations> ++ </source> + <target dev='sda' bus='scsi'/> + <address type='drive' controller='0' bus='0' target='3' unit='0'/> + </disk> +-- +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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit b24281c93405d6e3efb6edb3e7abff31628966b8) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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 @@ +

    + The protocol 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". + +-

    If the protocol attribute is "rbd", "sheepdog", +- "gluster", or "vxhs", an additional attribute name ++

    For any protocol other than nbd ++ an additional attribute name + is mandatory to specify which volume/image will be used. +

    + +-- +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: +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +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

    tags inside the +

  • , 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é +Reviewed-by: Ján Tomko +(cherry picked from commit 4be5a2f0c2c6f1236828592d8cb9ca5dc6f9df10) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <7d1090688b1ea9a76e46416d461784318b5cb8d4.1583322090.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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?= +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 ... +instead of .... 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
     blocks.
    +
    +Reviewed-by: Ján Tomko 
    +Signed-off-by: Daniel P. Berrangé 
    +(cherry picked from commit 039787c71a2bee6e60ddf5cb0515c0cdb85dd20b)
    +Signed-off-by: Ján Tomko 
    +https://bugzilla.redhat.com/show_bug.cgi?id=1694166
    +Message-Id: <72f7f14e62e058c436303fdeed68986f435b9011.1583322090.git.jtomko@redhat.com>
    +Reviewed-by: Michal Privoznik 
    +---
    + 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?= 
    +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:
    +
    + 
    +   
    +   
    +   
    +   
    + 
    +
    +Notice how core_id is repeated within the scope of the same socket_id.
    +
    +It now reports
    +
    + 
    +   
    +   
    +   
    +   
    + 
    +
    +So core_id is now unique within a (socket_id, die_id) pair.
    +
    +Reviewed-by: Daniel Henrique Barboza 
    +Reviewed-by: Jiri Denemark 
    +Signed-off-by: Daniel P. Berrangé 
    +(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 
    +---
    + 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 @@
    +         
    +           
    +         
    ++        
    ++          
    ++        
    +         
    +           
    +         
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -28,10 +28,10 @@
    +           6144
    +           8192
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -40,10 +40,10 @@
    +           8192
    +           10240
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -52,10 +52,10 @@
    +           10240
    +           12288
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -26,10 +26,10 @@
    +           6144
    +           8192
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -38,10 +38,10 @@
    +           8192
    +           10240
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -50,10 +50,10 @@
    +           10240
    +           12288
    +           
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -31,12 +31,12 @@
    +           6144
    +           8192
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -31,12 +31,12 @@
    +           6144
    +           8192
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -31,12 +31,12 @@
    +           6144
    +           8192
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    ++            
    +           
    +         
    +       
    +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 @@
    +           4096
    +           6144
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +         
    +@@ -31,12 +31,12 @@
    +           6144
    +           8192
    +           
    +-            
    +-            
    +-            
    +-            
    +-            
    +-            
    ++            
    ++            
    ++            
    ++            
    ++            
    ++            
    +           
    +         
    +       
    +-- 
    +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 
    +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 
    +Reviewed-by: Ján Tomko 
    +(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 
    +---
    + 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 
    +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 
    +Reviewed-by: Daniel P. Berrangé 
    +(cherry picked from commit d552b93448e253552c7e53a1240132c9763d2b24)
    +
    +https://bugzilla.redhat.com/show_bug.cgi?id=1798148
    +Message-Id: 
    +Reviewed-by: Ján Tomko 
    +---
    + 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
    + ````
    + 
    ++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 
    +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 
    +Reviewed-by: Ján Tomko 
    +(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 
    +---
    + 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 
    +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 
    +Reviewed-by: Masayoshi Mizuma 
    +Reviewed-by: Ján Tomko 
    +(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 
    +Message-Id: <20200214121237.623948-4-abologna@redhat.com>
    +Reviewed-by: Ján Tomko 
    +---
    + 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 @@
    +   
    +   
    +   
    ++  
    +   4002050
    +   0
    +   61700241
    +-- 
    +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 
    +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 
    +Tested-by: Lin Ma 
    +Reviewed-by: Jim Fehlig 
    +(cherry picked from commit a30078cb832646177defd256e77c632905f1e6d0)
    +
    +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1814157
    +
    +Signed-off-by: Michal Privoznik 
    +
    +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 
    +Message-Id: <7a59996bd80955551d37f775e8d682649b1f4a45.1584457667.git.mprivozn@redhat.com>
    +Acked-by: Peter Krempa 
    +---
    + 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 
    +@@ -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 
    + 
    + #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 @@
    ++
    ++    
    ++    
    ++        
    ++    
    ++    
    ++  
    ++ +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 @@ ++ ++ hotplug ++ d091ea82-29e6-2e34-3005-f02617b36e87 ++ 4194304 ++ 4194304 ++ 4 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ restart ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++
    ++ ++ ++ ++
    ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +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: +From: Michal Privoznik +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 +Reviewed-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit aeb909bf9b4c3fa48d017475545df94f7c5d3b3a) +Signed-off-by: Michal Privoznik +Message-Id: <3f21a46399486a42b8dd0fbbac25b75f4f6ac80a.1584643597.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: Jiri Denemark +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 +Reviewed-by: Ján Tomko +(cherry picked from commit bd04d63ad97c21b6955710e6473a502f49816a3c) + +https://bugzilla.redhat.com/show_bug.cgi?id=1791886 + +Signed-off-by: Jiri Denemark +Message-Id: <9b32d5af0dd1d3bf7108abc426dc4d6ceeaa84f8.1579193220.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: Jonathon Jongsma +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 +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +(cherry picked from commit 306b4cb070b8f57a22a261d1f097283f4ef84e65) +Signed-off-by: Jonathon Jongsma +https://bugzilla.redhat.com/show_bug.cgi?id=1759566 +Message-Id: <20200220165227.11491-4-jjongsma@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Andrea Bolognani +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 +Reviewed-by: Masayoshi Mizuma +Reviewed-by: Ján Tomko +(cherry picked from commit 7c4bc108a9bd7bda1543131d232e2ccee92a9e43) + +https://bugzilla.redhat.com/show_bug.cgi?id=1762634 + +Signed-off-by: Andrea Bolognani +Message-Id: <20200214121237.623948-7-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit bb2a81df21710ed8258854e0dc2b3c2e923831f2) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 740dd1a4e5ce81e5b0be855dd413dd7eec81ccd3) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit 4c581527d431939a63be70c201b4ddab703cddbe) +Signed-off-by: Michal Privoznik +Message-Id: <4048f92488a8b8c31c7a17a14b579840a9492328.1579165329.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: Michal Privoznik +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 +Reviewed-by: Peter Krempa +(cherry picked from commit 13eb6c14682004d0dc692554475125db0f161da7) +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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: +From: Michal Privoznik +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 +Reviewed-by: Daniel Henrique Barboza + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1718707 + +(cherry picked from commit 3203ad6cfd617fb11d4bb47e514c370b6624641b) +Signed-off-by: Michal Privoznik +Message-Id: <5e58b5853f9bd1a2b5109145afdad190071f5c44.1579165329.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Masayoshi Mizuma +Reviewed-by: Ján Tomko +(cherry picked from commit f8e923c1ba70d7be53ea18d9b4de040763347f9e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1762634 + +Signed-off-by: Andrea Bolognani +Message-Id: <20200214121237.623948-3-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Masayoshi Mizuma +Reviewed-by: Ján Tomko +(cherry picked from commit aeddab230cd1e2a12d5d6352971bb70ea067a1c4) + +https://bugzilla.redhat.com/show_bug.cgi?id=1762634 + +Signed-off-by: Andrea Bolognani +Message-Id: <20200214121237.623948-6-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Peter Krempa +Acked-by: Stefan Hajnoczi +Reviewed-by: Daniel P. Berrangé +Tested-by: Andrea Bolognani +(cherry picked from commit d99128a62b9f84e3e5b372d1e6419f4f1d1dffe6) +Signed-off-by: Ján Tomko + +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 +--- + 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 @@ + + + ++ + 4001050 + 0 + 61700242 +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 @@ + + + ++ + 4001050 + 0 + 39100242 +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 @@ + + + ++ + 4002000 + 0 + 43100242 +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 @@ + + + ++ + 4002050 + 0 + 61700241 +-- +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: +From: Laine Stump +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 +Reviewed-by: Daniel P. Berrangé +(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 +Message-Id: <20200130191244.24174-2-laine@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 @@ + + + ++ + 4001050 + 0 + 61700242 +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 @@ + + + ++ + 4002000 + 0 + 43100242 +-- +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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 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 +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit f0f986efa8a8e352fbdce7079ec440a4f3c8f522) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <78ba169fbe59c5307db462ad78b65b06776d64a6.1583322091.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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 + ++#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 ++ * . ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#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 ++ * . ++ */ ++ ++#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?= +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 +Reviewed-by: Jiri Denemark +Signed-off-by: Daniel P. Berrangé +(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 +--- + 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 @@ + + + ++ + 4001000 + 0 + 43100241 +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 @@ + + + ++ + 4001050 + 0 + 61700242 +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 @@ + + + ++ + 4001050 + 0 + 42900242 +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 @@ + + + ++ + 4001050 + 0 + 39100242 +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 @@ + + + ++ + 4002000 + 0 + 43100242 +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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 4 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ ++ ++ +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?= +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 +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit f04319a5449974f1553458e96c2a6ee25e65ab93) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <6e46af8184e9e982a6aca92a62534623795bb1fc.1583322091.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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 +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 +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 8a226ddb3602586a2ba2359afc4448c02f566a0e) + +https://bugzilla.redhat.com/1693587 +Signed-off-by: Laine Stump +Message-Id: <20200130191244.24174-6-laine@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Laine Stump +Date: Thu, 30 Jan 2020 14:12:42 -0500 +Subject: [PATCH] qemu: allow migration with assigned PCI hostdev if + 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 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 +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 2758f680b7d586baf084f340b153d7706b8ce12b) + +https://bugzilla.redhat.com/1693587 +Signed-off-by: Laine Stump +Message-Id: <20200130191244.24174-5-laine@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 ")); ++ 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 "), ++ virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type)); ++ return false; ++ ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: ++ /* ++ * if this is a network interface with , 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 "), ++ 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: +From: Peter Krempa +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 +Reviewed-by: Daniel Henrique Barboza +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Eric Blake +(cherry picked from commit bce4ac55f8d3df9d649c74d2f35feeaad4422028) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ + + + ++ ++ testcookievalue ++ blurb ++ + + + +@@ -39,6 +43,10 @@ + + + ++ ++ testcookievalue ++ blurb ++ + + + +-- +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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 41c7e5c2a689a4ad091cec40b61beeeb3dde49b8) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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: + + + + + + + + + + +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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: + +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 1753f605506e28eb42bc5bb6fa9abe8fcbe6fb9b) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ + + + ++ + + + +@@ -24,6 +25,7 @@ + + + ++ + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 304da9376c972413d77cc6c7f094a1b39d651ea8) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 @@ + + + ++ + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit ffc6249c79dbf980d116af7c7ed20222538a7c1c) +Message-Id: <05fc4389e00afd4b8bf5653fb730c4d8f6a4516d.1585581552.git.pkrempa@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Peter Krempa +Date: Wed, 19 Feb 2020 15:10:18 +0100 +Subject: [PATCH] qemu: block: forbid creation of storage sources with +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 96063ce280a398493d7a78a35f674ed25078d849) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit cc7868a8b3cfa4a0062936c23e82e4a31923f724) + +https://bugzilla.redhat.com/show_bug.cgi?id=1803092 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit db450a742224fb96d8f4d45fde3d0c19faeabfdb) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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, "%s", 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 @@ + + + +- ++ + + + +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 @@ + + + +- ++ + + +- ++ + + + + + +- ++ + + +- ++ + + + +-- +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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 41de7230ab169e80237f3e3a29bfecd9baf1a578) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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, "\n", job->data.commit.base->nodeformat); + +@@ -2614,6 +2617,11 @@ qemuDomainPrivateBlockJobFormatCommit(qemuBlockJobDataPtr job, + + if (job->data.commit.deleteCommittedImages) + virBufferAddLit(buf, "\n"); ++ ++ while (bitmaps && *bitmaps) ++ virBufferEscapeString(&disabledBitmapsBuf, "\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 @@ + + + ++ ++ ++ ++ + + + +-- +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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit 0627150a56fd53841918d558d8466feceb18552a) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <2df3adbe3991cb97a06707e818c30dfcb1f6de26.1583322091.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(cherry picked from commit ecdd92976144ba9caeae3ce781e39b5e9cc08807) + +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 135a0b3f7142a8d4f591bb24b3ae7d0f36877bf7) + +https://bugzilla.redhat.com/show_bug.cgi?id=1819755 + +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 30bc426071c0f5957af01181c063cd68ade97899) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(cherry picked from commit 606dc66b0958fe3545a318ae9bc6a62a67786378) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(cherry picked from commit 7973f7d7926ac9dbc5464e6be6eb2aaacecc2251) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit f3e0a45a00465a6f19f510f7806ade1764a7e162) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 44e1b85717b9a4e6df24f9cbf846627e4f29b859) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(cherry picked from commit f19248a1395e59abbd68ac31af3d9bd1273555bf) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Fixes: f02e21cb3379a41cd42f2d8116f2d10dabace83b +https://bugzilla.redhat.com/show_bug.cgi?id=1800505 +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit bd622e2a211aad449b54683e2ebd5e980418dd7c) +Signed-off-by: Ján Tomko +Message-Id: <6096c4347521d1493728cc7842f6ad455665b744.1581350626.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 +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 +Reviewed-by: Daniel P. Berrangé +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 0b0f389335e5d11150fa60561cae960f20d5ca44) + +https://bugzilla.redhat.com/show_bug.cgi?id=1792195 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Pavel Mores +Reviewed-by: Eric Blake +(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 +--- + 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, "\n", job->data.commit.base->nodeformat); ++ ++ if (job->data.commit.top) ++ virBufferAsprintf(buf, "\n", job->data.commit.top->nodeformat); ++ ++ if (job->data.commit.topparent) ++ virBufferAsprintf(buf, "\n", job->data.commit.topparent->nodeformat); ++ ++ if (job->data.commit.deleteCommittedImages) ++ virBufferAddLit(buf, "\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, "\n", job->data.commit.base->nodeformat); +- if (job->data.commit.top) +- virBufferAsprintf(&childBuf, "\n", job->data.commit.top->nodeformat); +- if (job->data.commit.topparent) +- virBufferAsprintf(&childBuf, "\n", job->data.commit.topparent->nodeformat); +- if (job->data.commit.deleteCommittedImages) +- virBufferAddLit(&childBuf, "\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 +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 +Reviewed-by: Pavel Mores +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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, "\n"); +- virBufferAdjustIndent(buf, 2); +- virBufferEscapeString(buf, "\n", src->nodestorage); +- virBufferEscapeString(buf, "\n", src->nodeformat); +- virBufferAdjustIndent(buf, -2); +- virBufferAddLit(buf, "\n"); +- } ++ virBufferEscapeString(&nodenamesChildBuf, "\n", src->nodestorage); ++ virBufferEscapeString(&nodenamesChildBuf, "\n", src->nodeformat); ++ ++ virXMLFormatElement(buf, "nodenames", NULL, &nodenamesChildBuf); + + if (src->pr) + virBufferAsprintf(buf, "\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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 180b3422e9a3391a0ee59d0076730ba85778fc7a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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: +Reviewed-by: Ján Tomko +--- + 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 @@ + + + ++ + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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, "\n", src->nodestorage); + virBufferEscapeString(&nodenamesChildBuf, "\n", src->nodeformat); + ++ if (src->sliceStorage) ++ virBufferEscapeString(&nodenamesChildBuf, "\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 @@ + + + ++ ++ ++ + + + +@@ -322,6 +325,7 @@ + + + ++ + + + base.qcow2 +-- +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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 599ae372d8cf0923757c5a3792acb07dcf3e8802) +Signed-off-by: Jonathon Jongsma +https://bugzilla.redhat.com/show_bug.cgi?id=1759566 +Message-Id: <20200220165227.11491-5-jjongsma@redhat.com> +Reviewed-by: Ján Tomko +--- + 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), +- ¶ms, &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), ¶ms, +- &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?= +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 +Reviewed-by: Peter Krempa +(cherry picked from commit d5256cbd5575fb714714de1d543d1e5d41daf8ff) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <1a2cb184deb18bf67e3fdc50785e829f74d89352.1583322090.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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?= +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 +Reported-by: Dan Zheng +Fixes: e005c95f56fee9ed780be7f8db103d690bd34cbd +(cherry picked from commit d61f95cf6a6fbd564e104c168d325581acd9cd8d) +Signed-off-by: Ján Tomko +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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?= +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 +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit 5c0444a38bb37ddeb7049683ef72d02beab9e617) +Signed-off-by: Ján Tomko + +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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +Reviewed-by: Daniel Henrique Barboza +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 9f436e067df2e4465228c8ba536dcf9f9445aabc) + +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Jiri Denemark +(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 +--- + 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?= +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 +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit 6baf97ef2c7416f3d81bdc6cf20f121b62c8fd4f) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: +Reviewed-by: Michal Privoznik +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Fixes: f02e21cb3379a41cd42f2d8116f2d10dabace83b +https://bugzilla.redhat.com/show_bug.cgi?id=1800505 +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit 457b0e74888f61b759e334d91479c258663835d5) +Signed-off-by: Ján Tomko +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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?= +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 +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit 9de5d69c218faa0e25c5d6a56ab5f6bacbd1a132) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <7653ce933656c9a13c9afa2a019ef11fb192bdc4.1583322091.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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: +From: Jonathon Jongsma +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 3c436c22a4f94c85c2b5e7b5fb84af48219d78e3) +Signed-off-by: Jonathon Jongsma +https://bugzilla.redhat.com/show_bug.cgi?id=1759566 +Message-Id: <20200220165227.11491-6-jjongsma@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: Jonathon Jongsma +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit e888c0f66752bb6516d63a612c20f565cbf9c0ca) +Signed-off-by: Jonathon Jongsma +https://bugzilla.redhat.com/show_bug.cgi?id=1759566 +Message-Id: <20200220165227.11491-2-jjongsma@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit 8e9e73a984165d5e9a82ba1f4531bb30482db5a8) + +https://bugzilla.redhat.com/show_bug.cgi?id=1524278 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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?= +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 +Fixes: b168fa88b85dec181882816ab65a59a6c4500667 +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Andrea Bolognani +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit bdb8a800b4920cf9184fd2fd117b17c67ba74dfb) +Signed-off-by: Jonathon Jongsma +https://bugzilla.redhat.com/show_bug.cgi?id=1759566 +Message-Id: <20200220165227.11491-3-jjongsma@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +Date: Thu, 30 Jan 2020 14:12:41 -0500 +Subject: [PATCH] qemu: support interface functionality +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The QEMU driver uses the 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 +( or 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 +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit eb9f6cc4b3464707cf689fda9812e5129003bf27) + +https://bugzilla.redhat.com/1693587 +Signed-off-by: Laine Stump +Message-Id: <20200130191244.24174-4-laine@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 , 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Peter Krempa +(cherry picked from commit e2ca6eb08731255b9b7cf3e938d20f4eae9fb427) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <3876fc88964781aec976d1a92b810aa9cf53c656.1583322090.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit 071a1ab92fbbd58f68fb4929d004d6155759067e) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: +Reviewed-by: Michal Privoznik +--- + 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?= +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 +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +Reviewed-by: Masayoshi Mizuma +(cherry picked from commit efaf46811c909ee5333360fba1d75ae82352964a) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <1fcb6b7d58c3791799c5d436edaa2faa07e92305.1583322091.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Suggested-by: Andrea Bolognani +Reviewed-by: Michal Privoznik +(cherry picked from commit 7055af6c2253666cd0b7c4c459c5a019da789140) +Signed-off-by: Ján Tomko +Message-Id: <619956878ec3e09fe6481c7e25b2820753aa57e5.1585045801.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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?= +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 223b370aaa6fcbcbfbd4045fde4ae67e047180ad) +Signed-off-by: Ján Tomko +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit e060b0624d1b78438b759cc5a25da87b28c9736c) +Message-Id: <95ad49e5316e5f9dd992e463bc7536e3046140d4.1585243469.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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é +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Tested-by: Daniel P. Berrangé +(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 +--- + 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 +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é +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Tested-by: Daniel P. Berrangé +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 7ba2208addf1cad4d6c06d3c172cca93f84ead11) +Message-Id: <9a56b9f7e03d41bf99399b14f399bc9007ed1a4e.1585063415.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 3b06103e695829c4720baaee8286f20568133ebd) +https://bugzilla.redhat.com/show_bug.cgi?id=1804617 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 @@ ++ ++ ++ ++ ++ ++ ++ 123456 ++ here ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit c60fe3106e8b91478e54129b4b1b81cc0543399e) +https://bugzilla.redhat.com/show_bug.cgi?id=1804617 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Erik Skultety +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit c4818812831967b8f882b2c33780aab129e245a2) + +https://bugzilla.redhat.com/show_bug.cgi?id=1791788 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ + + + +- ++ + + + +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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit c6d117528cc0ddb325abd67d69b6d4ebc1bfe608) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(cherry picked from commit 0ce8b0fbe2d0cbaf26da0402270720b776ebfb0f) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 54030892f5122ef120c1e8ffb6e0546871030272) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 530ac288618b2f46e49f3ce86d4d89e7607ee3fe) +https://bugzilla.redhat.com/show_bug.cgi?id=1812965 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 43a3d2e02ed09fafa04b61815c23651b0a94ef58) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 9bf9e0ae6af38c806f4672ca7b12a6b38d5a9581) +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Daniel Henrique Barboza + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1718707 + +(cherry picked from commit 1c16f261d0764ff70fb33ece4367f25e741cdb74) +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Daniel Henrique Barboza + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1718707 + +(cherry picked from commit 82e127e34350dc0ed908611a3b2a4fbd78ad9903) +Signed-off-by: Michal Privoznik +Message-Id: <5d41d06ee27842659082e67dd6abf40c3c59ae5d.1579165329.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit b544481a91e6f3ee0e7534e0fc3d2cfb3bb60dba) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 70d2758a9cee795b26563fe33b38a2396efa2324) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit b05322fc0376670edd54f9689ac8cda852581edc) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit ae64a75a8713cf14b25b40078766c2da93e001ff) +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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?= +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 +Reviewed-by: Daniel P. Berrangé +Tested-by: Andrea Bolognani +(cherry picked from commit b164eac5e1d4ebe17e673f0427b70f862a670f94) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <44ec9897e79f7482dc22611526a154915bb02cdb.1583322090.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit bdff9d4513694da8d9b2bb60a1f808fb1c286388) + +https://bugzilla.redhat.com/show_bug.cgi?id=1793263 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 3093822d1d8e3bbd01ea59f35a9fea1228f9268f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1793263 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +Reviewed-by: Daniel Henrique Barboza +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit 643294110c12a41faf2cf24c19948aaee0fcf36f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1798366 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit a592d589aa5015f5beb0f1d4302ceffe9fe7f7e8) + +https://bugzilla.redhat.com/show_bug.cgi?id=1798366 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Michal Privoznik +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 +Reviewed-by: Peter Krempa +(cherry picked from commit c76009313f8068c848cad6cb517daf42e6716bb9) + +https://bugzilla.redhat.com/show_bug.cgi?id=1794691 + +Signed-off-by: Michal Privoznik +Message-Id: <48a4b2f9ab1e8157e4b7baf1b506e90861a39308.1579874719.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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: +From: Michal Privoznik +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 +Reviewed-by: Peter Krempa +(cherry picked from commit cc361a34c53210d682dbc5f2d506b4a23b71e399) + +https://bugzilla.redhat.com/show_bug.cgi?id=1794691 + +Signed-off-by: Michal Privoznik +Message-Id: <5de22b27463cd2803b3910d7ef45a0e4bc08ad47.1579874719.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit b18328256b565806c04c153ce49fc3641412b35b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1519005#c24 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit d089234110282069e9a6dfe879ca257d114bb5bd) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Tested-by: Daniel P. Berrangé +(cherry picked from commit cab3622119a73a54e62e5f2d7b4257da00bd4ac8) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + .../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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(cherry picked from commit f8389505aae66e705046f5cbd9fe4ac10f1dee2e) +https://bugzilla.redhat.com/show_bug.cgi?id=1799013 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 7f8d0ca56a8335b29f3973e5490815c7cfbeac13) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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, "\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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 @@ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + .../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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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: +From: Jiri Denemark +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 + + + +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 1939fbef989e6990cb5dd2d2d7ff8ea002c517c2) +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + .../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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 6 ++ ++ hvm ++ ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++
    ++ ++ ++ ++ ++ ++
    ++ ++ ++ +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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit c34ec56abad4b2286ef82a0a3ab9deb4d807a9bf) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 + +Conflicts: The XML output file differs in the element as changes + in default cpu handling were not backported. +Message-Id: +Reviewed-by: Jiri Denemark +--- + .../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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ testcookievalue ++ blurb ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ ++ testcookievalue ++ blurb ++ ++ ++ ++
    ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ +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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Peter Krempa +Tested-by: Andrea Bolognani +(cherry picked from commit 99dc98db3d3e2381f322120bf00c25ba0501b092) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: +Reviewed-by: Michal Privoznik +--- + 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 +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 +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Peter Krempa +Acked-by: Stefan Hajnoczi +Reviewed-by: Daniel P. Berrangé +Tested-by: Andrea Bolognani +(cherry picked from commit 3913abd476cfe663db978d9110daa8bdc6d4e5b6) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: +Reviewed-by: Michal Privoznik +--- + 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 --> +- +- +- +- path +- handle +- loop +- nbd +- ploop +- +- +- +- +- +- +- +- +- +- +- immediate +- +- +- +- ++ ++ ++ ++ ++ ++ path ++ handle ++ loop ++ nbd ++ ploop ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ immediate ++ ++ ++ ++ ++ ++ + + + +-- +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: +From: Han Han +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 +Reviewed-by: Erik Skultety +(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 +--- + 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 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1667,24 +1669,26 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1695,17 +1699,19 @@ + + + +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1856,138 +1862,152 @@ + + + +- +- +- https +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ https ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + +- +- +- http +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ http ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + +- +- +- ftps +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ftps ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + +- +- +- sheepdog +- ftp +- tftp +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ sheepdog ++ ftp ++ tftp ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + +- +- nbd +- +- +- +- +- +- +- ++ ++ ++ nbd + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + +- +- gluster +- +- +- +- +- +- +- +- +- ++ ++ ++ gluster ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + +- +- +- vxhs +- +- +- +- +- +- +- ++ ++ ++ ++ vxhs ++ + +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2014,30 +2034,32 @@ + + + +- +- +- +- +- +- +- +- +- +- host +- direct +- ++ ++ ++ + +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ host ++ direct ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2048,27 +2070,29 @@ + + + +- +- pci +- +- +- +- +- +- +- ++ ++ ++ pci + +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +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 +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 +Reviewed-by: Peter Krempa +(cherry picked from commit f16663d58f7aab6bf800fcffd34f83f522927897) +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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: +From: Michal Privoznik +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 +Reviewed-by: Peter Krempa +(cherry picked from commit 5fddf61351f44e4186c0313d81907024c574201b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1804672 + +Signed-off-by: Michal Privoznik +Message-Id: <4c2586a6da3b01adce09573a6123a15b3aea5ae6.1582626185.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 +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 +Reviewed-by: Peter Krempa +(cherry picked from commit 62f3d8adbc0381223499ff2bef45b23e7dca401d) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1803551 +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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", "\n"); ++ TEST_BACKING_PARSE("fat:/somedir", "\n"); + TEST_BACKING_PARSE("://", NULL); + TEST_BACKING_PARSE("http://example.com", + "\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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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, ++ "\n" ++ "
    \n" ++ "\n"); ++ + TEST_JSON_FORMAT_NET("\n" + " \n" + "\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) + " \n" + "\n", 0); + ++ TEST_BACKING_PARSE("json:{\"file\":{\"driver\": \"nvme\"," ++ "\"device\": \"0000:01:00.0\"," ++ "\"namespace\": 1" ++ "}" ++ "}", ++ "\n" ++ "
    \n" ++ "\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: +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 93171b63c3a28dad06c3af6d2483d953a6f79ad2) +https://bugzilla.redhat.com/show_bug.cgi?id=1804617 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +Message-Id: <20200214121237.623948-2-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + .../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 @@ ++ ++ /usr/bin/qemu-system-aarch64 ++ kvm ++ virt-5.0 ++ aarch64 ++ ++ ++ ++ ++ efi ++ ++ ++ /usr/share/AAVMF/AAVMF_CODE.fd ++ /usr/share/AAVMF/AAVMF32_CODE.fd ++ /usr/share/OVMF/OVMF_CODE.fd ++ ++ rom ++ pflash ++ ++ ++ yes ++ no ++ ++ ++ no ++ ++ ++ ++ ++ ++ ++ ++ pxa262 ++ pxa270-a0 ++ arm1136 ++ cortex-a15 ++ pxa260 ++ arm1136-r2 ++ pxa261 ++ pxa255 ++ cortex-a72 ++ cortex-m33 ++ arm926 ++ cortex-r5f ++ arm11mpcore ++ pxa250 ++ ti925t ++ cortex-a57 ++ sa1110 ++ arm1176 ++ cortex-a53 ++ sa1100 ++ pxa270-c5 ++ cortex-a9 ++ cortex-m7 ++ cortex-a8 ++ cortex-a7 ++ pxa270-c0 ++ arm1026 ++ pxa270-b1 ++ cortex-m3 ++ max ++ cortex-m4 ++ pxa270-b0 ++ arm946 ++ cortex-m0 ++ cortex-r5 ++ pxa270-a1 ++ pxa270 ++ ++ ++ ++ ++ ++ disk ++ cdrom ++ floppy ++ lun ++ ++ ++ fdc ++ scsi ++ virtio ++ usb ++ sata ++ ++ ++ virtio ++ virtio-transitional ++ virtio-non-transitional ++ ++ ++ ++ ++ sdl ++ vnc ++ ++ ++ ++ ++ ++ subsystem ++ ++ ++ default ++ mandatory ++ requisite ++ optional ++ ++ ++ usb ++ pci ++ scsi ++ ++ ++ ++ default ++ vfio ++ ++ ++ ++ ++ virtio ++ virtio-transitional ++ virtio-non-transitional ++ ++ ++ random ++ egd ++ ++ ++ ++ ++ ++ ++ 3 ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ /usr/bin/qemu-system-aarch64 ++ kvm ++ integratorcp ++ aarch64 ++ ++ ++ ++ ++ ++ /usr/share/AAVMF/AAVMF_CODE.fd ++ /usr/share/AAVMF/AAVMF32_CODE.fd ++ /usr/share/OVMF/OVMF_CODE.fd ++ ++ rom ++ pflash ++ ++ ++ yes ++ no ++ ++ ++ no ++ ++ ++ ++ ++ ++ ++ ++ pxa262 ++ pxa270-a0 ++ arm1136 ++ cortex-a15 ++ pxa260 ++ arm1136-r2 ++ pxa261 ++ pxa255 ++ cortex-a72 ++ cortex-m33 ++ arm926 ++ cortex-r5f ++ arm11mpcore ++ pxa250 ++ ti925t ++ cortex-a57 ++ sa1110 ++ arm1176 ++ cortex-a53 ++ sa1100 ++ pxa270-c5 ++ cortex-a9 ++ cortex-m7 ++ cortex-a8 ++ cortex-a7 ++ pxa270-c0 ++ arm1026 ++ pxa270-b1 ++ cortex-m3 ++ max ++ cortex-m4 ++ pxa270-b0 ++ arm946 ++ cortex-m0 ++ cortex-r5 ++ pxa270-a1 ++ pxa270 ++ ++ ++ ++ ++ ++ disk ++ cdrom ++ floppy ++ lun ++ ++ ++ fdc ++ scsi ++ virtio ++ usb ++ sata ++ ++ ++ virtio ++ virtio-transitional ++ virtio-non-transitional ++ ++ ++ ++ ++ sdl ++ vnc ++ ++ ++ ++ ++ ++ subsystem ++ ++ ++ default ++ mandatory ++ requisite ++ optional ++ ++ ++ usb ++ pci ++ scsi ++ ++ ++ ++ default ++ vfio ++ ++ ++ ++ ++ virtio ++ virtio-transitional ++ virtio-non-transitional ++ ++ ++ random ++ egd ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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" ++ }, ++ { ++ "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" ++ }, ++ { ++ "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" ++ }, ++ { ++ "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" ++ }, ++ { ++ "default-value": 128, ++ "name": "virtqueue_size", ++ "type": "uint32" ++ }, ++ { ++ "default-value": true, ++ "name": "hotplug", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-backend", ++ "type": "child" ++ }, ++ { ++ "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" ++ }, ++ { ++ "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" ++ }, ++ { ++ "default-value": false, ++ "name": "free-page-hint", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-backend", ++ "type": "child" ++ }, ++ { ++ "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" ++ }, ++ { ++ "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" ++ }, ++ { ++ "name": "hotplugged", ++ "type": "bool" ++ }, ++ { ++ "name": "hotpluggable", ++ "type": "bool" ++ }, ++ { ++ "name": "realized", ++ "type": "bool" ++ }, ++ { ++ "name": "legacy-memory", ++ "type": "str" ++ }, ++ { ++ "name": "memory", ++ "type": "link" ++ }, ++ { ++ "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" ++ }, ++ { ++ "name": "unnamed-gpio-in[1]", ++ "type": "child" ++ }, ++ { ++ "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" ++ }, ++ { ++ "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" ++ }, ++ { ++ "name": "sve512", ++ "type": "bool" ++ }, ++ { ++ "name": "sve896", ++ "type": "bool" ++ }, ++ { ++ "name": "gicv3-maintenance-interrupt[0]", ++ "type": "link" ++ }, ++ { ++ "name": "sve1024", ++ "type": "bool" ++ }, ++ { ++ "name": "pmu-interrupt[0]", ++ "type": "link" ++ }, ++ { ++ "name": "sve1280", ++ "type": "bool" ++ }, ++ { ++ "name": "sve1536", ++ "type": "bool" ++ }, ++ { ++ "name": "unnamed-gpio-in[2]", ++ "type": "child" ++ }, ++ { ++ "name": "sve-max-vq", ++ "type": "uint32" ++ }, ++ { ++ "name": "sve", ++ "type": "bool" ++ }, ++ { ++ "name": "unnamed-gpio-in[0]", ++ "type": "child" ++ }, ++ { ++ "name": "sve256", ++ "type": "bool" ++ }, ++ { ++ "name": "sve1792", ++ "type": "bool" ++ }, ++ { ++ "name": "unnamed-gpio-out[3]", ++ "type": "link" ++ }, ++ { ++ "name": "cfgend", ++ "type": "bool" ++ }, ++ { ++ "name": "pmu", ++ "type": "bool" ++ }, ++ { ++ "name": "unnamed-gpio-out[1]", ++ "type": "link" ++ }, ++ { ++ "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" ++ }, ++ { ++ "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" ++ } ++ ], ++ "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 @@ ++ ++ /usr/bin/qemu-system-aarch64 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 4002050 ++ 0 ++ 61700241 ++ v4.2.0-1157-gadcd6e93b9 ++ aarch64 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 76121fc9c49d26c1ca4f596c3cac5c05eb02fc76) + +https://bugzilla.redhat.com/show_bug.cgi?id=1762634 + +Signed-off-by: Andrea Bolognani +Message-Id: <20200214131451.707092-1-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + .../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 @@ ++ ++ guest ++ 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 ++ 4194304 ++ 4194304 ++ 4 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-aarch64 ++ ++ ++ ++ ++ +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: +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +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 +Reviewed-by: Jiri Denemark +Signed-off-by: Daniel P. Berrangé +(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 +--- + .../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 @@ ++ ++ ++ ++ ++ x86_64 ++ ++ ++ ++ ++ ++ ++ 1048576 ++ 2048 ++ 4096 ++ 6144 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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: +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +Date: Wed, 19 Feb 2020 15:10:25 +0100 +Subject: [PATCH] tests: qemu: Add test data for the new element +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(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 +Message-Id: <21b28fdf8e4fc8aaf9a68b8c32be5d5a1fdedacc.1582120424.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + .../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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
    ++ ++ ++
    ++ ++ ++ ++ ++ ++
    ++ ++ ++ +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 +Date: Wed, 19 Feb 2020 15:10:23 +0100 +Subject: [PATCH] tests: qemublock: Add cases for creating image overlays on + top of disks with +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 065e548ebf0e39c8f9d30d0637ecfa84803d8f98) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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) + "}" + "}", + "\n"); ++ TEST_BACKING_PARSE("json:{\"driver\":\"file\"," ++ "\"filename\":\"/path/to/file\"" ++ "}", ++ "\n"); + TEST_BACKING_PARSE("json:{\"file.driver\":\"host_device\", " + "\"file.filename\":\"/path/to/dev\"}", + "\n"); +@@ -1389,6 +1393,12 @@ mymain(void) + "\n" + " \n" + "\n"); ++ TEST_BACKING_PARSE("json:{\"driver\":\"nbd\"," ++ "\"path\":\"/path/to/socket\"" ++ "}", ++ "\n" ++ " \n" ++ "\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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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) + "\n" + " \n" + "\n"); ++ TEST_BACKING_PARSE_FULL("json:{ \"driver\": \"raw\"," ++ "\"offset\": 10752," ++ "\"size\": 4063232," ++ "\"file\": { \"driver\": \"file\"," ++ "\"filename\": \"/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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +Reviewed-by: Ján Tomko +(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 +Reviewed-by: Richard W.M. Jones +--- + 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) + "\n" + " \n" + "\n"); ++ TEST_BACKING_PARSE("nbd+unix://?socket=/tmp/sock", ++ "\n" ++ " \n" ++ "\n"); ++ TEST_BACKING_PARSE("nbd+unix:///?socket=/tmp/sock", ++ "\n" ++ " \n" ++ "\n"); ++ TEST_BACKING_PARSE("nbd+unix:////?socket=/tmp/sock", ++ "\n" ++ " \n" ++ "\n"); ++ TEST_BACKING_PARSE("nbd+unix:///exp?socket=/tmp/sock", ++ "\n" ++ " \n" ++ "\n"); ++ TEST_BACKING_PARSE("nbd+unix:////exp?socket=/tmp/sock", ++ "\n" ++ " \n" ++ "\n"); + TEST_BACKING_PARSE_FULL("iscsi://testuser:testpass@example.org:1234/exportname", + "\n" + " \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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit e5c8f6e0800106c9331c975344086c7834fcae2a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1798148 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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?= +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 +Reviewed-by: Erik Skultety +(cherry picked from commit fdd48f5b737c09a0581bf666d1578f5bd5d0de12) + +Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499 + +Signed-off-by: Michal Privoznik +Message-Id: <6c9d9490de405d56f3fd787dd5d02d3fb4943bb4.1584101247.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(cherry picked from commit 50f7483a0d69906e90849f7f0a30f3f535021852) + +https://bugzilla.redhat.com/show_bug.cgi?id=1793263 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 3b60a0c0276ae7200b0bff7394e0d1e00706a1dd) + +https://bugzilla.redhat.com/show_bug.cgi?id=1207659 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Reported-by: Ming Xie +Reviewed-by: Eric Blake +Tested-by: Richard W.M. Jones +(cherry picked from commit 5f2fa393f721861132500f717ce509bb66afcdb7) +Message-Id: <79e24a6416d5bfbba6cdb2764b29663c2f8ccd45.1579263320.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +Reviewed-by: Richard W.M. Jones +--- + 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) + "\n" + " \n" + "\n"); ++ TEST_BACKING_PARSE("nbd:unix:/tmp/sock:exportname=/", ++ "\n" ++ " \n" ++ "\n"); + TEST_BACKING_PARSE("nbd://example.org:1234", + "\n" + " \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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 6efa04616553c573700906cb7154a8ceb3bd2cb3) + +https://bugzilla.redhat.com/show_bug.cgi?id=1791788 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Signed-off-by: Peter Krempa +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 4d5093ef75efdf87a941ffd3fbc1d974e031a0a3) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804603 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit e20c5b17037acca0cfffd983c0bcdd0ee5b7e628) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804603 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit c5b1c14379994369f5cb92bbb3da36d7d19150c2) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804603 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Michal Privoznik +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Peter Krempa +(cherry picked from commit 3918dbd84e4951b43f93fbf50ef52be00274850c) +Signed-off-by: Michal Privoznik +Message-Id: +Acked-by: Peter Krempa +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 63469116cc83d6d83a45b741826b48562b03a65f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1804603 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 doesn't use 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit d8b4f70e1e36772ef82dbe0f0706fa7845583e6c) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1694166 +Message-Id: <77519310a2e8c09b41bfcc0c8e37b1c2dcb35b5c.1583322090.git.jtomko@redhat.com> +Reviewed-by: Michal Privoznik +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 2ab278ec758b09398ea335626a41b453cdda6da7) +Signed-off-by: Ján Tomko +https://bugzilla.redhat.com/show_bug.cgi?id=1805742 +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +Reviewed-by: Michal Privoznik +(cherry picked from commit 02f909b8a6ad8c271693fed9ceab606f0dda2294) + +https://bugzilla.redhat.com/show_bug.cgi?id=1814923 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Peter Krempa +(cherry picked from commit 256e01e59e922ff70dce56284e53e3463d4dc072) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1804672 + +Signed-off-by: Michal Privoznik +Message-Id: <8b12c9adde3c8553b4a2b588ac1a657d0638336b.1582626185.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +Reviewed-by: Michal Privoznik +(cherry picked from commit 299796328c34a30295d6cdc7ebce5d65843e921f) +Message-Id: <2e350bb771f75d9fd068f69a595401907d92ca33.1584696274.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Daniel P. Berrangé +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(cherry picked from commit 84df98f29e031d3b1e68e7e3c0d2651ccba14106) + +https://bugzilla.redhat.com/show_bug.cgi?id=1798148 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Eric Blake +(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 +--- + 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 +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 +Reviewed-by: Eric Blake +(cherry picked from commit e3960f4b6d0b6d8cb8b2631f8358abf289c1cc18) + +https://bugzilla.redhat.com/show_bug.cgi?id=1798148 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 7e13ff8dc016dda5ffd50ff5c059f01c76486c82) + +https://bugzilla.redhat.com/show_bug.cgi?id=1791788 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit b9166baebe70a4b3577ddb6b2ee6af0dd4f60759) +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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 @@ + + + +- [!#$%&'()*+\-./0-9:>=<?@A-Z\^_`\[\]a-z|~]+ ++ "?[!#$%&'()*+\-./0-9:>=<?@A-Z\^_`\[\]a-z|~]+"? + + + +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 @@ + + + testcookievalue +- blurb ++ "blurb" + + + +@@ -47,7 +47,7 @@ + + + testcookievalue +- blurb ++ "blurb" + + + +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 @@ + + + testcookievalue +- blurb ++ "blurb" + + + +@@ -51,7 +51,7 @@ + + + testcookievalue +- blurb ++ "blurb" + + + +-- +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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 264b79c63a518df8ce32a78dda51ae554cd2d5f2) + +https://bugzilla.redhat.com/show_bug.cgi?id=1798148 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit aadb34be3428a5e467289709290b536ae6bf5d2a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1791788 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit fd70f1b4d324361bb9a708762631690aca043178) + +https://bugzilla.redhat.com/show_bug.cgi?id=1791788 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 +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 +Reviewed-by: Ján Tomko +(cherry picked from commit e8a819e87f806e6c6690614c40dbeab0bd2e800e) +Message-Id: <88f7d393b22949a8d6afdae44f8215aa06e65329.1582120424.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + 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\"" + "}" + "}", +- "\n", 0); ++ "\n" ++ " \n" ++ " \n" ++ " \n" ++ "\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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(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 +--- + 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) + " \n" + "\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" ++ "}", ++ "\n" ++ " \n" ++ " \n" ++ " \n" ++ " "0c8db85112873a79b7ef74f294cb70ef7f"\n" ++ " \n" ++ " \n" ++ "\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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 544ef82d05a675d9c6f939c67635ed46c094b164) +https://bugzilla.redhat.com/show_bug.cgi?id=1804750 +Message-Id: +Reviewed-by: Jiri Denemark +--- + 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" + "}", +- "\n" ++ "\n" + " \n" + " \n" + " \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" + "}", +- "\n" ++ "\n" + " \n" + " \n" + " \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: +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +(cherry picked from commit 35d1f5bd145163edf4f05c377b488ffa50d527d6) + +https://bugzilla.redhat.com/show_bug.cgi?id=1798148 +Message-Id: +Reviewed-by: Ján Tomko +--- + 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?= +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 +Reviewed-by: Erik Skultety +(cherry picked from commit ebd44715f19a81f16b2e263b262c0099fe94a0b6) + +Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499 + +Signed-off-by: Michal Privoznik +Message-Id: <5bd2b1b3dfb32ca39c8e1d10810385d483d0643a.1584101247.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Erik Skultety +(cherry picked from commit 08de39a9c7a65f17292eeef783d0598c2dfc8260) + +Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499 + +Signed-off-by: Michal Privoznik +Message-Id: <64efa6130de1732be0feeaf4f2e78c0aecaf38c5.1584101247.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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?= +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 +Reviewed-by: Erik Skultety +(cherry picked from commit 662876723cdfb138ca31847fdb3a84bbe3cadea5) + +Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499 + +Signed-off-by: Michal Privoznik +Message-Id: <8d02662ab00fa2c7088912148fb1131f24623d32.1584101247.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + 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, "\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, "\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?= +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("", + ^ +../../tests/virbuftest.c:414:56: note: expanded from macro 'DO_TEST_ESCAPE' + struct testBufAddStrData info = { data, expect }; \ + +Signed-off-by: Ján Tomko +Reviewed-by: Erik Skultety +(cherry picked from commit 46afdc21207d3276f0e100b6e54ca41ee5f12e99) + +Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + 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("\n", "\n \n"); + DO_TEST_ADD_STR("\n \n\n", "\n \n \n \n"); + +-#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", + "\n \n"); + +-#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: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +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 +Reviewed-by: Erik Skultety +(cherry picked from commit b0138d55f72ae64c2bf1abb4ab8cc7eea217ca04) + +Prerequisite for: https://bugzilla.redhat.com/show_bug.cgi?id=1808499 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + 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 &\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, "\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, "\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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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 +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 +Reviewed-by: Ján Tomko +(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 +--- + 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("\n" + " \n" + "\n"); ++ TEST_JSON_FORMAT_NET("\n" ++ " \n" ++ " \n" ++ " \n" ++ " \n" ++ "\n"); + TEST_JSON_FORMAT_NET("\n" + " \n" + "\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) + " \n" + "\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" ++ "}", ++ "\n" ++ " \n" ++ " \n" ++ " \n" ++ " "0c8db85112873a79b7ef74f294cb70ef7f"\n" ++ " \n" ++ " \n" ++ "\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: +From: Pino Toscano +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 +Reviewed-by: Ján Tomko +Tested-by: Richard W.M. Jones +(cherry picked from commit c5ee737bc5c0fc61451e45ff41526270bdf0113c) +Signed-off-by: Pino Toscano +Message-Id: <20200320122539.141785-3-ptoscano@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 @@ ++ ++ 00000000-0000-0000-0000-000000000000 ++ 32768 ++ 32768 ++ 1 ++ ++ hvm ++ ++ ++ destroy ++ restart ++ destroy ++ ++ ++ ++
    ++ ++ ++ ++ ++ +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: +From: Pino Toscano +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 +Reviewed-by: Ján Tomko +Tested-by: Richard W.M. Jones +https://bugzilla.redhat.com/show_bug.cgi?id=1808610 +(cherry picked from commit 9a469c0d358bf3fd4b4e55b20360620d6fda44b5) +Signed-off-by: Pino Toscano +Message-Id: <20200320122539.141785-2-ptoscano@redhat.com> +Reviewed-by: Ján Tomko +--- + 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 ' -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 "//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,,\n $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 - 6.0.0 +- Resolves: bz#1810193 + (Upgrade components in virt:rhel module:stream for RHEL-8.3 release) + +* Mon Mar 16 2020 Jiri Denemark - 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 - 4.5.0-41 +- qemu: Translate features in virQEMUCapsGetCPUFeatures (rhbz#1804224) + +* Mon Feb 17 2020 Jiri Denemark - 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 - 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 - 4.5.0-38 +- cpu_map/x86: Add support for BFLOAT16 data type (rhbz#1749516) + +* Fri Dec 13 2019 Jiri Denemark - 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 - 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 - 4.5.0-35 +- vircgroupv2: fix setting cpu.max period (rhbz#1749227) + +* Wed Sep 4 2019 Jiri Denemark - 4.5.0-34 +- vircgroupv2: fix abort in VIR_AUTOFREE (rhbz#1747440) + +* Mon Aug 26 2019 Jiri Denemark - 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 - 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 - 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 - 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 - 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 within 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 - 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 - 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 - 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 - 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 - 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 - 4.5.0-23 +- network: explicitly allow icmp/icmpv6 in libvirt zonefile (rhbz#1650320) + +* Fri Feb 15 2019 Jiri Denemark - 4.5.0-22 +- util: fix memory leak in virFirewallDInterfaceSetZone() (rhbz#1650320) + +* Fri Feb 8 2019 Jiri Denemark - 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 - 4.5.0-20 +- RHEL: qemu: Fix crash trying to use iSCSI hostdev (rhbz#1669424) + +* Thu Jan 24 2019 Jiri Denemark - 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 - 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 - 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 - 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 - 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 - 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 - 4.5.0-13 +- Revert "spec: Temporarily drop gluster support" (rhbz#1599339) + +* Wed Oct 17 2018 Jiri Denemark - 4.5.0-12 +- RHEL: Require firewalld-filesystem for firewalld rpm macros (rhbz#1639932) + +* Tue Oct 16 2018 Jiri Denemark - 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 - 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 - 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 - 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 - 4.5.0-7 +- qemu_migration: Avoid writing to freed memory (rhbz#1615854) + +* Thu Aug 2 2018 Jiri Denemark - 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 - 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 - 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 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 - 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 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 - 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 - 4.5.0-1 +- Rebased to libvirt-4.5.0 + +* Fri May 25 2018 Jiri Denemark - 4.3.0-1 +- Rebased to libvirt-4.3.0 + +* Wed Mar 21 2018 Daniel P. Berrangé - 4.1.0-2 +- Fix systemd macro argument with line continuations (rhbz#1558648) + +* Mon Mar 5 2018 Daniel Berrange - 4.1.0-1 +- Rebase to version 4.1.0 + +* Wed Feb 07 2018 Fedora Release Engineering - 4.0.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Fri Jan 19 2018 Daniel P. Berrange - 4.0.0-1 +- Rebase to version 4.0.0 + +* Wed Dec 20 2017 Cole Robinson - 3.10.0-2 +- Rebuild for xen 4.10 + +* Tue Dec 5 2017 Daniel P. Berrange - 3.10.0-1 +- Rebase to version 3.10.0 + +* Fri Nov 3 2017 Daniel P. Berrange - 3.9.0-1 +- Rebase to version 3.9.0 + +* Wed Oct 4 2017 Daniel P. Berrange - 3.8.0-1 +- Rebase to version 3.8.0 + +* Mon Sep 4 2017 Daniel P. Berrange - 3.7.0-1 +- Rebase to version 3.7.0 + +* Wed Aug 2 2017 Daniel P. Berrange - 3.6.0-1 +- Rebase to version 3.6.0 + +* Sun Jul 30 2017 Florian Weimer - 3.5.0-4 +- Rebuild with binutils fix for ppc64le (#1475636) + +* Tue Jul 25 2017 Daniel P. Berrange - 3.5.0-3 +- Disabled RBD on i386, arm, ppc64 (rhbz #1474743) + +* Mon Jul 17 2017 Cole Robinson - 3.5.0-2 +- Rebuild for xen 4.9 + +* Thu Jul 6 2017 Daniel P. Berrange - 3.5.0-1 +- Rebase to version 3.5.0 + +* Fri Jun 2 2017 Daniel P. Berrange - 3.4.0-1 +- Rebase to version 3.4.0 + +* Mon May 8 2017 Daniel P. Berrange - 3.3.0-1 +- Rebase to version 3.3.0 + +* Mon Apr 3 2017 Daniel P. Berrange - 3.2.0-1 +- Rebase to version 3.2.0 + +* Fri Mar 3 2017 Daniel P. Berrange - 3.1.0-1 +- Rebase to version 3.1.0 + +* Fri Feb 10 2017 Fedora Release Engineering - 3.0.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 19 2017 Daniel P. Berrange - 3.0.0-1 +- Rebase to version 3.0.0