commit abe0c881011c86b0c20a26043f73165a1fcd9c9c Author: CentOS Sources Date: Tue Aug 6 14:16:05 2019 -0400 import libvirt-4.5.0-24.module+el8.1.0+3205+41ff0a42 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..95d8dbd --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libvirt-4.5.0.tar.xz diff --git a/.libvirt.metadata b/.libvirt.metadata new file mode 100644 index 0000000..3fedbbb --- /dev/null +++ b/.libvirt.metadata @@ -0,0 +1 @@ +5f097d246c0fba04d18ac7ec951ad56ffa1a8958 SOURCES/libvirt-4.5.0.tar.xz diff --git a/SOURCES/libvirt-PPC64-support-for-NVIDIA-V100-GPU-with-NVLink2-passthrough.patch b/SOURCES/libvirt-PPC64-support-for-NVIDIA-V100-GPU-with-NVLink2-passthrough.patch new file mode 100644 index 0000000..d29a9cf --- /dev/null +++ b/SOURCES/libvirt-PPC64-support-for-NVIDIA-V100-GPU-with-NVLink2-passthrough.patch @@ -0,0 +1,183 @@ +From 5347b12008842b5c86f766e391c6f3756afbff7d Mon Sep 17 00:00:00 2001 +Message-Id: <5347b12008842b5c86f766e391c6f3756afbff7d@dist-git> +From: Daniel Henrique Barboza +Date: Fri, 3 May 2019 13:54:53 +0200 +Subject: [PATCH] PPC64 support for NVIDIA V100 GPU with NVLink2 passthrough + +The NVIDIA V100 GPU has an onboard RAM that is mapped into the +host memory and accessible as normal RAM via an NVLink2 bridge. When +passed through in a guest, QEMU puts the NVIDIA RAM window in a +non-contiguous area, above the PCI MMIO area that starts at 32TiB. +This means that the NVIDIA RAM window starts at 64TiB and go all the +way to 128TiB. + +This means that the guest might request a 64-bit window, for each PCI +Host Bridge, that goes all the way to 128TiB. However, the NVIDIA RAM +window isn't counted as regular RAM, thus this window is considered +only for the allocation of the Translation and Control Entry (TCE). +For more information about how NVLink2 support works in QEMU, +refer to the accepted implementation [1]. + +This memory layout differs from the existing VFIO case, requiring its +own formula. This patch changes the PPC64 code of +@qemuDomainGetMemLockLimitBytes to: + +- detect if we have a NVLink2 bridge being passed through to the +guest. This is done by using the @ppc64VFIODeviceIsNV2Bridge function +added in the previous patch. The existence of the NVLink2 bridge in +the guest means that we are dealing with the NVLink2 memory layout; + +- if an IBM NVLink2 bridge exists, passthroughLimit is calculated in a +different way to account for the extra memory the TCE table can alloc. +The 64TiB..128TiB window is more than enough to fit all possible +GPUs, thus the memLimit is the same regardless of passing through 1 or +multiple V100 GPUs. + +Further reading explaining the background +[1] https://lists.gnu.org/archive/html/qemu-devel/2019-03/msg03700.html +[2] https://www.redhat.com/archives/libvir-list/2019-March/msg00660.html +[3] https://www.redhat.com/archives/libvir-list/2019-April/msg00527.html + +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Erik Skultety +(cherry picked from commit 1a922648f67f56c4374d647feebf2adb9a642f96) + +https://bugzilla.redhat.com/show_bug.cgi?id=1505998 + +Conflicts: + The upstream commit relied on: + - v4.7.0-37-gb72183223f + - v4.7.0-38-ga14f597266 + which were not backported so virPCIDeviceAddressAsString had to + swapped for the former virDomainPCIAddressAsString in order to + compile. + +Signed-off-by: Erik Skultety +Message-Id: <03c00ebf46d85b0615134ef8655e67a4c909b7da.1556884443.git.eskultet@redhat.com> +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_domain.c | 80 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 61 insertions(+), 19 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index a8bc618389..21f0722495 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9813,7 +9813,7 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, + * such as '0004:04:00.0', and tells if the device is a NVLink2 + * bridge. + */ +-static ATTRIBUTE_UNUSED bool ++static bool + ppc64VFIODeviceIsNV2Bridge(const char *device) + { + const char *nvlink2Files[] = {"ibm,gpu", "ibm,nvlink", +@@ -9851,7 +9851,9 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def) + unsigned long long maxMemory = 0; + unsigned long long passthroughLimit = 0; + size_t i, nPCIHostBridges = 0; ++ virPCIDeviceAddressPtr pciAddr; + bool usesVFIO = false; ++ bool nvlink2Capable = false; + + for (i = 0; i < def->ncontrollers; i++) { + virDomainControllerDefPtr cont = def->controllers[i]; +@@ -9869,7 +9871,17 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def) + dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && + dev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + usesVFIO = true; +- break; ++ ++ pciAddr = &dev->source.subsys.u.pci.addr; ++ if (virPCIDeviceAddressIsValid(pciAddr, false)) { ++ VIR_AUTOFREE(char *) pciAddrStr = NULL; ++ ++ pciAddrStr = virDomainPCIAddressAsString(pciAddr); ++ if (ppc64VFIODeviceIsNV2Bridge(pciAddrStr)) { ++ nvlink2Capable = true; ++ break; ++ } ++ } + } + } + +@@ -9896,29 +9908,59 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def) + 4096 * nPCIHostBridges + + 8192; + +- /* passthroughLimit := max( 2 GiB * #PHBs, (c) +- * memory (d) +- * + memory * 1/512 * #PHBs + 8 MiB ) (e) ++ /* NVLink2 support in QEMU is a special case of the passthrough ++ * mechanics explained in the usesVFIO case below. The GPU RAM ++ * is placed with a gap after maxMemory. The current QEMU ++ * implementation puts the NVIDIA RAM above the PCI MMIO, which ++ * starts at 32TiB and is the MMIO reserved for the guest main RAM. + * +- * (c) is the pre-DDW VFIO DMA window accounting. We're allowing 2 GiB +- * rather than 1 GiB ++ * This window ends at 64TiB, and this is where the GPUs are being ++ * placed. The next available window size is at 128TiB, and ++ * 64TiB..128TiB will fit all possible NVIDIA GPUs. + * +- * (d) is the with-DDW (and memory pre-registration and related +- * features) DMA window accounting - assuming that we only account RAM +- * once, even if mapped to multiple PHBs ++ * The same assumption as the most common case applies here: ++ * the guest will request a 64-bit DMA window, per PHB, that is ++ * big enough to map all its RAM, which is now at 128TiB due ++ * to the GPUs. + * +- * (e) is the with-DDW userspace view and overhead for the 64-bit DMA +- * window. This is based a bit on expected guest behaviour, but there +- * really isn't a way to completely avoid that. We assume the guest +- * requests a 64-bit DMA window (per PHB) just big enough to map all +- * its RAM. 4 kiB page size gives the 1/512; it will be less with 64 +- * kiB pages, less still if the guest is mapped with hugepages (unlike +- * the default 32-bit DMA window, DDW windows can use large IOMMU +- * pages). 8 MiB is for second and further level overheads, like (b) */ +- if (usesVFIO) ++ * Note that the NVIDIA RAM window must be accounted for the TCE ++ * table size, but *not* for the main RAM (maxMemory). This gives ++ * us the following passthroughLimit for the NVLink2 case: ++ * ++ * passthroughLimit = maxMemory + ++ * 128TiB/512KiB * #PHBs + 8 MiB */ ++ if (nvlink2Capable) { ++ passthroughLimit = maxMemory + ++ 128 * (1ULL<<30) / 512 * nPCIHostBridges + ++ 8192; ++ } else if (usesVFIO) { ++ /* For regular (non-NVLink2 present) VFIO passthrough, the value ++ * of passthroughLimit is: ++ * ++ * passthroughLimit := max( 2 GiB * #PHBs, (c) ++ * memory (d) ++ * + memory * 1/512 * #PHBs + 8 MiB ) (e) ++ * ++ * (c) is the pre-DDW VFIO DMA window accounting. We're allowing 2 ++ * GiB rather than 1 GiB ++ * ++ * (d) is the with-DDW (and memory pre-registration and related ++ * features) DMA window accounting - assuming that we only account ++ * RAM once, even if mapped to multiple PHBs ++ * ++ * (e) is the with-DDW userspace view and overhead for the 64-bit ++ * DMA window. This is based a bit on expected guest behaviour, but ++ * there really isn't a way to completely avoid that. We assume the ++ * guest requests a 64-bit DMA window (per PHB) just big enough to ++ * map all its RAM. 4 kiB page size gives the 1/512; it will be ++ * less with 64 kiB pages, less still if the guest is mapped with ++ * hugepages (unlike the default 32-bit DMA window, DDW windows ++ * can use large IOMMU pages). 8 MiB is for second and further level ++ * overheads, like (b) */ + passthroughLimit = MAX(2 * 1024 * 1024 * nPCIHostBridges, + memory + + memory / 512 * nPCIHostBridges + 8192); ++ } + + memKB = baseLimit + passthroughLimit; + +-- +2.21.0 + 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..a32bf30 --- /dev/null +++ b/SOURCES/libvirt-RHEL-Add-rhel-machine-types-to-qemuDomainMachineNeedsFDC.patch @@ -0,0 +1,35 @@ +From 74b69d4a7240c601fcd12c18d5e8d95d641ae922 Mon Sep 17 00:00:00 2001 +Message-Id: <74b69d4a7240c601fcd12c18d5e8d95d641ae922@dist-git> +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 | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 4c15d5a36a..4c2a162b85 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9239,6 +9239,9 @@ qemuDomainMachineNeedsFDC(const char *machine) + STRPREFIX(p, "2.2") || + STRPREFIX(p, "2.3")) + return false; ++ if (STRPREFIX(p, "rhel7.0.0") || ++ STRPREFIX(p, "rhel7.1.0")) ++ return false; + return true; + } + return false; +-- +2.18.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..449b106 --- /dev/null +++ b/SOURCES/libvirt-RHEL-Fix-virConnectGetMaxVcpus-output.patch @@ -0,0 +1,46 @@ +From 72c5455c00fcec50bae3e71a6fbd6330e524be0a Mon Sep 17 00:00:00 2001 +Message-Id: <72c5455c00fcec50bae3e71a6fbd6330e524be0a@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 1e31be5900..effe04ca3a 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -1186,6 +1186,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.18.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..69fece3 --- /dev/null +++ b/SOURCES/libvirt-RHEL-Hack-around-changed-Broadwell-Haswell-CPUs.patch @@ -0,0 +1,165 @@ +From 498389f6b88547c352add4b209d61896a5143c00 Mon Sep 17 00:00:00 2001 +Message-Id: <498389f6b88547c352add4b209d61896a5143c00@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 | 29 +++++++++++++++++++ + tests/qemuxml2argvdata/cpu-Haswell.args | 2 +- + .../qemuxml2argvdata/cpu-host-model-cmt.args | 3 +- + tests/qemuxml2argvdata/cpu-tsc-frequency.args | 2 +- + tests/qemuxml2argvdata/q35-acpi-nouefi.args | 2 +- + tests/qemuxml2argvdata/q35-acpi-uefi.args | 2 +- + tests/qemuxml2argvdata/q35-noacpi-nouefi.args | 2 +- + 7 files changed, 36 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 4fc3176ad3..c1eefca639 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6677,6 +6677,8 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver, + size_t i; + virCapsPtr caps = NULL; + virCPUDefPtr cpu = def->cpu; ++ bool hle = false; ++ bool rtm = false; + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; +@@ -6734,6 +6736,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: +@@ -6757,6 +6764,28 @@ 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) { ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) ++ virBufferAddLit(buf, ",rtm=on"); ++ else ++ virBufferAddLit(buf, ",+rtm"); ++ } ++ if (!hle) { ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) ++ virBufferAddLit(buf, ",hle=on"); ++ else ++ virBufferAddLit(buf, ",+hle"); ++ } ++ } ++ + ret = 0; + cleanup: + virObjectUnref(caps); +diff --git a/tests/qemuxml2argvdata/cpu-Haswell.args b/tests/qemuxml2argvdata/cpu-Haswell.args +index c7ce396d05..6f20359524 100644 +--- a/tests/qemuxml2argvdata/cpu-Haswell.args ++++ b/tests/qemuxml2argvdata/cpu-Haswell.args +@@ -8,7 +8,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 \ + -smp 6,sockets=6,cores=1,threads=1 \ + -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +diff --git a/tests/qemuxml2argvdata/cpu-host-model-cmt.args b/tests/qemuxml2argvdata/cpu-host-model-cmt.args +index 8767278d11..d236aa9e09 100644 +--- a/tests/qemuxml2argvdata/cpu-host-model-cmt.args ++++ b/tests/qemuxml2argvdata/cpu-host-model-cmt.args +@@ -9,7 +9,8 @@ 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,+osxsave,+f16c,+rdrand,+pdpe1gb,+abm,+lahf_lm \ +++smx,+est,+tm2,+xtpr,+pdcm,+osxsave,+f16c,+rdrand,+pdpe1gb,+abm,+lahf_lm,+rtm,\ +++hle \ + -m 214 \ + -smp 6,sockets=6,cores=1,threads=1 \ + -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +diff --git a/tests/qemuxml2argvdata/cpu-tsc-frequency.args b/tests/qemuxml2argvdata/cpu-tsc-frequency.args +index 7824dea96f..216fd43014 100644 +--- a/tests/qemuxml2argvdata/cpu-tsc-frequency.args ++++ b/tests/qemuxml2argvdata/cpu-tsc-frequency.args +@@ -10,7 +10,7 @@ QEMU_AUDIO_DRV=none \ + -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,+osxsave,+f16c,+rdrand,+pdpe1gb,+abm,+lahf_lm,\ +-+invtsc,tsc-frequency=3504000000 \ +++invtsc,+rtm,+hle,tsc-frequency=3504000000 \ + -m 214 \ + -smp 1,sockets=1,cores=1,threads=1 \ + -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +diff --git a/tests/qemuxml2argvdata/q35-acpi-nouefi.args b/tests/qemuxml2argvdata/q35-acpi-nouefi.args +index caef49ea16..a9375a35db 100644 +--- a/tests/qemuxml2argvdata/q35-acpi-nouefi.args ++++ b/tests/qemuxml2argvdata/q35-acpi-nouefi.args +@@ -8,7 +8,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 \ + -smp 1,sockets=1,cores=1,threads=1 \ + -uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +diff --git a/tests/qemuxml2argvdata/q35-acpi-uefi.args b/tests/qemuxml2argvdata/q35-acpi-uefi.args +index a3293aeb9d..8e3368b9e9 100644 +--- a/tests/qemuxml2argvdata/q35-acpi-uefi.args ++++ b/tests/qemuxml2argvdata/q35-acpi-uefi.args +@@ -8,7 +8,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 fab2a6fcb0..0dd61840ef 100644 +--- a/tests/qemuxml2argvdata/q35-noacpi-nouefi.args ++++ b/tests/qemuxml2argvdata/q35-noacpi-nouefi.args +@@ -8,7 +8,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 \ + -smp 1,sockets=1,cores=1,threads=1 \ + -uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \ +-- +2.18.0 + diff --git a/SOURCES/libvirt-RHEL-network-regain-guest-network-connectivity-after-firewalld-switch-to-nftables.patch b/SOURCES/libvirt-RHEL-network-regain-guest-network-connectivity-after-firewalld-switch-to-nftables.patch new file mode 100644 index 0000000..081d0e9 --- /dev/null +++ b/SOURCES/libvirt-RHEL-network-regain-guest-network-connectivity-after-firewalld-switch-to-nftables.patch @@ -0,0 +1,146 @@ +From 54e270d7fb68b41002654374d395e4f260a24add Mon Sep 17 00:00:00 2001 +Message-Id: <54e270d7fb68b41002654374d395e4f260a24add@dist-git> +From: Laine Stump +Date: Mon, 15 Oct 2018 20:31:02 -0400 +Subject: [PATCH] RHEL: network: regain guest network connectivity after + firewalld switch to nftables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is a DOWNSTREAM ONLY patch to temporarily get back guest network +connectivity while still allowing the firewalld backend to use +nftables (which is the default with RHEL8). + +The circumstances that cause the problem: + +In the past (when both libvirt and firewalld used iptables), if either +libvirt's rules *OR* firewalld's rules accepted a packet, it would be +accepted. + +But now firewalld uses nftables for its backend, while libvirt's +firewall rules are still using iptables; iptables rules are still +processed, but at a different time during packet processing than the +firewalld nftables hooks. The result is that a packet must be accepted +by *BOTH* the libvirt iptables rules *AND* the firewalld nftable rules +in order to be accepted. + +This causes pain for two types of traffic: + +1) libvirt always adds rules to permit DNS and DHCP (and sometimes +TFTP) from guests to the host. But libvirt's bridges are in +firewalld's "default" zone (which is usually the zone called +"public"). The public zone allows ssh, but doesn't allow DNS, DHCP, or +TFTP. So guests connected to libvirt's bridges can't acquire an IP +address from DHCP, nor can they make DNS queries to the DNS server +libvirt has setup on the host. + +2) firewalld's higher level "rich rules" don't yet have the ability to +configure the acceptance of forwarded traffic (traffic that is going +somewhere beyond the host), so any traffic that needs to be forwarded +is rejected. + +libvirt can't send "direct" nftables rules (firewalld only supports +that for iptables), so we can't solve this problem by just sending +direct nftables rules instead of iptables rules. + +However, we can take advantage of a quirk in firewalld zones that have +a default policy of accept (meaning any packet that doesn't match a +specific rule in the zone will be accepted) - this default accept will +also accept forwarded traffic (not just traffic destined for the host). + +So, as a temporary solution to get all network traffic flowing, this +patch creates a new firewalld zone called "libvirt" which is setup to +include interfaces named virbr0-virbr9, and has a default policy of +accept. With this zone installed, libvirt networks that use the names +virbr0-virbr9 will have *all* their traffic accepted, both to the host +and to/from the rest of the network. + +firewalld zones can't normally be added to the runtime config of +firewalld, so we have to reload all of the permanent config for it to +be recognized. This is done with a call to "firewall-cmd --reload" +during postinstall and postuninstall. In the case that firewalld is +inactive, firewall-cmd exits without doing anything (i.e. it doesn't +start up firewalld.service if it's not already started). + +This obviously can't be a permanent solution, since it allows guests +to have access to *all* services on the host. However, it doesn't +allow QE and beta testers to test firewalld with an nftables backend +(which is important for firewalld and nftables devs) without breaking +network connectivity for libvirt managed virtual machines (so testing +of those can also take place. + +Resolves: https://bugzilla.redhat.com/1638864 + +This problem is discussed in more detail in this message thread: + +https://post-office.corp.redhat.com/mailman/private/virt-devel/2018-September/msg00145.html +https://post-office.corp.redhat.com/mailman/private/virt-devel/2018-October/msg00042.html + +and in the BZ assigned to firewalld: https://bugzilla.redhat.com/1623841 + +Signed-off-by: Laine Stump +Acked-by: Daniel P. Berrangé +Reviewed-by: Jiri Denemark +--- + libvirt.spec.in | 14 ++++++++++++++ + src/network/Makefile.inc.am | 10 +++++++++- + src/network/libvirt.zone | 15 +++++++++++++++ + 3 files changed, 38 insertions(+), 1 deletion(-) + create mode 100644 src/network/libvirt.zone + +diff --git a/src/network/Makefile.inc.am b/src/network/Makefile.inc.am +index 508c8c0422..20d899e699 100644 +--- a/src/network/Makefile.inc.am ++++ b/src/network/Makefile.inc.am +@@ -87,6 +87,11 @@ install-data-network: + ( cd $(DESTDIR)$(confdir)/qemu/networks/autostart && \ + rm -f default.xml && \ + $(LN_S) ../default.xml default.xml ) ++if HAVE_FIREWALLD ++ $(MKDIR_P) "$(DESTDIR)$(prefix)/lib/firewalld/zones" ++ $(INSTALL_DATA) $(srcdir)/network/libvirt.zone \ ++ $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml ++endif HAVE_FIREWALLD + + uninstall-data-network: + rm -f $(DESTDIR)$(confdir)/qemu/networks/autostart/default.xml +@@ -95,10 +100,13 @@ uninstall-data-network: + rmdir "$(DESTDIR)$(confdir)/qemu/networks" || : + rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/network" ||: + rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/network" ||: ++if HAVE_FIREWALLD ++ rm -f $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml ++endif HAVE_FIREWALLD + + endif WITH_NETWORK + +-EXTRA_DIST += network/default.xml ++EXTRA_DIST += network/default.xml network/libvirt.zone + + .PHONY: \ + install-data-network \ +diff --git a/src/network/libvirt.zone b/src/network/libvirt.zone +new file mode 100644 +index 0000000000..355a70b4da +--- /dev/null ++++ b/src/network/libvirt.zone +@@ -0,0 +1,15 @@ ++ ++ ++ libvirt ++ All network connections are accepted. This also permits packets to/from interfaces in the zone to be forwarded. This zone is intended to be used only by libvirt virtual networks. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.19.1 + 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..537e868 --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Add-ability-to-set-sgio-values-for-hostdev.patch @@ -0,0 +1,77 @@ +From 2d4b19613c462e876ee1327d600f5cbbb998c540 Mon Sep 17 00:00:00 2001 +Message-Id: <2d4b19613c462e876ee1327d600f5cbbb998c540@dist-git> +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 | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index a4f545ef92..3ea9784854 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -1633,6 +1633,7 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) + virDomainDiskDefPtr disk = NULL; + virDomainHostdevDefPtr hostdev = NULL; + char *sysfs_path = NULL; ++ char *hostdev_path = NULL; + const char *path = NULL; + int val = -1; + int ret = -1; +@@ -1654,14 +1655,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))) + goto cleanup; +- } + +- return 0; ++ path = hostdev_path; + } else { + return 0; + } +@@ -1670,7 +1667,11 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) + goto cleanup; + + /* 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 +@@ -1683,6 +1684,7 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) + ret = 0; + + cleanup: ++ VIR_FREE(hostdev_path); + VIR_FREE(sysfs_path); + return ret; + } +-- +2.20.1 + 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..61a15f5 --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Add-check-for-unpriv-sgio-for-SCSI-generic-host-device.patch @@ -0,0 +1,64 @@ +From c39257f41ccb22272c6161777bf71390676bf7f0 Mon Sep 17 00:00:00 2001 +Message-Id: +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 | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index 3ea9784854..7d15af9c0b 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -1473,6 +1473,8 @@ qemuAddSharedHostdev(virQEMUDriverPtr driver, + { + char *dev_path = NULL; + char *key = NULL; ++ virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi; ++ virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host; + int ret = -1; + + if (!qemuIsSharedHostdev(hostdev)) +@@ -1481,6 +1483,19 @@ qemuAddSharedHostdev(virQEMUDriverPtr driver, + if (!(dev_path = qemuGetHostdevPath(hostdev))) + goto cleanup; + ++ 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); ++ ret = -1; ++ } ++ goto cleanup; ++ } ++ + if (!(key = qemuGetSharedDeviceKey(dev_path))) + goto cleanup; + +-- +2.20.1 + 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..c86c563 --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Fix-crash-trying-to-use-iSCSI-hostdev.patch @@ -0,0 +1,45 @@ +From 11bfd4f26c090b95a100aaf056ecfa799dfce979 Mon Sep 17 00:00:00 2001 +Message-Id: <11bfd4f26c090b95a100aaf056ecfa799dfce979@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 768e9d8308..a81298326f 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -1667,6 +1667,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))) + goto cleanup; + +-- +2.20.1 + diff --git a/SOURCES/libvirt-Revert-RHEL-network-regain-guest-network-connectivity-after-firewalld-switch-to-nftables.patch b/SOURCES/libvirt-Revert-RHEL-network-regain-guest-network-connectivity-after-firewalld-switch-to-nftables.patch new file mode 100644 index 0000000..600d63a --- /dev/null +++ b/SOURCES/libvirt-Revert-RHEL-network-regain-guest-network-connectivity-after-firewalld-switch-to-nftables.patch @@ -0,0 +1,84 @@ +From 195908ad66fc52643d94eca0f45e5740f25e3e78 Mon Sep 17 00:00:00 2001 +Message-Id: <195908ad66fc52643d94eca0f45e5740f25e3e78@dist-git> +From: Laine Stump +Date: Fri, 1 Feb 2019 20:29:26 -0500 +Subject: [PATCH] Revert "RHEL: network: regain guest network connectivity + after firewalld switch to nftables" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit 54e270d7fb68b41002654374d395e4f260a24add. + +This patch appeared in libvirt-4.5.0-11.el8 (RHEL git commit id +2fb53957). It was a downstream-only temporary fix to the networking +issues resulting from firewalld's switch to using nftables. Now that +there is a permanent fix upstream we can revert this patch and use the +upstream patches instead. + +https://bugzilla.redhat.com/1650320 + +Signed-off-by: Laine Stump +Reviewed-by: Ján Tomko +--- + libvirt.spec.in | 14 -------------- + src/network/Makefile.inc.am | 10 +--------- + src/network/libvirt.zone | 15 --------------- + 3 files changed, 1 insertion(+), 38 deletions(-) + delete mode 100644 src/network/libvirt.zone + +diff --git a/src/network/Makefile.inc.am b/src/network/Makefile.inc.am +index 20d899e699..508c8c0422 100644 +--- a/src/network/Makefile.inc.am ++++ b/src/network/Makefile.inc.am +@@ -87,11 +87,6 @@ install-data-network: + ( cd $(DESTDIR)$(confdir)/qemu/networks/autostart && \ + rm -f default.xml && \ + $(LN_S) ../default.xml default.xml ) +-if HAVE_FIREWALLD +- $(MKDIR_P) "$(DESTDIR)$(prefix)/lib/firewalld/zones" +- $(INSTALL_DATA) $(srcdir)/network/libvirt.zone \ +- $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml +-endif HAVE_FIREWALLD + + uninstall-data-network: + rm -f $(DESTDIR)$(confdir)/qemu/networks/autostart/default.xml +@@ -100,13 +95,10 @@ uninstall-data-network: + rmdir "$(DESTDIR)$(confdir)/qemu/networks" || : + rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/network" ||: + rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/network" ||: +-if HAVE_FIREWALLD +- rm -f $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml +-endif HAVE_FIREWALLD + + endif WITH_NETWORK + +-EXTRA_DIST += network/default.xml network/libvirt.zone ++EXTRA_DIST += network/default.xml + + .PHONY: \ + install-data-network \ +diff --git a/src/network/libvirt.zone b/src/network/libvirt.zone +deleted file mode 100644 +index 355a70b4da..0000000000 +--- a/src/network/libvirt.zone ++++ /dev/null +@@ -1,15 +0,0 @@ +- +- +- libvirt +- All network connections are accepted. This also permits packets to/from interfaces in the zone to be forwarded. This zone is intended to be used only by libvirt virtual networks. +- +- +- +- +- +- +- +- +- +- +- +-- +2.20.1 + diff --git a/SOURCES/libvirt-Revert-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName.patch b/SOURCES/libvirt-Revert-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName.patch new file mode 100644 index 0000000..546facb --- /dev/null +++ b/SOURCES/libvirt-Revert-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName.patch @@ -0,0 +1,163 @@ +From 6af885a53e425b88c7d9c123f64bbc4f8517b8a8 Mon Sep 17 00:00:00 2001 +Message-Id: <6af885a53e425b88c7d9c123f64bbc4f8517b8a8@dist-git> +From: John Ferlan +Date: Thu, 15 Nov 2018 06:43:58 -0500 +Subject: [PATCH] Revert "access: Modify the VIR_ERR_ACCESS_DENIED to include + driverName" + +https://bugzilla.redhat.com/show_bug.cgi?id=1631608 (RHEL8) +https://bugzilla.redhat.com/show_bug.cgi?id=1631606 (RHEL7) + +This reverts commit ccc72d5cbdd85f66cb737134b3be40aac1df03ef. + +Based on upstream comment to a follow-up patch, this didn't take the +right approach and the right thing to do is revert and rework. + +Signed-off-by: John Ferlan +(cherry picked from commit b08396a5feab02fb3bb595603c888ee733aa178e) +Reviewed-by: Erik Skultety +--- + src/access/viraccessmanager.c | 25 ++++++++++++------------- + src/rpc/gendispatch.pl | 2 +- + src/util/virerror.c | 4 ++-- + 3 files changed, 15 insertions(+), 16 deletions(-) + +diff --git a/src/access/viraccessmanager.c b/src/access/viraccessmanager.c +index 1dfff32b9d..e7b5bf38da 100644 +--- a/src/access/viraccessmanager.c ++++ b/src/access/viraccessmanager.c +@@ -196,12 +196,11 @@ static void virAccessManagerDispose(void *object) + * should the admin need to debug things + */ + static int +-virAccessManagerSanitizeError(int ret, +- const char *driverName) ++virAccessManagerSanitizeError(int ret) + { + if (ret < 0) { + virResetLastError(); +- virAccessError(VIR_ERR_ACCESS_DENIED, driverName, NULL); ++ virAccessError(VIR_ERR_ACCESS_DENIED, NULL); + } + + return ret; +@@ -218,7 +217,7 @@ int virAccessManagerCheckConnect(virAccessManagerPtr manager, + if (manager->drv->checkConnect) + ret = manager->drv->checkConnect(manager, driverName, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + +@@ -234,7 +233,7 @@ int virAccessManagerCheckDomain(virAccessManagerPtr manager, + if (manager->drv->checkDomain) + ret = manager->drv->checkDomain(manager, driverName, domain, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckInterface(virAccessManagerPtr manager, +@@ -249,7 +248,7 @@ int virAccessManagerCheckInterface(virAccessManagerPtr manager, + if (manager->drv->checkInterface) + ret = manager->drv->checkInterface(manager, driverName, iface, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckNetwork(virAccessManagerPtr manager, +@@ -264,7 +263,7 @@ int virAccessManagerCheckNetwork(virAccessManagerPtr manager, + if (manager->drv->checkNetwork) + ret = manager->drv->checkNetwork(manager, driverName, network, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, +@@ -279,7 +278,7 @@ int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, + if (manager->drv->checkNodeDevice) + ret = manager->drv->checkNodeDevice(manager, driverName, nodedev, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckNWFilter(virAccessManagerPtr manager, +@@ -294,7 +293,7 @@ int virAccessManagerCheckNWFilter(virAccessManagerPtr manager, + if (manager->drv->checkNWFilter) + ret = manager->drv->checkNWFilter(manager, driverName, nwfilter, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager, +@@ -309,7 +308,7 @@ int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager, + if (manager->drv->checkNWFilterBinding) + ret = manager->drv->checkNWFilterBinding(manager, driverName, binding, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckSecret(virAccessManagerPtr manager, +@@ -324,7 +323,7 @@ int virAccessManagerCheckSecret(virAccessManagerPtr manager, + if (manager->drv->checkSecret) + ret = manager->drv->checkSecret(manager, driverName, secret, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckStoragePool(virAccessManagerPtr manager, +@@ -339,7 +338,7 @@ int virAccessManagerCheckStoragePool(virAccessManagerPtr manager, + if (manager->drv->checkStoragePool) + ret = manager->drv->checkStoragePool(manager, driverName, pool, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } + + int virAccessManagerCheckStorageVol(virAccessManagerPtr manager, +@@ -355,5 +354,5 @@ int virAccessManagerCheckStorageVol(virAccessManagerPtr manager, + if (manager->drv->checkStorageVol) + ret = manager->drv->checkStorageVol(manager, driverName, pool, vol, perm); + +- return virAccessManagerSanitizeError(ret, driverName); ++ return virAccessManagerSanitizeError(ret); + } +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index f599002056..0c4648c0fb 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2199,7 +2199,7 @@ elsif ($mode eq "client") { + print " virObjectUnref(mgr);\n"; + if ($action eq "Ensure") { + print " if (rv == 0)\n"; +- print " virReportError(VIR_ERR_ACCESS_DENIED, conn->driver->name, NULL);\n"; ++ print " virReportError(VIR_ERR_ACCESS_DENIED, NULL);\n"; + print " return $fail;\n"; + } else { + print " virResetLastError();\n"; +diff --git a/src/util/virerror.c b/src/util/virerror.c +index 5f50fa0349..f198f27957 100644 +--- a/src/util/virerror.c ++++ b/src/util/virerror.c +@@ -1439,9 +1439,9 @@ virErrorMsg(virErrorNumber error, const char *info) + break; + case VIR_ERR_ACCESS_DENIED: + if (info == NULL) +- errmsg = _("access denied from '%s'"); ++ errmsg = _("access denied"); + else +- errmsg = _("access denied from '%s': %s"); ++ errmsg = _("access denied: %s"); + break; + case VIR_ERR_DBUS_SERVICE: + if (info == NULL) +-- +2.19.2 + diff --git a/SOURCES/libvirt-access-Fix-nwfilter-binding-ACL-access-API-name-generation.patch b/SOURCES/libvirt-access-Fix-nwfilter-binding-ACL-access-API-name-generation.patch new file mode 100644 index 0000000..4b53a50 --- /dev/null +++ b/SOURCES/libvirt-access-Fix-nwfilter-binding-ACL-access-API-name-generation.patch @@ -0,0 +1,60 @@ +From 254da75ea1a9c2cade909534153f444bb8981c2a Mon Sep 17 00:00:00 2001 +Message-Id: <254da75ea1a9c2cade909534153f444bb8981c2a@dist-git> +From: John Ferlan +Date: Mon, 27 Aug 2018 08:27:47 -0400 +Subject: [PATCH] access: Fix nwfilter-binding ACL access API name generation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1611320 + +Generation of the ACL API policy is a "automated process" +based on this perl script which "worked" with the changes to +add nwfilter binding API's because they had the "nwfilter" +prefix; however, the generated output name was incorrect +based on the remote protocol algorithm which expected to +generate names such as 'nwfilter-binding.action' instead +of 'nwfilter.binding-action'. + +This effectively changes src/access/org.libvirt.api.policy entries: + + org.libvirt.api.nwfilter.binding-create ==> + org.libvirt.api.nwfilter-binding.create + + org.libvirt.api.nwfilter.binding-delete ==> + org.libvirt.api.nwfilter-binding.delete + + org.libvirt.api.nwfilter.binding-getattr ==> + org.libvirt.api.nwfilter-binding.getattr + + org.libvirt.api.nwfilter.binding-read ==> + org.libvirt.api.nwfilter-binding.read + +Signed-off-by: John Ferlan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 6ef65e3c96d5d1f16a16daca83b81b818d461e64) +https: //bugzilla.redhat.com/show_bug.cgi?id=1622540 +Reviewed-by: Erik Skultety +--- + src/access/genpolkit.pl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/access/genpolkit.pl b/src/access/genpolkit.pl +index 968cb8c55c..e074c90eb6 100755 +--- a/src/access/genpolkit.pl ++++ b/src/access/genpolkit.pl +@@ -22,8 +22,8 @@ use warnings; + + my @objects = ( + "CONNECT", "DOMAIN", "INTERFACE", +- "NETWORK","NODE_DEVICE", "NWFILTER", +- "SECRET", "STORAGE_POOL", "STORAGE_VOL", ++ "NETWORK","NODE_DEVICE", "NWFILTER_BINDING", "NWFILTER", ++ "SECRET", "STORAGE_POOL", "STORAGE_VOL", + ); + + my $objects = join ("|", @objects); +-- +2.18.0 + diff --git a/SOURCES/libvirt-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName.patch b/SOURCES/libvirt-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName.patch new file mode 100644 index 0000000..a47583c --- /dev/null +++ b/SOURCES/libvirt-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName.patch @@ -0,0 +1,173 @@ +From 85750b0466aa3719d3d2447abaab2e87db92f552 Mon Sep 17 00:00:00 2001 +Message-Id: <85750b0466aa3719d3d2447abaab2e87db92f552@dist-git> +From: John Ferlan +Date: Mon, 5 Nov 2018 07:48:37 -0500 +Subject: [PATCH] access: Modify the VIR_ERR_ACCESS_DENIED to include + driverName + +https://bugzilla.redhat.com/show_bug.cgi?id=1631608 (RHEL 8.0) +https://bugzilla.redhat.com/show_bug.cgi?id=1631606 (RHEL 7.7) + +Changes made to manage and utilize a secondary connection +driver to APIs outside the scope of the primary connection +driver have resulted in some confusion processing polkit rules +since the simple "access denied" error message doesn't provide +enough of a clue when combined with the "authentication failed: +access denied by policy" as to which connection driver refused +or failed the ACL check. + +In order to provide some context, let's modify the existing +"access denied" error returne from the various vir*EnsureACL +API's to provide the connection driver name that is causing +the failure. This should provide the context for writing the +polkit rules that would allow access via the driver. + +Signed-off-by: John Ferlan +ACKed-by: Michal Privoznik +(cherry picked from commit ccc72d5cbdd85f66cb737134b3be40aac1df03ef) +Reviewed-by: Jiri Denemark +--- + src/access/viraccessmanager.c | 25 +++++++++++++------------ + src/rpc/gendispatch.pl | 2 +- + src/util/virerror.c | 4 ++-- + 3 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/src/access/viraccessmanager.c b/src/access/viraccessmanager.c +index e7b5bf38da..1dfff32b9d 100644 +--- a/src/access/viraccessmanager.c ++++ b/src/access/viraccessmanager.c +@@ -196,11 +196,12 @@ static void virAccessManagerDispose(void *object) + * should the admin need to debug things + */ + static int +-virAccessManagerSanitizeError(int ret) ++virAccessManagerSanitizeError(int ret, ++ const char *driverName) + { + if (ret < 0) { + virResetLastError(); +- virAccessError(VIR_ERR_ACCESS_DENIED, NULL); ++ virAccessError(VIR_ERR_ACCESS_DENIED, driverName, NULL); + } + + return ret; +@@ -217,7 +218,7 @@ int virAccessManagerCheckConnect(virAccessManagerPtr manager, + if (manager->drv->checkConnect) + ret = manager->drv->checkConnect(manager, driverName, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + +@@ -233,7 +234,7 @@ int virAccessManagerCheckDomain(virAccessManagerPtr manager, + if (manager->drv->checkDomain) + ret = manager->drv->checkDomain(manager, driverName, domain, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckInterface(virAccessManagerPtr manager, +@@ -248,7 +249,7 @@ int virAccessManagerCheckInterface(virAccessManagerPtr manager, + if (manager->drv->checkInterface) + ret = manager->drv->checkInterface(manager, driverName, iface, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNetwork(virAccessManagerPtr manager, +@@ -263,7 +264,7 @@ int virAccessManagerCheckNetwork(virAccessManagerPtr manager, + if (manager->drv->checkNetwork) + ret = manager->drv->checkNetwork(manager, driverName, network, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, +@@ -278,7 +279,7 @@ int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, + if (manager->drv->checkNodeDevice) + ret = manager->drv->checkNodeDevice(manager, driverName, nodedev, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNWFilter(virAccessManagerPtr manager, +@@ -293,7 +294,7 @@ int virAccessManagerCheckNWFilter(virAccessManagerPtr manager, + if (manager->drv->checkNWFilter) + ret = manager->drv->checkNWFilter(manager, driverName, nwfilter, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager, +@@ -308,7 +309,7 @@ int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager, + if (manager->drv->checkNWFilterBinding) + ret = manager->drv->checkNWFilterBinding(manager, driverName, binding, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckSecret(virAccessManagerPtr manager, +@@ -323,7 +324,7 @@ int virAccessManagerCheckSecret(virAccessManagerPtr manager, + if (manager->drv->checkSecret) + ret = manager->drv->checkSecret(manager, driverName, secret, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckStoragePool(virAccessManagerPtr manager, +@@ -338,7 +339,7 @@ int virAccessManagerCheckStoragePool(virAccessManagerPtr manager, + if (manager->drv->checkStoragePool) + ret = manager->drv->checkStoragePool(manager, driverName, pool, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckStorageVol(virAccessManagerPtr manager, +@@ -354,5 +355,5 @@ int virAccessManagerCheckStorageVol(virAccessManagerPtr manager, + if (manager->drv->checkStorageVol) + ret = manager->drv->checkStorageVol(manager, driverName, pool, vol, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index 0c4648c0fb..f599002056 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2199,7 +2199,7 @@ elsif ($mode eq "client") { + print " virObjectUnref(mgr);\n"; + if ($action eq "Ensure") { + print " if (rv == 0)\n"; +- print " virReportError(VIR_ERR_ACCESS_DENIED, NULL);\n"; ++ print " virReportError(VIR_ERR_ACCESS_DENIED, conn->driver->name, NULL);\n"; + print " return $fail;\n"; + } else { + print " virResetLastError();\n"; +diff --git a/src/util/virerror.c b/src/util/virerror.c +index f198f27957..5f50fa0349 100644 +--- a/src/util/virerror.c ++++ b/src/util/virerror.c +@@ -1439,9 +1439,9 @@ virErrorMsg(virErrorNumber error, const char *info) + break; + case VIR_ERR_ACCESS_DENIED: + if (info == NULL) +- errmsg = _("access denied"); ++ errmsg = _("access denied from '%s'"); + else +- errmsg = _("access denied: %s"); ++ errmsg = _("access denied from '%s': %s"); + break; + case VIR_ERR_DBUS_SERVICE: + if (info == NULL) +-- +2.19.1 + diff --git a/SOURCES/libvirt-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName_1.patch b/SOURCES/libvirt-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName_1.patch new file mode 100644 index 0000000..dc0cb0a --- /dev/null +++ b/SOURCES/libvirt-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName_1.patch @@ -0,0 +1,159 @@ +From 541a154e0f98604f63cb22356287dfa3858748c9 Mon Sep 17 00:00:00 2001 +Message-Id: <541a154e0f98604f63cb22356287dfa3858748c9@dist-git> +From: John Ferlan +Date: Thu, 15 Nov 2018 06:43:59 -0500 +Subject: [PATCH] access: Modify the VIR_ERR_ACCESS_DENIED to include + driverName + +https://bugzilla.redhat.com/show_bug.cgi?id=1631608 (RHEL8) +https://bugzilla.redhat.com/show_bug.cgi?id=1631606 (RHEL7) + +Changes made to manage and utilize a secondary connection +driver to APIs outside the scope of the primary connection +driver have resulted in some confusion processing polkit rules +since the simple "access denied" error message doesn't provide +enough of a clue when combined with the "authentication failed: +access denied by policy" as to which connection driver refused +or failed the ACL check. + +In order to provide some context, let's modify the existing +"access denied" error returned from the various vir*EnsureACL +API's to provide the connection driver name that is causing +the failure. This should provide the context for writing the +polkit rules that would allow access via the driver, but yet +still adhere to the virAccessManagerSanitizeError commentary +regarding not telling the user why access was denied. + +Signed-off-by: John Ferlan +(cherry picked from commit 605496be609e153526fcdd3e98df8cf5244bc8fa) +Reviewed-by: Erik Skultety +--- + src/access/viraccessmanager.c | 26 ++++++++++++++------------ + src/rpc/gendispatch.pl | 3 ++- + 2 files changed, 16 insertions(+), 13 deletions(-) + +diff --git a/src/access/viraccessmanager.c b/src/access/viraccessmanager.c +index e7b5bf38da..f5d62604cf 100644 +--- a/src/access/viraccessmanager.c ++++ b/src/access/viraccessmanager.c +@@ -196,11 +196,13 @@ static void virAccessManagerDispose(void *object) + * should the admin need to debug things + */ + static int +-virAccessManagerSanitizeError(int ret) ++virAccessManagerSanitizeError(int ret, ++ const char *driverName) + { + if (ret < 0) { + virResetLastError(); +- virAccessError(VIR_ERR_ACCESS_DENIED, NULL); ++ virAccessError(VIR_ERR_ACCESS_DENIED, ++ _("'%s' denied access"), driverName); + } + + return ret; +@@ -217,7 +219,7 @@ int virAccessManagerCheckConnect(virAccessManagerPtr manager, + if (manager->drv->checkConnect) + ret = manager->drv->checkConnect(manager, driverName, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + +@@ -233,7 +235,7 @@ int virAccessManagerCheckDomain(virAccessManagerPtr manager, + if (manager->drv->checkDomain) + ret = manager->drv->checkDomain(manager, driverName, domain, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckInterface(virAccessManagerPtr manager, +@@ -248,7 +250,7 @@ int virAccessManagerCheckInterface(virAccessManagerPtr manager, + if (manager->drv->checkInterface) + ret = manager->drv->checkInterface(manager, driverName, iface, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNetwork(virAccessManagerPtr manager, +@@ -263,7 +265,7 @@ int virAccessManagerCheckNetwork(virAccessManagerPtr manager, + if (manager->drv->checkNetwork) + ret = manager->drv->checkNetwork(manager, driverName, network, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, +@@ -278,7 +280,7 @@ int virAccessManagerCheckNodeDevice(virAccessManagerPtr manager, + if (manager->drv->checkNodeDevice) + ret = manager->drv->checkNodeDevice(manager, driverName, nodedev, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNWFilter(virAccessManagerPtr manager, +@@ -293,7 +295,7 @@ int virAccessManagerCheckNWFilter(virAccessManagerPtr manager, + if (manager->drv->checkNWFilter) + ret = manager->drv->checkNWFilter(manager, driverName, nwfilter, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager, +@@ -308,7 +310,7 @@ int virAccessManagerCheckNWFilterBinding(virAccessManagerPtr manager, + if (manager->drv->checkNWFilterBinding) + ret = manager->drv->checkNWFilterBinding(manager, driverName, binding, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckSecret(virAccessManagerPtr manager, +@@ -323,7 +325,7 @@ int virAccessManagerCheckSecret(virAccessManagerPtr manager, + if (manager->drv->checkSecret) + ret = manager->drv->checkSecret(manager, driverName, secret, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckStoragePool(virAccessManagerPtr manager, +@@ -338,7 +340,7 @@ int virAccessManagerCheckStoragePool(virAccessManagerPtr manager, + if (manager->drv->checkStoragePool) + ret = manager->drv->checkStoragePool(manager, driverName, pool, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } + + int virAccessManagerCheckStorageVol(virAccessManagerPtr manager, +@@ -354,5 +356,5 @@ int virAccessManagerCheckStorageVol(virAccessManagerPtr manager, + if (manager->drv->checkStorageVol) + ret = manager->drv->checkStorageVol(manager, driverName, pool, vol, perm); + +- return virAccessManagerSanitizeError(ret); ++ return virAccessManagerSanitizeError(ret, driverName); + } +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index 0c4648c0fb..a8b9f5aeca 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2199,7 +2199,8 @@ elsif ($mode eq "client") { + print " virObjectUnref(mgr);\n"; + if ($action eq "Ensure") { + print " if (rv == 0)\n"; +- print " virReportError(VIR_ERR_ACCESS_DENIED, NULL);\n"; ++ print " virReportError(VIR_ERR_ACCESS_DENIED,\n"; ++ print" _(\"'%s' denied access\"), conn->driver->name);\n"; + print " return $fail;\n"; + } else { + print " virResetLastError();\n"; +-- +2.19.2 + diff --git a/SOURCES/libvirt-conf-Add-validation-of-input-devices.patch b/SOURCES/libvirt-conf-Add-validation-of-input-devices.patch new file mode 100644 index 0000000..5f9dbbb --- /dev/null +++ b/SOURCES/libvirt-conf-Add-validation-of-input-devices.patch @@ -0,0 +1,76 @@ +From c2afbedc310ac1a65a5ee96c8fa4103e926483c4 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Han Han +Date: Tue, 28 Aug 2018 10:30:51 +0200 +Subject: [PATCH] conf: Add validation of input devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1591151 + +Add function virDomainInputDefValidate to validate input devices. +Make sure evdev attribute of source element is not used by mouse, +keyboard, and tablet input device. + +Signed-off-by: Han Han +Reviewed-by: John Ferlan +(cherry picked from commit deb057fd364cb57614c6dea7b05c247231f9ae4f) +Signed-off-by: Ján Tomko + +https: //bugzilla.redhat.com/show_bug.cgi?id=1591240 +Reviewed-by: Andrea Bolognani +--- + src/conf/domain_conf.c | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 51a79ad8b1..16e52d149d 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -5760,6 +5760,29 @@ virDomainVsockDefValidate(const virDomainVsockDef *vsock) + return 0; + } + ++static int ++virDomainInputDefValidate(const virDomainInputDef *input) ++{ ++ switch ((virDomainInputType) input->type) { ++ case VIR_DOMAIN_INPUT_TYPE_MOUSE: ++ case VIR_DOMAIN_INPUT_TYPE_TABLET: ++ case VIR_DOMAIN_INPUT_TYPE_KBD: ++ case VIR_DOMAIN_INPUT_TYPE_LAST: ++ if (input->source.evdev) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("setting source evdev path only supported for " ++ "passthrough input devices")); ++ return -1; ++ } ++ break; ++ ++ case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: ++ break; ++ } ++ ++ return 0; ++} ++ + + static int + virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, +@@ -5799,9 +5822,11 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, + case VIR_DOMAIN_DEVICE_VSOCK: + return virDomainVsockDefValidate(dev->data.vsock); + ++ case VIR_DOMAIN_DEVICE_INPUT: ++ return virDomainInputDefValidate(dev->data.input); ++ + case VIR_DOMAIN_DEVICE_LEASE: + case VIR_DOMAIN_DEVICE_FS: +- case VIR_DOMAIN_DEVICE_INPUT: + case VIR_DOMAIN_DEVICE_SOUND: + case VIR_DOMAIN_DEVICE_WATCHDOG: + case VIR_DOMAIN_DEVICE_GRAPHICS: +-- +2.18.0 + diff --git a/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch new file mode 100644 index 0000000..9d79b6a --- /dev/null +++ b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch @@ -0,0 +1,69 @@ +From 2e3774564235a185a2cc4b7a22c17de17498db68 Mon Sep 17 00:00:00 2001 +Message-Id: <2e3774564235a185a2cc4b7a22c17de17498db68@dist-git> +From: Michal Privoznik +Date: Thu, 18 Apr 2019 19:36:31 +0200 +Subject: [PATCH] conf: Expose virDomainSCSIDriveAddressIsUsed + +RHEl-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1692296 +RHEL-8.1.0: https://bugzilla.redhat.com/show_bug.cgi?id=1692354 + +This function checks if given drive address is already present in +passed domain definition. Expose the function as it will be used +shortly. + +Signed-off-by: Michal Privoznik +Tested-by: Daniel Henrique Barboza +Reviewed-by: Jim Fehlig +(cherry picked from commit 89237d534f0fe950d06a2081089154160c6c2224) +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/conf/domain_conf.c | 2 +- + src/conf/domain_conf.h | 4 ++++ + src/libvirt_private.syms | 1 + + 3 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index d431441f62..e62f78471c 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -4404,7 +4404,7 @@ virDomainDriveAddressIsUsedByHostdev(const virDomainDef *def, + * Return true if the SCSI drive address is already in use, false + * otherwise. + */ +-static bool ++bool + virDomainSCSIDriveAddressIsUsed(const virDomainDef *def, + const virDomainDeviceDriveAddress *addr) + { +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index f05fca284f..dbccf2cf24 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2789,6 +2789,10 @@ virDomainXMLNamespacePtr + virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt) + ATTRIBUTE_NONNULL(1); + ++bool ++virDomainSCSIDriveAddressIsUsed(const virDomainDef *def, ++ const virDomainDeviceDriveAddress *addr); ++ + int virDomainDefPostParse(virDomainDefPtr def, + virCapsPtr caps, + unsigned int parseFlags, +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 624151056a..df27ac4b3a 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -520,6 +520,7 @@ virDomainRunningReasonTypeToString; + virDomainSaveConfig; + virDomainSaveStatus; + virDomainSaveXML; ++virDomainSCSIDriveAddressIsUsed; + virDomainSeclabelTypeFromString; + virDomainSeclabelTypeToString; + virDomainShmemDefEquals; +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Fix-a-error-msg-typo-in-virDomainVideoDefValidate.patch b/SOURCES/libvirt-conf-Fix-a-error-msg-typo-in-virDomainVideoDefValidate.patch new file mode 100644 index 0000000..c848359 --- /dev/null +++ b/SOURCES/libvirt-conf-Fix-a-error-msg-typo-in-virDomainVideoDefValidate.patch @@ -0,0 +1,35 @@ +From b1c91c78451c59b0ebe3aafa17eef764e69be28c Mon Sep 17 00:00:00 2001 +Message-Id: +From: Han Han +Date: Tue, 31 Jul 2018 10:42:27 +0200 +Subject: [PATCH] conf: Fix a error msg typo in virDomainVideoDefValidate + +https://bugzilla.redhat.com/show_bug.cgi?id=1607825 + +Introduced by commit d48813e8. + +Signed-off-by: Han Han +Reviewed-by: Erik Skultety +(cherry picked from commit d1c4480390da7243e37daee37f8a40cb439a6a7c) +Signed-off-by: Erik Skultety +Reviewed-by: Jiri Denemark +--- + 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 23288aa01b..a05aad056d 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -5697,7 +5697,7 @@ virDomainVideoDefValidate(const virDomainVideoDef *video, + if (def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_NONE && + def->nvideos > 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +- _("a '%s' video type must be the only video device " ++ _("a 'none' video type must be the only video device " + "defined for the domain")); + return -1; + } +-- +2.18.0 + diff --git a/SOURCES/libvirt-conf-Fix-check-for-chardev-source-path.patch b/SOURCES/libvirt-conf-Fix-check-for-chardev-source-path.patch new file mode 100644 index 0000000..6aa4fef --- /dev/null +++ b/SOURCES/libvirt-conf-Fix-check-for-chardev-source-path.patch @@ -0,0 +1,113 @@ +From 27213f01f9320cf0fec49980f78a100e64025ba4 Mon Sep 17 00:00:00 2001 +Message-Id: <27213f01f9320cf0fec49980f78a100e64025ba4@dist-git> +From: Andrea Bolognani +Date: Fri, 7 Sep 2018 17:53:32 +0200 +Subject: [PATCH] conf: Fix check for chardev source path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Attempting to use a chardev definition like + + + + + +correctly results in an error being reported, since the source +path - a required piece of information - is missing; however, +the very similar + + + + + +was happily accepted by libvirt, only to result in libvirtd +crashing as soon as the guest was started. + +The issue was caused by checking the chardev's targetType +against whitelisted values from virDomainChrChannelTargetType +without first checking the chardev's deviceType to make sure +it is actually a channel, for which the check makes sense, +rather than a different type of chardev. + +The only reason this wasn't spotted earlier is that the +whitelisted values just so happen to correspond to USB and +PCI serial devices and Xen and UML consoles respectively, +all of which are fairly uncommon. + +https://bugzilla.redhat.com/show_bug.cgi?id=1609720 + +Signed-off-by: Andrea Bolognani +Reviewed-by: Ján Tomko +(cherry picked from commit 614193fac67445a7e92bf620ffef726ed1bd6f07) + +https://bugzilla.redhat.com/show_bug.cgi?id=1609723 + +Signed-off-by: Andrea Bolognani +Reviewed-by: Erik Skultety +--- + src/conf/domain_conf.c | 11 +++++++---- + .../serial-unix-missing-source.xml | 15 +++++++++++++++ + tests/qemuxml2argvtest.c | 1 + + 3 files changed, 23 insertions(+), 4 deletions(-) + create mode 100644 tests/qemuxml2argvdata/serial-unix-missing-source.xml + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index a881b43b51..240b33f28c 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -5523,11 +5523,14 @@ virDomainChrSourceDefValidate(const virDomainChrSourceDef *def, + break; + + case VIR_DOMAIN_CHR_TYPE_UNIX: +- /* path can be auto generated */ ++ /* The source path can be auto generated for certain specific ++ * types of channels, but in most cases we should report an ++ * error if the user didn't provide it */ + if (!def->data.nix.path && +- (!chr_def || +- (chr_def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN && +- chr_def->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO))) { ++ !(chr_def && ++ chr_def->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && ++ (chr_def->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN || ++ chr_def->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Missing source path attribute for char device")); + return -1; +diff --git a/tests/qemuxml2argvdata/serial-unix-missing-source.xml b/tests/qemuxml2argvdata/serial-unix-missing-source.xml +new file mode 100644 +index 0000000000..1e1221f12d +--- /dev/null ++++ b/tests/qemuxml2argvdata/serial-unix-missing-source.xml +@@ -0,0 +1,15 @@ ++ ++ guest ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 1048576 ++ 1 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-aarch64 ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 608a2b6ce3..ebe9c8a131 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1363,6 +1363,7 @@ mymain(void) + DO_TEST("serial-unix-chardev", + QEMU_CAPS_DEVICE_ISA_SERIAL); + DO_TEST_CAPS_LATEST("serial-unix-chardev"); ++ DO_TEST_PARSE_ERROR("serial-unix-missing-source", NONE); + DO_TEST("serial-tcp-chardev", + QEMU_CAPS_DEVICE_ISA_SERIAL); + DO_TEST("serial-udp-chardev", +-- +2.19.1 + diff --git a/SOURCES/libvirt-conf-Introduce-new-hostdev-attribute-display.patch b/SOURCES/libvirt-conf-Introduce-new-hostdev-attribute-display.patch new file mode 100644 index 0000000..2dc0045 --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-new-hostdev-attribute-display.patch @@ -0,0 +1,416 @@ +From 5ad0f7cc1b2444ee9355229316fb008919d22c71 Mon Sep 17 00:00:00 2001 +Message-Id: <5ad0f7cc1b2444ee9355229316fb008919d22c71@dist-git> +From: Erik Skultety +Date: Thu, 19 Jul 2018 15:04:02 +0200 +Subject: [PATCH] conf: Introduce new attribute 'display' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QEMU 2.12 introduced a new type of display for mediated devices using +vfio-pci backend which allows a mediated device to be used as a VGA +compatible device as an alternative to an emulated video device. QEMU +exposes this feature via a vfio device property 'display' with supported +values 'on/off/auto' (libvirt will default to 'off'). + +This patch adds the necessary bits to domain config handling in order to +expose this feature. Since there's no convenient way for libvirt to come +up with usable defaults for the display setting, simply because libvirt +is not able to figure out which of the display implementations - dma-buf +which requires OpenGL support vs vfio regions which doesn't need OpenGL +(works with OpenGL enabled too) - the underlying mdev uses. + +Reviewed-by: Ján Tomko +Signed-off-by: Erik Skultety +(cherry picked from commit d54e45b6edd7623e488a19e30bc4148a21fa8b03) + +https://bugzilla.redhat.com/show_bug.cgi?id=1475770 +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +--- + docs/formatdomain.html.in | 20 +++- + docs/schemas/domaincommon.rng | 5 + + src/conf/domain_conf.c | 19 +++- + src/conf/domain_conf.h | 1 + + src/qemu/qemu_domain.c | 98 ++++++++++++++++++- + .../qemuxml2argvdata/hostdev-mdev-display.xml | 39 ++++++++ + .../hostdev-mdev-display.xml | 47 +++++++++ + tests/qemuxml2xmltest.c | 1 + + 8 files changed, 222 insertions(+), 8 deletions(-) + create mode 100644 tests/qemuxml2argvdata/hostdev-mdev-display.xml + create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 9dd22554ad..3554c3dc30 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -4510,9 +4510,23 @@ + guest. Currently, model='vfio-pci' and + model='vfio-ccw' (Since 4.4.0) + is supported. Refer MDEV to create +- a mediated device on the host. There are also some implications on the +- usage of guest's address type depending on the model +- attribute, see the address element below. ++ a mediated device on the host. ++ Since 4.6.0 (QEMU 2.12) an optional ++ display attribute may be used to enable or disable ++ support for an accelerated remote desktop backed by a mediated ++ device (such as NVIDIA vGPU or Intel GVT-g) as an alternative to ++ emulated video devices. This attribute ++ is limited to model='vfio-pci' only. Supported values ++ are either on or off (default is 'off'). ++ It is required to use a ++ graphical framebuffer in order to ++ use this attribute, currently only supported with VNC, Spice and ++ egl-headless graphics devices. ++

++ Note: There are also some implications on the usage of guest's ++ address type depending on the model attribute, ++ see the address element below. ++

+ + +

+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 157726752c..be8430ab22 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -4579,6 +4579,11 @@ + vfio-ccw + + ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 72086f9e86..830c298158 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -7656,6 +7656,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, + char *rawio = NULL; + char *backendStr = NULL; + char *model = NULL; ++ char *display = NULL; + int backend; + int ret = -1; + virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci; +@@ -7675,6 +7676,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, + sgio = virXMLPropString(node, "sgio"); + rawio = virXMLPropString(node, "rawio"); + model = virXMLPropString(node, "model"); ++ display = virXMLPropString(node, "display"); + + /* @type is passed in from the caller rather than read from the + * xml document, because it is specified in different places for +@@ -7762,6 +7764,15 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, + model); + goto cleanup; + } ++ ++ if (display && ++ (mdevsrc->display = virTristateSwitchTypeFromString(display)) <= 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("unknown value '%s' for attribute " ++ "'display'"), ++ display); ++ goto cleanup; ++ } + } + + switch (def->source.subsys.type) { +@@ -7815,6 +7826,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, + VIR_FREE(rawio); + VIR_FREE(backendStr); + VIR_FREE(model); ++ VIR_FREE(display); + return ret; + } + +@@ -26568,9 +26580,14 @@ virDomainHostdevDefFormat(virBufferPtr buf, + virTristateBoolTypeToString(scsisrc->rawio)); + } + +- if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) ++ if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) { + virBufferAsprintf(buf, " model='%s'", + virMediatedDeviceModelTypeToString(mdevsrc->model)); ++ if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) ++ virBufferAsprintf(buf, " display='%s'", ++ virTristateSwitchTypeToString(mdevsrc->display)); ++ } ++ + } + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 3deda1d978..8ca9558ceb 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -382,6 +382,7 @@ typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediated + typedef virDomainHostdevSubsysMediatedDev *virDomainHostdevSubsysMediatedDevPtr; + struct _virDomainHostdevSubsysMediatedDev { + int model; /* enum virMediatedDeviceModelType */ ++ int display; /* virTristateSwitch */ + char uuidstr[VIR_UUID_STRING_BUFLEN]; /* mediated device's uuid string */ + }; + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 9498594857..5337f1ce55 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -4451,9 +4451,48 @@ qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net) + + + static int +-qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, +- const virDomainDef *def) ++qemuDomainMdevDefValidate(const virDomainHostdevSubsysMediatedDev *mdevsrc, ++ const virDomainDef *def, ++ virQEMUCapsPtr qemuCaps) + { ++ if (mdevsrc->display == VIR_TRISTATE_SWITCH_ABSENT) ++ return 0; ++ ++ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("display property of device vfio-pci is " ++ "not supported by this version of QEMU")); ++ return -1; ++ } ++ ++ if (mdevsrc->model != VIR_MDEV_MODEL_TYPE_VFIO_PCI) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _(" attribute 'display' is only supported" ++ " with model='vfio-pci'")); ++ ++ return -1; ++ } ++ ++ if (mdevsrc->display == VIR_TRISTATE_SWITCH_ON) { ++ if (def->ngraphics == 0) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("graphics device is needed for attribute value " ++ "'display=on' in ")); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static int ++qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, ++ const virDomainDef *def, ++ virQEMUCapsPtr qemuCaps) ++{ ++ const virDomainHostdevSubsysMediatedDev *mdevsrc; ++ + /* forbid capabilities mode hostdev in this kind of hypervisor */ + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +@@ -4463,6 +4502,24 @@ qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef *hostdev, + return -1; + } + ++ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { ++ switch ((virDomainHostdevSubsysType) hostdev->source.subsys.type) { ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: ++ break; ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: ++ mdevsrc = &hostdev->source.subsys.u.mdev; ++ return qemuDomainMdevDefValidate(mdevsrc, def, qemuCaps); ++ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: ++ default: ++ virReportEnumRangeError(virDomainHostdevSubsysType, ++ hostdev->source.subsys.type); ++ return -1; ++ } ++ } ++ + return 0; + } + +@@ -5595,7 +5652,8 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, + break; + + case VIR_DOMAIN_DEVICE_HOSTDEV: +- ret = qemuDomainDeviceDefValidateHostdev(dev->data.hostdev, def); ++ ret = qemuDomainDeviceDefValidateHostdev(dev->data.hostdev, def, ++ qemuCaps); + break; + + case VIR_DOMAIN_DEVICE_VIDEO: +@@ -6205,6 +6263,35 @@ qemuDomainVsockDefPostParse(virDomainVsockDefPtr vsock) + } + + ++static int ++qemuDomainHostdevDefMdevPostParse(virDomainHostdevSubsysMediatedDevPtr mdevsrc, ++ virQEMUCapsPtr qemuCaps) ++{ ++ /* QEMU 2.12 added support for vfio-pci display type, we default to ++ * 'display=off' to stay safe from future changes */ ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_DISPLAY) && ++ mdevsrc->display == VIR_TRISTATE_SWITCH_ABSENT) ++ mdevsrc->display = VIR_TRISTATE_SWITCH_OFF; ++ ++ return 0; ++} ++ ++ ++static int ++qemuDomainHostdevDefPostParse(virDomainHostdevDefPtr hostdev, ++ virQEMUCapsPtr qemuCaps) ++{ ++ virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; ++ ++ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && ++ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV && ++ qemuDomainHostdevDefMdevPostParse(&subsys->u.mdev, qemuCaps) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + static int + qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, + const virDomainDef *def, +@@ -6255,11 +6342,14 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, + ret = qemuDomainVsockDefPostParse(dev->data.vsock); + break; + ++ case VIR_DOMAIN_DEVICE_HOSTDEV: ++ ret = qemuDomainHostdevDefPostParse(dev->data.hostdev, qemuCaps); ++ break; ++ + case VIR_DOMAIN_DEVICE_LEASE: + case VIR_DOMAIN_DEVICE_FS: + case VIR_DOMAIN_DEVICE_INPUT: + case VIR_DOMAIN_DEVICE_SOUND: +- case VIR_DOMAIN_DEVICE_HOSTDEV: + case VIR_DOMAIN_DEVICE_WATCHDOG: + case VIR_DOMAIN_DEVICE_GRAPHICS: + case VIR_DOMAIN_DEVICE_HUB: +diff --git a/tests/qemuxml2argvdata/hostdev-mdev-display.xml b/tests/qemuxml2argvdata/hostdev-mdev-display.xml +new file mode 100644 +index 0000000000..f37e08e1b9 +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-mdev-display.xml +@@ -0,0 +1,39 @@ ++ ++ QEMUGuest2 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i686 ++ ++ ++ ++ ++

++ ++ ++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2xmloutdata/hostdev-mdev-display.xml b/tests/qemuxml2xmloutdata/hostdev-mdev-display.xml +new file mode 100644 +index 0000000000..94c11b1199 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-mdev-display.xml +@@ -0,0 +1,47 @@ ++ ++ QEMUGuest2 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i686 ++ ++ ++ ++ ++
++ ++ ++
++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++