From 99cbc7849a38c94360543d40bae3a541c2306a93 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2019 12:57:08 +0000 Subject: import libvirt-4.5.0-26.el7 --- 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-Handle-copying-bitmaps-to-larger-data-buffers.patch b/SOURCES/libvirt-Handle-copying-bitmaps-to-larger-data-buffers.patch new file mode 100644 index 0000000..8a5f286 --- /dev/null +++ b/SOURCES/libvirt-Handle-copying-bitmaps-to-larger-data-buffers.patch @@ -0,0 +1,54 @@ +From 806c01fea005e3887ad74efa3ecbab8294c0ddca Mon Sep 17 00:00:00 2001 +Message-Id: <806c01fea005e3887ad74efa3ecbab8294c0ddca@dist-git> +From: "Allen, John" +Date: Fri, 26 Apr 2019 15:12:01 +0200 +Subject: [PATCH] Handle copying bitmaps to larger data buffers + +If a bitmap of a shorter length than the data buffer is passed to +virBitmapToDataBuf, it will read off the end of the bitmap and copy junk +into the returned buffer. Add a check to only copy the length of the +bitmap to the buffer. + +The problem can be observed after setting a vcpu affinity using the vcpupin +command on a system with a large number of cores: + # virsh vcpupin example_domain 0 0 + # virsh vcpupin example_domain 0 + VCPU CPU Affinity + --------------------------- + 0 0,192,197-198,202 + +Signed-off-by: John Allen +(cherry picked from commit 51f9f80d350e633adf479c6a9b3c55f82ca9cbd4) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1703159 + +Signed-off-by: Pavel Hrdina +Message-Id: <8c72d73f39288e0a38d72481e771d1df53d593a3.1556284274.git.phrdina@redhat.com> +Reviewed-by: Andrea Bolognani +--- + src/util/virbitmap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c +index 0cc5292d8c..0bc0d068bb 100644 +--- a/src/util/virbitmap.c ++++ b/src/util/virbitmap.c +@@ -832,11 +832,15 @@ virBitmapToDataBuf(virBitmapPtr bitmap, + unsigned char *bytes, + size_t len) + { ++ size_t nbytes = bitmap->map_len * (VIR_BITMAP_BITS_PER_UNIT / CHAR_BIT); + unsigned long *l; + size_t i, j; + + memset(bytes, 0, len); + ++ /* If bitmap and buffer differ in size, only fill to the smaller length */ ++ len = MIN(len, nbytes); ++ + /* htole64 is not provided by gnulib, so we do the conversion by hand */ + l = bitmap->map; + for (i = j = 0; i < len; i++, j++) { +-- +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..d747a75 --- /dev/null +++ b/SOURCES/libvirt-RHEL-Add-rhel-machine-types-to-qemuDomainMachineNeedsFDC.patch @@ -0,0 +1,35 @@ +From ff2b3b8bdb05750071b2c799431c7cc35db348f3 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 | 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-Add-support-for-QMP-I-O-error-reason.patch b/SOURCES/libvirt-RHEL-Add-support-for-QMP-I-O-error-reason.patch new file mode 100644 index 0000000..950cf92 --- /dev/null +++ b/SOURCES/libvirt-RHEL-Add-support-for-QMP-I-O-error-reason.patch @@ -0,0 +1,52 @@ +From 12912db55da81fff50119b780b151a0fc864d878 Mon Sep 17 00:00:00 2001 +Message-Id: <12912db55da81fff50119b780b151a0fc864d878@dist-git> +From: Jiri Denemark +Date: Thu, 9 Oct 2014 10:38:39 +0200 +Subject: [PATCH] RHEL: Add support for QMP I/O error reason + +RHEL-only + +Adds support for __com.redhat_reason on I/O error events. The code will +fallback to upstream nospace boolean if the reason is not present and +complain if neither of these is found. + +https://bugzilla.redhat.com/show_bug.cgi?id=1119784 + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_monitor_json.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index ec8469476e..1bc5b662ae 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -740,7 +740,7 @@ qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data) + { + const char *device; + const char *action; +- const char *reason = ""; ++ const char *reason; + bool nospc = false; + int actionID; + +@@ -756,8 +756,14 @@ qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data) + if ((device = virJSONValueObjectGetString(data, "device")) == NULL) + VIR_WARN("missing device in disk io error event"); + +- if (virJSONValueObjectGetBoolean(data, "nospace", &nospc) == 0 && nospc) +- reason = "enospc"; ++ reason = virJSONValueObjectGetString(data, "__com.redhat_reason"); ++ if (!reason) { ++ if (virJSONValueObjectGetBoolean(data, "nospace", &nospc) != 0) { ++ VIR_WARN("neither __com.redhat_reason nor nospace found in disk " ++ "io error event"); ++ } ++ reason = nospc ? "enospc" : ""; ++ } + + if ((actionID = qemuMonitorIOErrorActionTypeFromString(action)) < 0) { + VIR_WARN("unknown disk io error action '%s'", action); +-- +2.18.0 + diff --git a/SOURCES/libvirt-RHEL-Define-ETHTOOL_-GS-COALESCE-when-building-on-older-kernels.patch b/SOURCES/libvirt-RHEL-Define-ETHTOOL_-GS-COALESCE-when-building-on-older-kernels.patch new file mode 100644 index 0000000..cd55ddf --- /dev/null +++ b/SOURCES/libvirt-RHEL-Define-ETHTOOL_-GS-COALESCE-when-building-on-older-kernels.patch @@ -0,0 +1,62 @@ +From c26689a72b04c30ea703d8820f4fc3ce840c6e3b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Martin Kletzander +Date: Tue, 25 Apr 2017 13:41:21 +0200 +Subject: [PATCH] RHEL: Define ETHTOOL_[GS]COALESCE when building on older + kernels + +https://bugzilla.redhat.com/show_bug.cgi?id=1414627 + +RHEL-only (upstream will have this only when built on kernel that +supports it). + +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/util/virnetdev.c | 23 ++++++++--------------- + 1 file changed, 8 insertions(+), 15 deletions(-) + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index b250af9e2c..bc1e70f0a8 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -3393,7 +3393,14 @@ virNetDevGetEthtoolGFeatures(virBitmapPtr bitmap ATTRIBUTE_UNUSED, + # endif + + +-# if HAVE_DECL_ETHTOOL_SCOALESCE && HAVE_DECL_ETHTOOL_GCOALESCE ++/* Workaround for binary distributions building on old kernels */ ++# ifndef ETHTOOL_GCOALESCE ++# define ETHTOOL_GCOALESCE 0x0000000e ++# endif ++# ifndef ETHTOOL_SCOALESCE ++# define ETHTOOL_SCOALESCE 0x0000000f ++# endif ++ + /** + * virNetDevSetCoalesce: + * @ifname: interface name to modify +@@ -3493,20 +3500,6 @@ int virNetDevSetCoalesce(const char *ifname, + VIR_FORCE_CLOSE(fd); + return ret; + } +-# else +-int virNetDevSetCoalesce(const char *ifname, +- virNetDevCoalescePtr coalesce, +- bool update) +-{ +- if (!coalesce && !update) +- return 0; +- +- virReportSystemError(ENOSYS, +- _("Cannot set coalesce info on interface '%s'"), +- ifname); +- return -1; +-} +-# endif + + + /** +-- +2.18.0 + diff --git a/SOURCES/libvirt-RHEL-Fix-maxvcpus-output.patch b/SOURCES/libvirt-RHEL-Fix-maxvcpus-output.patch new file mode 100644 index 0000000..4640622 --- /dev/null +++ b/SOURCES/libvirt-RHEL-Fix-maxvcpus-output.patch @@ -0,0 +1,39 @@ +From 7dff909fa34bdd93ad200dbffe70c0c1ee931925 Mon Sep 17 00:00:00 2001 +Message-Id: <7dff909fa34bdd93ad200dbffe70c0c1ee931925@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Wed, 17 Sep 2014 19:00:58 +0200 +Subject: [PATCH] RHEL: Fix maxvcpus output + +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 + +Signed-off-by: Jiri Denemark +--- + src/util/virhostcpu.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index 013c95bb56..3f7d70b87b 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -1214,6 +1214,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..8bb5717 --- /dev/null +++ b/SOURCES/libvirt-RHEL-Hack-around-changed-Broadwell-Haswell-CPUs.patch @@ -0,0 +1,165 @@ +From af7f65d5ce4fe129b0844eb031212a3fb397b8da Mon Sep 17 00:00:00 2001 +Message-Id: +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-Support-virtio-disk-hotplug-in-JSON-mode.patch b/SOURCES/libvirt-RHEL-Support-virtio-disk-hotplug-in-JSON-mode.patch new file mode 100644 index 0000000..e0241fc --- /dev/null +++ b/SOURCES/libvirt-RHEL-Support-virtio-disk-hotplug-in-JSON-mode.patch @@ -0,0 +1,457 @@ +From 8bac3f7591f7df980a631deeb67a2f20eab6fc62 Mon Sep 17 00:00:00 2001 +Message-Id: <8bac3f7591f7df980a631deeb67a2f20eab6fc62@dist-git> +From: Jiri Denemark +Date: Tue, 5 Apr 2016 09:14:09 +0200 +Subject: [PATCH] RHEL: Support virtio disk hotplug in JSON mode + +RHEL only, no upstream + +For bug + https://bugzilla.redhat.com/show_bug.cgi?id=1026966 + https://bugzilla.redhat.com/show_bug.cgi?id=573946 + +The existing drive_add command can hotplug SCSI and VirtIO +disks, but this isn't ported to JSON mode. RHEL6 introduces +a custom __com.redhat_drive_add that only supports VirtIO +disks. Switch the VirtIO hotplug to this command, but leave +the SCSI hotplug using old command so SCSI gets an explicit +error about being unsupported. + +* src/libvirt_private.syms: Export virJSONValueObjectRemoveKey +* src/util/json.c, src/util/json.h: Add virJSONValueObjectRemoveKey + to allow a key to be deleted from an object +* src/qemu/qemu_monitor_json.c: Try __com.redhat_drive_add first and use + drive_add only if the redhat command is not known to qemu. + +Also includes the following fix: + +https://bugzilla.redhat.com/show_bug.cgi?id=696596 + +Upstream added drive_del as a way to ensure that disks are fully +removed before returning control to libvirt. But RHEL backported +it as __com.redhat_drive_del, prior to upstream adoption of a +QMP counterpart. Because we weren't trying the RHEL-specific +spelling, we were falling back to the unsafe approach of just +removing the device and hoping for the best, which was racy and +could occasionally result in a rapid hot-plug cycle trying to +plug in a new disk that collides with the old disk not yet gone. + +* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveDel): Try +rhel-specific drive_del monitor command first. + +(cherry picked from commit d1c200dfead14a590a4ddebe20a20ffe441d2b24 in +rhel-6.5 branch) + +Signed-off-by: Jiri Denemark + +Conflicts: + src/libvirt_private.syms - the change is already upstream + src/util/virjson.[ch] - the change is already upstream + src/qemu/qemu_monitor_json.c - context; upstream doesn't try to + call nonexistent drive_{add,del} QMP commands any more +--- + src/qemu/qemu_monitor.c | 12 ++-- + src/qemu/qemu_monitor_json.c | 107 +++++++++++++++++++++++++++++++++++ + src/qemu/qemu_monitor_json.h | 6 ++ + tests/qemuhotplugtest.c | 93 +++++++++++++++++++++++++++++- + 4 files changed, 212 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 6fc038a8d9..5e0e95cc51 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -2947,8 +2947,10 @@ qemuMonitorDriveDel(qemuMonitorPtr mon, + + QEMU_CHECK_MONITOR(mon); + +- /* there won't be a direct replacement for drive_del in QMP */ +- return qemuMonitorTextDriveDel(mon, drivestr); ++ if (mon->json) ++ return qemuMonitorJSONDriveDel(mon, drivestr); ++ else ++ return qemuMonitorTextDriveDel(mon, drivestr); + } + + +@@ -3137,8 +3139,10 @@ qemuMonitorAddDrive(qemuMonitorPtr mon, + + QEMU_CHECK_MONITOR(mon); + +- /* there won't ever be a direct QMP replacement for this function */ +- return qemuMonitorTextAddDrive(mon, drivestr); ++ if (mon->json) ++ return qemuMonitorJSONAddDrive(mon, drivestr); ++ else ++ return qemuMonitorTextAddDrive(mon, drivestr); + } + + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index af754e870e..ec8469476e 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -4055,6 +4055,113 @@ int qemuMonitorJSONDelObject(qemuMonitorPtr mon, + } + + ++int qemuMonitorJSONAddDrive(qemuMonitorPtr mon, ++ const char *drivestr) ++{ ++ int ret = -1; ++ virJSONValuePtr cmd; ++ virJSONValuePtr reply = NULL; ++ virJSONValuePtr args; ++ ++ cmd = qemuMonitorJSONMakeCommand("__com.redhat_drive_add", ++ NULL); ++ if (!cmd) ++ return -1; ++ ++ args = qemuMonitorJSONKeywordStringToJSON(drivestr, "type"); ++ if (!args) ++ goto cleanup; ++ ++ /* __com.redhat_drive_add rejects the 'if' key */ ++ virJSONValueObjectRemoveKey(args, "if", NULL); ++ ++ if (virJSONValueObjectAppend(cmd, "arguments", args) < 0) { ++ virReportOOMError(); ++ goto cleanup; ++ } ++ args = NULL; /* cmd owns reference to args now */ ++ ++ if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) ++ goto cleanup; ++ ++ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { ++ virJSONValueFree(cmd); ++ virJSONValueFree(reply); ++ cmd = reply = NULL; ++ ++ VIR_DEBUG("__com.redhat_drive_add command not found," ++ " trying upstream way"); ++ } else { ++ ret = qemuMonitorJSONCheckError(cmd, reply); ++ goto cleanup; ++ } ++ ++ /* Upstream approach */ ++ /* there won't be a direct replacement for drive_add in QMP */ ++ ret = qemuMonitorTextAddDrive(mon, drivestr); ++ ++ cleanup: ++ virJSONValueFree(args); ++ virJSONValueFree(cmd); ++ virJSONValueFree(reply); ++ return ret; ++} ++ ++ ++int qemuMonitorJSONDriveDel(qemuMonitorPtr mon, ++ const char *drivestr) ++{ ++ int ret; ++ virJSONValuePtr cmd; ++ virJSONValuePtr reply = NULL; ++ ++ VIR_DEBUG("drivestr=%s", drivestr); ++ cmd = qemuMonitorJSONMakeCommand("__com.redhat_drive_del", ++ "s:id", drivestr, ++ NULL); ++ if (!cmd) ++ return -1; ++ ++ if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) ++ goto cleanup; ++ ++ if (qemuMonitorJSONHasError(reply, "CommandNotFound")) { ++ virJSONValueFree(cmd); ++ virJSONValueFree(reply); ++ cmd = reply = NULL; ++ ++ VIR_DEBUG("__com.redhat_drive_del command not found," ++ " trying upstream way"); ++ } else if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) { ++ /* NB: device not found errors mean the drive was ++ * auto-deleted and we ignore the error */ ++ ret = 0; ++ goto cleanup; ++ } else { ++ ret = qemuMonitorJSONCheckError(cmd, reply); ++ goto cleanup; ++ } ++ ++ /* Upstream approach */ ++ /* there won't be a direct replacement for drive_del in QMP */ ++ if ((ret = qemuMonitorTextDriveDel(mon, drivestr)) < 0) { ++ virErrorPtr err = virGetLastError(); ++ if (err && err->code == VIR_ERR_OPERATION_UNSUPPORTED) { ++ VIR_ERROR("%s", ++ _("deleting disk is not supported. " ++ "This may leak data if disk is reassigned")); ++ ret = 1; ++ virResetLastError(); ++ } ++ } ++ ++ cleanup: ++ virJSONValueFree(cmd); ++ virJSONValueFree(reply); ++ return ret; ++} ++ ++ + int + qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions, + const char *device, const char *file, +diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h +index b92fc3762b..9c8fab7cc0 100644 +--- a/src/qemu/qemu_monitor_json.h ++++ b/src/qemu/qemu_monitor_json.h +@@ -238,6 +238,12 @@ int qemuMonitorJSONAddObject(qemuMonitorPtr mon, + int qemuMonitorJSONDelObject(qemuMonitorPtr mon, + const char *objalias); + ++int qemuMonitorJSONAddDrive(qemuMonitorPtr mon, ++ const char *drivestr); ++ ++int qemuMonitorJSONDriveDel(qemuMonitorPtr mon, ++ const char *drivestr); ++ + int qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, + virJSONValuePtr actions, + const char *device, +diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c +index 663e33ed00..cddedf768e 100644 +--- a/tests/qemuhotplugtest.c ++++ b/tests/qemuhotplugtest.c +@@ -665,6 +665,14 @@ mymain(void) + " }" \ + "}\r\n" + ++#define QMP_NOT_FOUND \ ++ "{" \ ++ " \"error\": {" \ ++ " \"class\": \"CommandNotFound\"," \ ++ " \"desc\": \"The command has not been found\"" \ ++ " }" \ ++ "}" ++ + DO_TEST_UPDATE("graphics-spice", "graphics-spice-nochange", false, false, NULL); + DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false, + "set_password", QMP_OK, "expire_password", QMP_OK); +@@ -685,67 +693,135 @@ mymain(void) + "chardev-remove", QMP_OK); + + DO_TEST_ATTACH("base-live", "disk-virtio", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-virtio", false, false, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + ++ DO_TEST_ATTACH("base-live", "disk-virtio", false, true, ++ "__com.redhat_drive_add", QMP_OK, ++ "device_add", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-virtio", false, false, ++ "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ + DO_TEST_ATTACH_EVENT("base-live", "disk-virtio", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-virtio", true, true, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("base-live", "disk-virtio", false, false, + "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + ++ DO_TEST_ATTACH_EVENT("base-live", "disk-virtio", false, true, ++ "__com.redhat_drive_add", QMP_OK, ++ "device_add", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-virtio", true, true, ++ "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-virtio", false, false, ++ "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ + DO_TEST_ATTACH("base-live", "disk-usb", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-usb", false, false, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + ++ DO_TEST_ATTACH("base-live", "disk-usb", false, true, ++ "__com.redhat_drive_add", QMP_OK, ++ "device_add", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-usb", false, false, ++ "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ + DO_TEST_ATTACH_EVENT("base-live", "disk-usb", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-usb", true, true, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("base-live", "disk-usb", false, false, + "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + ++ DO_TEST_ATTACH_EVENT("base-live", "disk-usb", false, true, ++ "__com.redhat_drive_add", QMP_OK, ++ "device_add", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-usb", true, true, ++ "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-usb", false, false, ++ "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ + DO_TEST_ATTACH("base-live", "disk-scsi", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-scsi", false, false, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + ++ DO_TEST_ATTACH("base-live", "disk-scsi", false, true, ++ "__com.redhat_drive_add", QMP_OK, ++ "device_add", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-scsi", false, false, ++ "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ + DO_TEST_ATTACH_EVENT("base-live", "disk-scsi", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-scsi", true, true, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("base-live", "disk-scsi", false, false, + "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + ++ DO_TEST_ATTACH_EVENT("base-live", "disk-scsi", false, true, ++ "__com.redhat_drive_add", QMP_OK, ++ "device_add", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-scsi", true, true, ++ "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ DO_TEST_DETACH("base-live", "disk-scsi", false, false, ++ "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK, ++ "__com.redhat_drive_del", QMP_OK); ++ + DO_TEST_ATTACH("base-without-scsi-controller-live", "disk-scsi-2", false, true, + /* Four controllers added */ + "device_add", QMP_OK, + "device_add", QMP_OK, + "device_add", QMP_OK, + "device_add", QMP_OK, +- "human-monitor-command", HMP("OK\\r\\n"), + /* Disk added */ ++ "__com.redhat_drive_add", QMP_NOT_FOUND, ++ "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", false, false, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_EVENT("base-without-scsi-controller-live", "disk-scsi-2", false, true, +@@ -754,14 +830,17 @@ mymain(void) + "device_add", QMP_OK, + "device_add", QMP_OK, + "device_add", QMP_OK, +- "human-monitor-command", HMP("OK\\r\\n"), + /* Disk added */ ++ "__com.redhat_drive_add", QMP_NOT_FOUND, ++ "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", true, true, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", false, false, + "device_del", QMP_DEVICE_DELETED("scsi3-0-5-7") QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH("base-live", "qemu-agent", false, true, +@@ -772,38 +851,47 @@ mymain(void) + "chardev-remove", QMP_OK); + + DO_TEST_ATTACH("base-ccw-live", "ccw-virtio", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-ccw-live", "ccw-virtio", false, false, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + + DO_TEST_DETACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, false, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + + DO_TEST_DETACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, false, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + + /* Attach a second device, then detach the first one. Then attach the first one again. */ + DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + + DO_TEST_DETACH("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-explicit", false, true, + "device_del", QMP_OK, ++ "__com.redhat_drive_del", QMP_NOT_FOUND, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-reverse", false, false, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + +@@ -821,6 +909,7 @@ mymain(void) + "object-del", QMP_OK); + DO_TEST_ATTACH("base-live+disk-scsi-wwn", + "disk-scsi-duplicate-wwn", false, false, ++ "__com.redhat_drive_add", QMP_NOT_FOUND, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + +-- +2.18.0 + diff --git a/SOURCES/libvirt-RHEL-conf-storage-Fix-a-memory-leak-in-virStoragePoolDefParseSource.patch b/SOURCES/libvirt-RHEL-conf-storage-Fix-a-memory-leak-in-virStoragePoolDefParseSource.patch new file mode 100644 index 0000000..d4580a0 --- /dev/null +++ b/SOURCES/libvirt-RHEL-conf-storage-Fix-a-memory-leak-in-virStoragePoolDefParseSource.patch @@ -0,0 +1,41 @@ +From b5f39d1ad467ab712d41f693f998c6a9e3046b4f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Erik Skultety +Date: Wed, 10 Apr 2019 10:25:01 +0200 +Subject: [PATCH] RHEL: conf: storage: Fix a memory leak in + virStoragePoolDefParseSource +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1584663 + +RHEL-only + +Commit acf8c561 backported an upstream memory leak in @ver variable that +was later fixed upstream by using AUTOFREE which is not available +downstream, so we need a downstream fix. The issue was reported by +coverity. + +Signed-off-by: Erik Skultety +Message-Id: +Reviewed-by: Ján Tomko +--- + src/conf/storage_conf.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c +index 5a124a0a2f..e171425239 100644 +--- a/src/conf/storage_conf.c ++++ b/src/conf/storage_conf.c +@@ -566,6 +566,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, + cleanup: + ctxt->node = relnode; + ++ VIR_FREE(ver); + VIR_FREE(port); + VIR_FREE(nodeset); + virStorageAuthDefFree(authdef); +-- +2.21.0 + diff --git a/SOURCES/libvirt-RHEL-cpu-Add-downstream-only-CPU-features-for-CVE-2017-5715.patch b/SOURCES/libvirt-RHEL-cpu-Add-downstream-only-CPU-features-for-CVE-2017-5715.patch new file mode 100644 index 0000000..61e6655 --- /dev/null +++ b/SOURCES/libvirt-RHEL-cpu-Add-downstream-only-CPU-features-for-CVE-2017-5715.patch @@ -0,0 +1,194 @@ +From 5d335dc7f64e2bd394c1bf86c6e5582fd859857a Mon Sep 17 00:00:00 2001 +Message-Id: <5d335dc7f64e2bd394c1bf86c6e5582fd859857a@dist-git> +From: Paolo Bonzini +Date: Tue, 12 Dec 2017 16:23:42 +0100 +Subject: [PATCH] RHEL: cpu: Add downstream only CPU features for CVE-2017-5715 + +RHEL-only: The downstream patches for CVE-2017-5715 contained more CPU +features than what was eventually pushed upstream. We need to keep them +included for backward compatibility. + +Signed-off-by: Paolo Bonzini +Signed-off-by: Jiri Denemark +--- + src/cpu/cpu_map.xml | 6 ++++++ + .../x86_64-cpuid-Core-i7-5600U-ibrs-disabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-host.xml | 1 + + tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-disabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-host.xml | 1 + + tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-disabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-host.xml | 1 + + tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-disabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-host.xml | 1 + + 13 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 96daa0f9af..f1f8048c14 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -298,6 +298,12 @@ + + + ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-disabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-disabled.xml +index e033bb141f..5c9cfa9bd6 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-disabled.xml +@@ -1,6 +1,6 @@ + + + +- ++ + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-guest.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-guest.xml +index a70cb6d46a..538bfe16ab 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-guest.xml +@@ -22,6 +22,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-host.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-host.xml +index b8e3399103..004423ee57 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs-host.xml +@@ -23,6 +23,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-disabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-disabled.xml +index aacc7a2b14..ec299652f7 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-disabled.xml +@@ -1,6 +1,6 @@ + + + +- ++ + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-guest.xml +index a66c7a5644..d8aaaad29d 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-guest.xml +@@ -24,6 +24,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-host.xml +index 624d71db20..9bac4b4648 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3-host.xml +@@ -25,6 +25,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-disabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-disabled.xml +index d904808cec..85369d755c 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-disabled.xml +@@ -1,7 +1,7 @@ + + + +- ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-guest.xml +index 60609f5c70..d4f303ecce 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-guest.xml +@@ -20,6 +20,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-host.xml +index 357cafd10a..60a7a9339d 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-host.xml +@@ -25,6 +25,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-disabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-disabled.xml +index b5c70a9dc4..a5b85a15c2 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-disabled.xml +@@ -1,7 +1,7 @@ + + + +- ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-guest.xml +index 5f51dea631..64b69dea56 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-guest.xml +@@ -22,6 +22,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-host.xml +index a11b31369d..00e8da7512 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115-host.xml +@@ -23,6 +23,7 @@ + + + ++ + + + +-- +2.18.0 + diff --git a/SOURCES/libvirt-RHEL-cpu_map-Mark-arch-facilities-feature-as-non-migratable.patch b/SOURCES/libvirt-RHEL-cpu_map-Mark-arch-facilities-feature-as-non-migratable.patch new file mode 100644 index 0000000..ddd3d48 --- /dev/null +++ b/SOURCES/libvirt-RHEL-cpu_map-Mark-arch-facilities-feature-as-non-migratable.patch @@ -0,0 +1,43 @@ +From ead15fe7a0cd60eb91ff7744b24af15b6c122239 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Wed, 9 Jan 2019 15:39:49 +0100 +Subject: [PATCH] RHEL: cpu_map: Mark arch-facilities feature as non-migratable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RHEL-only + +The arch-facilities feature, which was added only in RHEL, is not +migratable and thus it should not be included in host-model features. + +The feature was introduced as arch-capabilities upstream in QEMU 3.1.0, +which is later than QEMU 2.10, where we started probing what features +cannot be migrated, so we don't need to add this cpu_map hack there. + +https://bugzilla.redhat.com/show_bug.cgi?id=1658406 +https://bugzilla.redhat.com/show_bug.cgi?id=1664793 + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index f1f8048c14..9d53d4b43a 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -301,7 +301,7 @@ + + + +- ++ + + + +-- +2.21.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..f741d2f --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Add-ability-to-set-sgio-values-for-hostdev.patch @@ -0,0 +1,72 @@ +From f2cf0ae7bc371c75f6c0e79192711f2b1d201b10 Mon Sep 17 00:00:00 2001 +Message-Id: +From: John Ferlan +Date: Thu, 9 Jul 2015 08:28:57 -0400 +Subject: [PATCH] RHEL: qemu: Add ability to set sgio values for hostdev + +https://bugzilla.redhat.com/show_bug.cgi?id=1072736 + +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 +--- + 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.18.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..c299cd8 --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Add-check-for-unpriv-sgio-for-SCSI-generic-host-device.patch @@ -0,0 +1,59 @@ +From 712005bcf26190dc6fd1fe56283377987909cc4b Mon Sep 17 00:00:00 2001 +Message-Id: <712005bcf26190dc6fd1fe56283377987909cc4b@dist-git> +From: John Ferlan +Date: Thu, 9 Jul 2015 08:28:58 -0400 +Subject: [PATCH] RHEL: qemu: Add check for unpriv sgio for SCSI generic host + device + +https://bugzilla.redhat.com/show_bug.cgi?id=1072736 + +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 +--- + 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.18.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..aa40c07 --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Alter-qemuSetUnprivSGIO-hostdev-shareable-logic.patch @@ -0,0 +1,52 @@ +From 5b24ffe0ec9bd2fb18d26e6261b84556097067b7 Mon Sep 17 00:00:00 2001 +Message-Id: <5b24ffe0ec9bd2fb18d26e6261b84556097067b7@dist-git> +From: John Ferlan +Date: Wed, 5 Dec 2018 08:49:31 -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=1656360 + +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 de0cbca083..5971f3eb64 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -1667,9 +1667,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))) + goto cleanup; + +@@ -1686,7 +1683,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.21.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..07082ba --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Alter-val-usage-in-qemuSetUnprivSGIO.patch @@ -0,0 +1,59 @@ +From 6764c4c345ba0ce1f60adab7958441279c3f4913 Mon Sep 17 00:00:00 2001 +Message-Id: <6764c4c345ba0ce1f60adab7958441279c3f4913@dist-git> +From: John Ferlan +Date: Wed, 5 Dec 2018 08:49:30 -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=1656360 + +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 7d15af9c0b..de0cbca083 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -1650,7 +1650,7 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) + char *sysfs_path = NULL; + char *hostdev_path = NULL; + const char *path = NULL; +- int val = -1; ++ int val = 0; + int ret = -1; + + /* "sgio" is only valid for block disk; cdrom +@@ -1682,11 +1682,14 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) + goto cleanup; + + /* 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.21.0 + diff --git a/SOURCES/libvirt-RHEL-qemu-Support-vhost-user-multiqueue-with-QEMU-2.3.patch b/SOURCES/libvirt-RHEL-qemu-Support-vhost-user-multiqueue-with-QEMU-2.3.patch new file mode 100644 index 0000000..908653f --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-Support-vhost-user-multiqueue-with-QEMU-2.3.patch @@ -0,0 +1,38 @@ +From 1a2abd15b50c99659fe850673d95a2edd75f19a1 Mon Sep 17 00:00:00 2001 +Message-Id: <1a2abd15b50c99659fe850673d95a2edd75f19a1@dist-git> +From: Martin Kletzander +Date: Mon, 23 Nov 2015 12:46:36 +0100 +Subject: [PATCH] RHEL: qemu: Support vhost-user-multiqueue with QEMU 2.3 + +RHEL-only + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1207692 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1284416 + +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_capabilities.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 0d79780f25..fc1cf53066 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -4000,8 +4000,11 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, + virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_AARCH64_OFF); + + /* vhost-user supports multi-queue from v2.4.0 onwards, +- * but there is no way to query for that capability */ +- if (qemuCaps->version >= 2004000) ++ * but there is no way to query for that capability ++ * ++ * RHEL-only: The change was back-ported to earlier QEMU version, ++ * particularly 2.3, in BZ 1276100 */ ++ if (qemuCaps->version >= 2003000) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE); + + /* smm option is supported from v2.4.0 */ +-- +2.18.0 + diff --git a/SOURCES/libvirt-RHEL-qemu-support-relative-backing-for-RHEL-7.0.z-qemu.patch b/SOURCES/libvirt-RHEL-qemu-support-relative-backing-for-RHEL-7.0.z-qemu.patch new file mode 100644 index 0000000..ef405b0 --- /dev/null +++ b/SOURCES/libvirt-RHEL-qemu-support-relative-backing-for-RHEL-7.0.z-qemu.patch @@ -0,0 +1,41 @@ +From b9b227314c5736ad310c6b323f0adf0d9165e4d3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Eric Blake +Date: Tue, 7 Oct 2014 17:06:17 -0600 +Subject: [PATCH] RHEL: qemu: support relative backing for RHEL 7.0.z qemu + +RHEL-only: https://bugzilla.redhat.com/show_bug.cgi?id=1150322 + +qemu-kvm-rhev for RHEL 7.0.z backported enough code to allow +relative backing file manipulations, but could not backport +everything from upstream. So, instead of providing the upstream +'change-backing-file' QMP command, it added a downstream-only +'__com.redhat_change-backing-file' as a witness that relative +backing is supported, but not as full-featured. Since libvirt +from RHEL 7.1 may be driving an older qemu, we need to be able +to recognize the alternate spelling. + +* src/qemu/qemu_capabilities.c (virQEMUCapsCommands): Also +recognize downstream spelling. + +Signed-off-by: Eric Blake +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_capabilities.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 37c8fbe3d3..0d79780f25 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -1006,6 +1006,7 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = { + { "add-fd", QEMU_CAPS_ADD_FD }, + { "nbd-server-start", QEMU_CAPS_NBD_SERVER }, + { "change-backing-file", QEMU_CAPS_CHANGE_BACKING_FILE }, ++ { "__com.redhat_change-backing-file", QEMU_CAPS_CHANGE_BACKING_FILE }, + { "rtc-reset-reinjection", QEMU_CAPS_RTC_RESET_REINJECTION }, + { "migrate-incoming", QEMU_CAPS_INCOMING_DEFER }, + { "query-hotpluggable-cpus", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS }, +-- +2.18.0 + diff --git a/SOURCES/libvirt-RHEL-screenshot-Implement-multiple-screen-support.patch b/SOURCES/libvirt-RHEL-screenshot-Implement-multiple-screen-support.patch new file mode 100644 index 0000000..e9b67c4 --- /dev/null +++ b/SOURCES/libvirt-RHEL-screenshot-Implement-multiple-screen-support.patch @@ -0,0 +1,171 @@ +From 6019d375ba10735d805801fb0ecee71e4a32871c Mon Sep 17 00:00:00 2001 +Message-Id: <6019d375ba10735d805801fb0ecee71e4a32871c@dist-git> +From: Michal Privoznik +Date: Fri, 26 Aug 2011 16:41:17 +0800 +Subject: [PATCH] RHEL: screenshot: Implement multiple screen support + +For https://bugzilla.redhat.com/show_bug.cgi?id=1026966 + https://bugzilla.redhat.com/show_bug.cgi?id=710489 +RHEL only, requires __com.redhat_qxl_screendump + +As RHEL qemu supports taking screenshot of other monitors than the +first one, we can allow libvirt to support this feature too. + +Although this command allows screen specification via ID, there is +not a way to assign one to the primary monitor. Therefore, we must +stick to upstream command in case of primary monitor, and use this +new command in other cases. + +(cherry picked from commit 800c9b2c1e0347585213ba6895db7cf064cda21c in +rhel-6.5 branch) + +Signed-off-by: Jiri Denemark + +Conflicts: + src/qemu/qemu_driver.c - context + src/qemu/qemu_monitor.c - don't return -1 without reporting an + error +--- + src/qemu/qemu_driver.c | 20 +++++++++----------- + src/qemu/qemu_monitor.c | 13 +++++++++++++ + src/qemu/qemu_monitor.h | 3 +++ + src/qemu/qemu_monitor_json.c | 24 ++++++++++++++++++++++++ + src/qemu/qemu_monitor_json.h | 4 ++++ + 5 files changed, 53 insertions(+), 11 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 825b2b27e6..00952a55e7 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -3996,6 +3996,7 @@ qemuDomainScreenshot(virDomainPtr dom, + char *ret = NULL; + bool unlink_tmp = false; + virQEMUDriverConfigPtr cfg = NULL; ++ int rc; + + virCheckFlags(0, NULL); + +@@ -4021,12 +4022,6 @@ qemuDomainScreenshot(virDomainPtr dom, + } + + if (screen) { +- if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SCREENDUMP_DEVICE)) { +- virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", +- _("qemu does not allow specifying screen ID")); +- goto endjob; +- } +- + for (i = 0; i < vm->def->nvideos; i++) { + const virDomainVideoDef *video = vm->def->videos[i]; + +@@ -4057,11 +4052,14 @@ qemuDomainScreenshot(virDomainPtr dom, + qemuSecuritySetSavedStateLabel(driver->securityManager, vm->def, tmp); + + qemuDomainObjEnterMonitor(driver, vm); +- if (qemuMonitorScreendump(priv->mon, videoAlias, screen, tmp) < 0) { +- ignore_value(qemuDomainObjExitMonitor(driver, vm)); +- goto endjob; +- } +- if (qemuDomainObjExitMonitor(driver, vm) < 0) ++ ++ if (!videoAlias || ++ virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SCREENDUMP_DEVICE)) ++ rc = qemuMonitorScreendump(priv->mon, videoAlias, screen, tmp); ++ else ++ rc = qemuMonitorScreendumpRH(priv->mon, videoAlias, tmp); ++ ++ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + goto endjob; + + if (VIR_CLOSE(tmp_fd) < 0) { +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 6ed475ede0..6fc038a8d9 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -3340,6 +3340,19 @@ qemuMonitorSendKey(qemuMonitorPtr mon, + } + + ++int ++qemuMonitorScreendumpRH(qemuMonitorPtr mon, ++ const char *device, ++ const char *file) ++{ ++ VIR_DEBUG("device=%s, file=%s", device, file); ++ ++ QEMU_CHECK_MONITOR(mon); ++ ++ return qemuMonitorJSONScreendumpRH(mon, device, file); ++} ++ ++ + int + qemuMonitorScreendump(qemuMonitorPtr mon, + const char *device, +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index b3d62324b4..f4d8225ca5 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -878,6 +878,9 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, + + int qemuMonitorInjectNMI(qemuMonitorPtr mon); + ++int qemuMonitorScreendumpRH(qemuMonitorPtr mon, ++ const char *device, ++ const char *file); + int qemuMonitorScreendump(qemuMonitorPtr mon, + const char *device, + unsigned int head, +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 3e90279b71..af754e870e 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -4481,6 +4481,30 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon, + return ret; + } + ++int qemuMonitorJSONScreendumpRH(qemuMonitorPtr mon, ++ const char *id, ++ const char *file) ++{ ++ int ret = -1; ++ virJSONValuePtr cmd, reply = NULL; ++ ++ cmd = qemuMonitorJSONMakeCommand("__com.redhat_qxl_screendump", ++ "s:filename", file, ++ "s:id", id, ++ NULL); ++ if (!cmd) ++ return -1; ++ ++ ret = qemuMonitorJSONCommand(mon, cmd, &reply); ++ ++ if (ret == 0) ++ ret = qemuMonitorJSONCheckError(cmd, reply); ++ ++ virJSONValueFree(cmd); ++ virJSONValueFree(reply); ++ return ret; ++} ++ + int qemuMonitorJSONScreendump(qemuMonitorPtr mon, + const char *device, + unsigned int head, +diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h +index 6bc0dd3ad2..b92fc3762b 100644 +--- a/src/qemu/qemu_monitor_json.h ++++ b/src/qemu/qemu_monitor_json.h +@@ -297,6 +297,10 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon, + unsigned int *keycodes, + unsigned int nkeycodes); + ++int qemuMonitorJSONScreendumpRH(qemuMonitorPtr mon, ++ const char *id, ++ const char *file); ++ + int qemuMonitorJSONScreendump(qemuMonitorPtr mon, + const char *device, + unsigned int head, +-- +2.18.0 + 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..6e296c0 --- /dev/null +++ b/SOURCES/libvirt-access-Fix-nwfilter-binding-ACL-access-API-name-generation.patch @@ -0,0 +1,60 @@ +From 99968171f09ae0f374b5e9c961032ffa6bd4dd11 Mon Sep 17 00:00:00 2001 +Message-Id: <99968171f09ae0f374b5e9c961032ffa6bd4dd11@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..089ebf9 --- /dev/null +++ b/SOURCES/libvirt-access-Modify-the-VIR_ERR_ACCESS_DENIED-to-include-driverName.patch @@ -0,0 +1,159 @@ +From c7d644f205a64175961218c82f764cdd10766bff Mon Sep 17 00:00:00 2001 +Message-Id: +From: John Ferlan +Date: Wed, 3 Apr 2019 07:22:20 -0400 +Subject: [PATCH] access: Modify the VIR_ERR_ACCESS_DENIED to include + driverName + +https://bugzilla.redhat.com/show_bug.cgi?id=1631606 + +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) +Message-Id: <20190403112220.23881-1-jferlan@redhat.com> +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.21.0 + diff --git a/SOURCES/libvirt-admin-reject-clients-unless-their-UID-matches-the-current-UID.patch b/SOURCES/libvirt-admin-reject-clients-unless-their-UID-matches-the-current-UID.patch new file mode 100644 index 0000000..8ab6861 --- /dev/null +++ b/SOURCES/libvirt-admin-reject-clients-unless-their-UID-matches-the-current-UID.patch @@ -0,0 +1,61 @@ +From 0abfa9e0b0b396420a165ac90e69952b23b5ca3e Mon Sep 17 00:00:00 2001 +Message-Id: <0abfa9e0b0b396420a165ac90e69952b23b5ca3e@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 15 May 2019 21:40:56 +0100 +Subject: [PATCH] admin: reject clients unless their UID matches the current + UID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The admin protocol RPC messages are only intended for use by the user +running the daemon. As such they should not be allowed for any client +UID that does not match the server UID. + +Fixes CVE-2019-10132 + +Reviewed-by: Ján Tomko +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 96f41cd765c9e525fe28ee5abbfbf4a79b3720c7) +Reviewed-by: Jiri Denemark +Message-Id: <20190515204058.28077-2-berrange@redhat.com> +--- + src/admin/admin_server_dispatch.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/src/admin/admin_server_dispatch.c b/src/admin/admin_server_dispatch.c +index b78ff902c0..9f25813ae3 100644 +--- a/src/admin/admin_server_dispatch.c ++++ b/src/admin/admin_server_dispatch.c +@@ -66,6 +66,28 @@ remoteAdmClientNew(virNetServerClientPtr client ATTRIBUTE_UNUSED, + void *opaque) + { + struct daemonAdmClientPrivate *priv; ++ uid_t clientuid; ++ gid_t clientgid; ++ pid_t clientpid; ++ unsigned long long timestamp; ++ ++ if (virNetServerClientGetUNIXIdentity(client, ++ &clientuid, ++ &clientgid, ++ &clientpid, ++ ×tamp) < 0) ++ return NULL; ++ ++ VIR_DEBUG("New client pid %lld uid %lld", ++ (long long)clientpid, ++ (long long)clientuid); ++ ++ if (geteuid() != clientuid) { ++ virReportRestrictedError(_("Disallowing client %lld with uid %lld"), ++ (long long)clientpid, ++ (long long)clientuid); ++ return NULL; ++ } + + if (VIR_ALLOC(priv) < 0) + return NULL; +-- +2.21.0 + diff --git a/SOURCES/libvirt-api-disallow-virConnect-HypervisorCPU-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virConnect-HypervisorCPU-on-read-only-connections.patch new file mode 100644 index 0000000..bf8786e --- /dev/null +++ b/SOURCES/libvirt-api-disallow-virConnect-HypervisorCPU-on-read-only-connections.patch @@ -0,0 +1,46 @@ +From f97144b76b3452e69c14834d1ecc69dbf802ac12 Mon Sep 17 00:00:00 2001 +Message-Id: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 18 Jun 2019 13:30:02 +0200 +Subject: [PATCH] api: disallow virConnect*HypervisorCPU on read-only + connections +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These APIs can be used to execute arbitrary emulators. +Forbid them on read-only connections. + +Fixes: CVE-2019-10168 +Signed-off-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Ján Tomko +Message-Id: <470651092e7d6a4ba5875cf8885fd3714d5ea189.1560857354.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/libvirt-host.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/libvirt-host.c b/src/libvirt-host.c +index e20d6ee250..2978825d22 100644 +--- a/src/libvirt-host.c ++++ b/src/libvirt-host.c +@@ -1041,6 +1041,7 @@ virConnectCompareHypervisorCPU(virConnectPtr conn, + + virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR); + virCheckNonNullArgGoto(xmlCPU, error); ++ virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->connectCompareHypervisorCPU) { + int ret; +@@ -1234,6 +1235,7 @@ virConnectBaselineHypervisorCPU(virConnectPtr conn, + + virCheckConnectReturn(conn, NULL); + virCheckNonNullArgGoto(xmlCPUs, error); ++ virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->connectBaselineHypervisorCPU) { + char *cpu; +-- +2.22.0 + diff --git a/SOURCES/libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch new file mode 100644 index 0000000..672dd0f --- /dev/null +++ b/SOURCES/libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch @@ -0,0 +1,38 @@ +From fae17c4141d504073e9cb16b49d2af9e73272ac2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 18 Jun 2019 13:30:01 +0200 +Subject: [PATCH] api: disallow virConnectGetDomainCapabilities on read-only + connections +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This API can be used to execute arbitrary emulators. +Forbid it on read-only connections. + +Fixes: CVE-2019-10167 +Signed-off-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Ján Tomko +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/libvirt-domain.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index b936dd8eb7..ab2c44cfe1 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -11287,6 +11287,7 @@ virConnectGetDomainCapabilities(virConnectPtr conn, + virResetLastError(); + + virCheckConnectReturn(conn, NULL); ++ virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->connectGetDomainCapabilities) { + char *ret; +-- +2.22.0 + diff --git a/SOURCES/libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch new file mode 100644 index 0000000..6cd6db1 --- /dev/null +++ b/SOURCES/libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch @@ -0,0 +1,40 @@ +From 20a2fc74e717ca21e1a183b4e210872eb0c56be9 Mon Sep 17 00:00:00 2001 +Message-Id: <20a2fc74e717ca21e1a183b4e210872eb0c56be9@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 18 Jun 2019 13:30:00 +0200 +Subject: [PATCH] api: disallow virDomainManagedSaveDefineXML on read-only + connections +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virDomainManagedSaveDefineXML can be used to alter the domain's +config used for managedsave or even execute arbitrary emulator binaries. +Forbid it on read-only connections. + +Fixes: CVE-2019-10166 +Reported-by: Matthias Gerstner +Signed-off-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Ján Tomko +Message-Id: <352bf5e963a6482d426f97b0ef36ca019e69280b.1560857354.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/libvirt-domain.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 697326ae9a..b936dd8eb7 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -9495,6 +9495,7 @@ virDomainManagedSaveDefineXML(virDomainPtr domain, const char *dxml, + + virCheckDomainReturn(domain, -1); + conn = domain->conn; ++ virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainManagedSaveDefineXML) { + int ret; +-- +2.22.0 + diff --git a/SOURCES/libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch new file mode 100644 index 0000000..7653e1f --- /dev/null +++ b/SOURCES/libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch @@ -0,0 +1,98 @@ +From 2e532b74b3100a06e0f1ba21f657883fe5aafcc5 Mon Sep 17 00:00:00 2001 +Message-Id: <2e532b74b3100a06e0f1ba21f657883fe5aafcc5@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 18 Jun 2019 13:29:59 +0200 +Subject: [PATCH] api: disallow virDomainSaveImageGetXMLDesc on read-only + connections +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virDomainSaveImageGetXMLDesc API is taking a path parameter, +which can point to any path on the system. This file will then be +read and parsed by libvirtd running with root privileges. + +Forbid it on read-only connections. + +Fixes: CVE-2019-10161 +Reported-by: Matthias Gerstner +Signed-off-by: Ján Tomko +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Ján Tomko + +Conflicts: + src/libvirt-domain.c + src/remote/remote_protocol.x + +Upstream commit 12a51f372 which introduced the VIR_DOMAIN_SAVE_IMAGE_XML_SECURE +alias for VIR_DOMAIN_XML_SECURE is not backported. +Just skip the commit since we now disallow the whole API on read-only +connections, regardless of the flag. +Message-Id: <4c14d609cd7b548459b9ef2f59728fa5c5e38268.1560857354.git.jtomko@redhat.com> + +Reviewed-by: Jiri Denemark +--- + src/libvirt-domain.c | 11 ++--------- + src/qemu/qemu_driver.c | 2 +- + src/remote/remote_protocol.x | 3 +-- + 3 files changed, 4 insertions(+), 12 deletions(-) + +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 568023176b..697326ae9a 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -1073,9 +1073,7 @@ virDomainRestoreFlags(virConnectPtr conn, const char *from, const char *dxml, + * previously by virDomainSave() or virDomainSaveFlags(). + * + * No security-sensitive data will be included unless @flags contains +- * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only +- * connections. For this API, @flags should not contain either +- * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU. ++ * VIR_DOMAIN_XML_SECURE. + * + * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of + * error. The caller must free() the returned value. +@@ -1091,12 +1089,7 @@ virDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *file, + + virCheckConnectReturn(conn, NULL); + virCheckNonNullArgGoto(file, error); +- +- if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) { +- virReportError(VIR_ERR_OPERATION_DENIED, "%s", +- _("virDomainSaveImageGetXMLDesc with secure flag")); +- goto error; +- } ++ virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainSaveImageGetXMLDesc) { + char *ret; +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 704ba24215..25818f5d8c 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -6784,7 +6784,7 @@ qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path, + if (fd < 0) + goto cleanup; + +- if (virDomainSaveImageGetXMLDescEnsureACL(conn, def, flags) < 0) ++ if (virDomainSaveImageGetXMLDescEnsureACL(conn, def) < 0) + goto cleanup; + + ret = qemuDomainDefFormatXML(driver, def, flags); +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index 28c8febabd..52b92334fa 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -5226,8 +5226,7 @@ enum remote_procedure { + /** + * @generate: both + * @priority: high +- * @acl: domain:read +- * @acl: domain:read_secure:VIR_DOMAIN_XML_SECURE ++ * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_SAVE_IMAGE_GET_XML_DESC = 235, + +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-Add-memory-bandwidth-allocation-capability-of-host.patch b/SOURCES/libvirt-conf-Add-memory-bandwidth-allocation-capability-of-host.patch new file mode 100644 index 0000000..bf92ee0 --- /dev/null +++ b/SOURCES/libvirt-conf-Add-memory-bandwidth-allocation-capability-of-host.patch @@ -0,0 +1,397 @@ +From a7292e2be3fef0c14d5393120471b1dc5d7a5adb Mon Sep 17 00:00:00 2001 +Message-Id: +From: Bing Niu +Date: Mon, 15 Apr 2019 17:33:00 +0200 +Subject: [PATCH] conf: Add memory bandwidth allocation capability of host +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add new XML section to report host's memory bandwidth allocation +capability. The format as below example: + + + ..... + + + + + + + +granularity ---- granularity of memory bandwidth, unit percentage. +min ---- minimum memory bandwidth allowed, unit percentage. +maxAllocs ---- maximum memory bandwidth allocation group supported. + +Signed-off-by: Bing Niu +Reviewed-by: John Ferlan +(cherry picked from commit 7995fecc25c6bc8d0ebb243ea2c8765b076c8974) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + docs/schemas/capability.rng | 33 ++++++ + src/conf/capabilities.c | 107 ++++++++++++++++++ + src/conf/capabilities.h | 11 ++ + src/util/virresctrl.c | 20 ++++ + src/util/virresctrl.h | 15 +++ + .../resctrl/info/MB/bandwidth_gran | 1 + + .../resctrl/info/MB/min_bandwidth | 1 + + .../linux-resctrl/resctrl/info/MB/num_closids | 1 + + .../vircaps-x86_64-resctrl.xml | 8 ++ + tests/virresctrldata/resctrl.schemata | 1 + + 10 files changed, 198 insertions(+) + create mode 100644 tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/bandwidth_gran + create mode 100644 tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/min_bandwidth + create mode 100644 tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/num_closids + +diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng +index 52164d5ecb..d61515ccbe 100644 +--- a/docs/schemas/capability.rng ++++ b/docs/schemas/capability.rng +@@ -51,6 +51,9 @@ + + + ++ ++ ++ + + + +@@ -326,6 +329,36 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c +index 7a810efa66..3d893447cb 100644 +--- a/src/conf/capabilities.c ++++ b/src/conf/capabilities.c +@@ -197,6 +197,16 @@ virCapabilitiesFreeNUMAInfo(virCapsPtr caps) + caps->host.nnumaCell = 0; + } + ++static void ++virCapsHostMemBWNodeFree(virCapsHostMemBWNodePtr ptr) ++{ ++ if (!ptr) ++ return; ++ ++ virBitmapFree(ptr->cpus); ++ VIR_FREE(ptr); ++} ++ + static void + virCapabilitiesClearSecModel(virCapsHostSecModelPtr secmodel) + { +@@ -239,6 +249,10 @@ virCapsDispose(void *object) + virCapsHostCacheBankFree(caps->host.caches[i]); + VIR_FREE(caps->host.caches); + ++ for (i = 0; i < caps->host.nnodes; i++) ++ virCapsHostMemBWNodeFree(caps->host.nodes[i]); ++ VIR_FREE(caps->host.nodes); ++ + VIR_FREE(caps->host.netprefix); + VIR_FREE(caps->host.pagesSize); + virCPUDefFree(caps->host.cpu); +@@ -957,6 +971,58 @@ virCapabilitiesFormatCaches(virBufferPtr buf, + return 0; + } + ++static int ++virCapabilitiesFormatMemoryBandwidth(virBufferPtr buf, ++ size_t nnodes, ++ virCapsHostMemBWNodePtr *nodes) ++{ ++ size_t i = 0; ++ virBuffer controlBuf = VIR_BUFFER_INITIALIZER; ++ ++ if (!nnodes) ++ return 0; ++ ++ virBufferAddLit(buf, "\n"); ++ virBufferAdjustIndent(buf, 2); ++ ++ for (i = 0; i < nnodes; i++) { ++ virCapsHostMemBWNodePtr node = nodes[i]; ++ virResctrlInfoMemBWPerNodePtr control = &node->control; ++ char *cpus_str = virBitmapFormat(node->cpus); ++ ++ if (!cpus_str) ++ return -1; ++ ++ virBufferAsprintf(buf, ++ "id, cpus_str); ++ VIR_FREE(cpus_str); ++ ++ virBufferSetChildIndent(&controlBuf, buf); ++ virBufferAsprintf(&controlBuf, ++ "\n", ++ control->granularity, control->min, ++ control->max_allocation); ++ ++ if (virBufferCheckError(&controlBuf) < 0) ++ return -1; ++ ++ if (virBufferUse(&controlBuf)) { ++ virBufferAddLit(buf, ">\n"); ++ virBufferAddBuffer(buf, &controlBuf); ++ virBufferAddLit(buf, "\n"); ++ } else { ++ virBufferAddLit(buf, "/>\n"); ++ } ++ } ++ ++ virBufferAdjustIndent(buf, -2); ++ virBufferAddLit(buf, "\n"); ++ ++ return 0; ++} ++ + /** + * virCapabilitiesFormatXML: + * @caps: capabilities to format +@@ -1060,6 +1126,10 @@ virCapabilitiesFormatXML(virCapsPtr caps) + caps->host.caches) < 0) + goto error; + ++ if (virCapabilitiesFormatMemoryBandwidth(&buf, caps->host.nnodes, ++ caps->host.nodes) < 0) ++ goto error; ++ + for (i = 0; i < caps->host.nsecModels; i++) { + virBufferAddLit(&buf, "\n"); + virBufferAdjustIndent(&buf, 2); +@@ -1602,6 +1672,40 @@ virCapabilitiesInitResctrl(virCapsPtr caps) + } + + ++static int ++virCapabilitiesInitResctrlMemory(virCapsPtr caps) ++{ ++ virCapsHostMemBWNodePtr node = NULL; ++ size_t i = 0; ++ int ret = -1; ++ ++ for (i = 0; i < caps->host.ncaches; i++) { ++ virCapsHostCacheBankPtr bank = caps->host.caches[i]; ++ if (VIR_ALLOC(node) < 0) ++ goto cleanup; ++ ++ if (virResctrlInfoGetMemoryBandwidth(caps->host.resctrl, ++ bank->level, &node->control) > 0) { ++ node->id = bank->id; ++ if (!(node->cpus = virBitmapNewCopy(bank->cpus))) ++ goto cleanup; ++ ++ if (VIR_APPEND_ELEMENT(caps->host.nodes, ++ caps->host.nnodes, node) < 0) { ++ goto cleanup; ++ } ++ } ++ virCapsHostMemBWNodeFree(node); ++ node = NULL; ++ } ++ ++ ret = 0; ++ cleanup: ++ virCapsHostMemBWNodeFree(node); ++ return ret; ++} ++ ++ + int + virCapabilitiesInitCaches(virCapsPtr caps) + { +@@ -1731,6 +1835,9 @@ virCapabilitiesInitCaches(virCapsPtr caps) + qsort(caps->host.caches, caps->host.ncaches, + sizeof(*caps->host.caches), virCapsHostCacheBankSorter); + ++ if (virCapabilitiesInitResctrlMemory(caps) < 0) ++ goto cleanup; ++ + ret = 0; + cleanup: + VIR_FREE(type); +diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h +index fe1b9ea455..046e275ac6 100644 +--- a/src/conf/capabilities.h ++++ b/src/conf/capabilities.h +@@ -151,6 +151,14 @@ struct _virCapsHostCacheBank { + virResctrlInfoPerCachePtr *controls; + }; + ++typedef struct _virCapsHostMemBWNode virCapsHostMemBWNode; ++typedef virCapsHostMemBWNode *virCapsHostMemBWNodePtr; ++struct _virCapsHostMemBWNode { ++ unsigned int id; ++ virBitmapPtr cpus; /* All CPUs that belong to this node*/ ++ virResctrlInfoMemBWPerNode control; ++}; ++ + typedef struct _virCapsHost virCapsHost; + typedef virCapsHost *virCapsHostPtr; + struct _virCapsHost { +@@ -175,6 +183,9 @@ struct _virCapsHost { + size_t ncaches; + virCapsHostCacheBankPtr *caches; + ++ size_t nnodes; ++ virCapsHostMemBWNodePtr *nodes; ++ + size_t nsecModels; + virCapsHostSecModelPtr secModels; + +diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c +index adf36a7c0a..4b5442f879 100644 +--- a/src/util/virresctrl.c ++++ b/src/util/virresctrl.c +@@ -629,6 +629,26 @@ virResctrlInfoIsEmpty(virResctrlInfoPtr resctrl) + } + + ++int ++virResctrlInfoGetMemoryBandwidth(virResctrlInfoPtr resctrl, ++ unsigned int level, ++ virResctrlInfoMemBWPerNodePtr control) ++{ ++ virResctrlInfoMemBWPtr membw_info = resctrl->membw_info; ++ ++ if (!membw_info) ++ return 0; ++ ++ if (membw_info->last_level_cache != level) ++ return 0; ++ ++ control->granularity = membw_info->bandwidth_granularity; ++ control->min = membw_info->min_bandwidth; ++ control->max_allocation = membw_info->max_allocation; ++ return 1; ++} ++ ++ + int + virResctrlInfoGetCache(virResctrlInfoPtr resctrl, + unsigned int level, +diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h +index 8d62517aa1..cfd56ddd06 100644 +--- a/src/util/virresctrl.h ++++ b/src/util/virresctrl.h +@@ -50,6 +50,17 @@ struct _virResctrlInfoPerCache { + unsigned int max_allocation; + }; + ++typedef struct _virResctrlInfoMemBWPerNode virResctrlInfoMemBWPerNode; ++typedef virResctrlInfoMemBWPerNode *virResctrlInfoMemBWPerNodePtr; ++struct _virResctrlInfoMemBWPerNode { ++ /* Smallest possible increase of the allocation bandwidth in percentage */ ++ unsigned int granularity; ++ /* Minimal allocatable bandwidth in percentage */ ++ unsigned int min; ++ /* Maximum number of simultaneous allocations */ ++ unsigned int max_allocation; ++}; ++ + typedef struct _virResctrlInfo virResctrlInfo; + typedef virResctrlInfo *virResctrlInfoPtr; + +@@ -63,6 +74,10 @@ virResctrlInfoGetCache(virResctrlInfoPtr resctrl, + size_t *ncontrols, + virResctrlInfoPerCachePtr **controls); + ++int ++virResctrlInfoGetMemoryBandwidth(virResctrlInfoPtr resctrl, ++ unsigned int level, ++ virResctrlInfoMemBWPerNodePtr control); + /* Alloc-related things */ + typedef struct _virResctrlAlloc virResctrlAlloc; + typedef virResctrlAlloc *virResctrlAllocPtr; +diff --git a/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/bandwidth_gran b/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/bandwidth_gran +new file mode 100644 +index 0000000000..f599e28b8a +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/bandwidth_gran +@@ -0,0 +1 @@ ++10 +diff --git a/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/min_bandwidth b/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/min_bandwidth +new file mode 100644 +index 0000000000..f599e28b8a +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/min_bandwidth +@@ -0,0 +1 @@ ++10 +diff --git a/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/num_closids b/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/num_closids +new file mode 100644 +index 0000000000..b8626c4cff +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/resctrl/info/MB/num_closids +@@ -0,0 +1 @@ ++4 +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml +index 4840614e86..9b00cf0995 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml +@@ -49,6 +49,14 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/virresctrldata/resctrl.schemata b/tests/virresctrldata/resctrl.schemata +index fa980e58c9..2578822b70 100644 +--- a/tests/virresctrldata/resctrl.schemata ++++ b/tests/virresctrldata/resctrl.schemata +@@ -1 +1,2 @@ + L3:0=000ff;1=000f0 ++MB:0=100;1=100 +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Add-optional-NFS-Source-Pool-protocol-ver-n-option.patch b/SOURCES/libvirt-conf-Add-optional-NFS-Source-Pool-protocol-ver-n-option.patch new file mode 100644 index 0000000..1be6b48 --- /dev/null +++ b/SOURCES/libvirt-conf-Add-optional-NFS-Source-Pool-protocol-ver-n-option.patch @@ -0,0 +1,213 @@ +From acf8c5619852146eed84123c7f432db925781511 Mon Sep 17 00:00:00 2001 +Message-Id: +From: John Ferlan +Date: Wed, 3 Apr 2019 10:58:19 -0400 +Subject: [PATCH] conf: Add optional NFS Source Pool option +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1584663 + +Add an optional way to define which NFS Server version will be +used to content the target NFS server. + +Signed-off-by: John Ferlan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 801f8cfb37f12007878df53332fdc03245a9d40d) +Message-Id: <20190403145819.4656-1-jferlan@redhat.com> +Reviewed-by: Ján Tomko +--- + docs/formatstorage.html.in | 16 ++++++++++++++ + docs/schemas/storagepool.rng | 7 ++++++ + src/conf/storage_conf.c | 22 +++++++++++++++++++ + src/conf/storage_conf.h | 3 +++ + .../pool-netfs-protocol-ver.xml | 21 ++++++++++++++++++ + .../pool-netfs-protocol-ver.xml | 21 ++++++++++++++++++ + tests/storagepoolxml2xmltest.c | 1 + + 7 files changed, 91 insertions(+) + create mode 100644 tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml + create mode 100644 tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml + +diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in +index b6bf3edbd2..b1b76a1dda 100644 +--- a/docs/formatstorage.html.in ++++ b/docs/formatstorage.html.in +@@ -121,6 +121,16 @@ + </source> + ... + ++
++...
++  <source>
++    <host name='localhost'/>
++    <dir path='/var/lib/libvirt/images'/>
++    <format type='nfs'/>
++    <protocol ver='3'/>
++  </source>
++...
++ +
+
device
+
Provides the source for pools backed by physical devices +@@ -386,6 +396,12 @@ + LVM metadata type. All drivers are required to have a default + value for this, so it is optional. Since 0.4.1
+ ++
protocol
++
For a netfs Storage Pool provide a mechanism to ++ define which NFS protocol version number will be used to contact ++ the server's NFS service. The attribute ver accepts ++ an unsigned integer as the version number to use. ++ Since 5.1.0
+
vendor
+
Provides optional information about the vendor of the + storage device. This contains a single +diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng +index 52b2044bef..0cb8beb926 100644 +--- a/docs/schemas/storagepool.rng ++++ b/docs/schemas/storagepool.rng +@@ -520,6 +520,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c +index 5036ab9ef8..5a124a0a2f 100644 +--- a/src/conf/storage_conf.c ++++ b/src/conf/storage_conf.c +@@ -415,6 +415,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, + virStorageAuthDefPtr authdef = NULL; + char *name = NULL; + char *port = NULL; ++ char *ver = NULL; + int n; + + relnode = ctxt->node; +@@ -540,6 +541,24 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, + authdef = NULL; + } + ++ /* Option protocol version string (NFSvN) */ ++ if ((ver = virXPathString("string(./protocol/@ver)", ctxt))) { ++ if ((source->format != VIR_STORAGE_POOL_NETFS_NFS) && ++ (source->format != VIR_STORAGE_POOL_NETFS_AUTO)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("storage pool protocol ver unsupported for " ++ "pool type '%s'"), ++ virStoragePoolFormatFileSystemNetTypeToString(source->format)); ++ goto cleanup; ++ } ++ if (virStrToLong_uip(ver, NULL, 0, &source->protocolVer) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("storage pool protocol ver '%s' is malformaed"), ++ ver); ++ goto cleanup; ++ } ++ } ++ + source->vendor = virXPathString("string(./vendor/@name)", ctxt); + source->product = virXPathString("string(./product/@name)", ctxt); + +@@ -956,6 +975,9 @@ virStoragePoolSourceFormat(virBufferPtr buf, + if (src->auth) + virStorageAuthDefFormat(buf, src->auth); + ++ if (src->protocolVer) ++ virBufferAsprintf(buf, "\n", src->protocolVer); ++ + virBufferEscapeString(buf, "\n", src->vendor); + virBufferEscapeString(buf, "\n", src->product); + +diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h +index 15dfd8becf..3b637e2258 100644 +--- a/src/conf/storage_conf.h ++++ b/src/conf/storage_conf.h +@@ -203,6 +203,9 @@ struct _virStoragePoolSource { + * or lvm version, etc. + */ + int format; ++ ++ /* Protocol version value for netfs */ ++ unsigned int protocolVer; + }; + + typedef struct _virStoragePoolTarget virStoragePoolTarget; +diff --git a/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml b/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml +new file mode 100644 +index 0000000000..40f3f94e41 +--- /dev/null ++++ b/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml +@@ -0,0 +1,21 @@ ++ ++ nfsimages ++ 7641d5a8-af11-f730-a34e-0a7dfcede71f ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ /mnt ++ ++ 0700 ++ 0 ++ 0 ++ ++ ++ +diff --git a/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml b/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml +new file mode 100644 +index 0000000000..5fcad1305b +--- /dev/null ++++ b/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml +@@ -0,0 +1,21 @@ ++ ++ nfsimages ++ 7641d5a8-af11-f730-a34e-0a7dfcede71f ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ /mnt ++ ++ 0700 ++ 0 ++ 0 ++ ++ ++ +diff --git a/tests/storagepoolxml2xmltest.c b/tests/storagepoolxml2xmltest.c +index 29c0e42479..cf41b4d065 100644 +--- a/tests/storagepoolxml2xmltest.c ++++ b/tests/storagepoolxml2xmltest.c +@@ -86,6 +86,7 @@ mymain(void) + DO_TEST("pool-iscsi-auth"); + DO_TEST("pool-netfs"); + DO_TEST("pool-netfs-auto"); ++ DO_TEST("pool-netfs-protocol-ver"); + DO_TEST("pool-netfs-gluster"); + DO_TEST("pool-netfs-cifs"); + DO_TEST("pool-scsi"); +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Add-return-value-check-to-virResctrlAllocForeachCache.patch b/SOURCES/libvirt-conf-Add-return-value-check-to-virResctrlAllocForeachCache.patch new file mode 100644 index 0000000..13da8f8 --- /dev/null +++ b/SOURCES/libvirt-conf-Add-return-value-check-to-virResctrlAllocForeachCache.patch @@ -0,0 +1,49 @@ +From 7a8c614b37e0d7e1b2eac08a72f46ef715b72c5a Mon Sep 17 00:00:00 2001 +Message-Id: <7a8c614b37e0d7e1b2eac08a72f46ef715b72c5a@dist-git> +From: Bing Niu +Date: Mon, 15 Apr 2019 17:32:59 +0200 +Subject: [PATCH] conf: Add return value check to virResctrlAllocForeachCache +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add return value check to virResctrlAllocForeachCache in +virDomainCachetuneDefFormat. The virResctrlAllocForeachCache does have +return value, so need check return value to make sure function executed +without error. + +Signed-off-by: Bing Niu +Reviewed-by: John Ferlan +(cherry picked from commit 8d6f508e64728f9aaa5a624462ac0da325854cad) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650 + +Signed-off-by: Pavel Hrdina +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 2f56c077a9..74781fe596 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -27258,10 +27258,10 @@ virDomainCachetuneDefFormat(virBufferPtr buf, + int ret = -1; + + virBufferSetChildIndent(&childrenBuf, buf); +- virResctrlAllocForeachCache(resctrl->alloc, +- virDomainCachetuneDefFormatHelper, +- &childrenBuf); +- ++ if (virResctrlAllocForeachCache(resctrl->alloc, ++ virDomainCachetuneDefFormatHelper, ++ &childrenBuf) < 0) ++ goto cleanup; + + if (virBufferCheckError(&childrenBuf) < 0) + goto cleanup; +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Add-support-for-memorytune-XML-processing-for-resctrl-MBA.patch b/SOURCES/libvirt-conf-Add-support-for-memorytune-XML-processing-for-resctrl-MBA.patch new file mode 100644 index 0000000..2d34310 --- /dev/null +++ b/SOURCES/libvirt-conf-Add-support-for-memorytune-XML-processing-for-resctrl-MBA.patch @@ -0,0 +1,503 @@ +From 1240e6d5b3d53a34a94b308ddf2f10a12f2556f6 Mon Sep 17 00:00:00 2001 +Message-Id: <1240e6d5b3d53a34a94b308ddf2f10a12f2556f6@dist-git> +From: Bing Niu +Date: Mon, 15 Apr 2019 17:32:58 +0200 +Subject: [PATCH] conf: Add support for memorytune XML processing for resctrl + MBA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce a new section memorytune to support memory bandwidth allocation. +This is consistent with existing cachetune. As the example: +below: + + ...... + + + + + +vpus --- vpus subjected to this memory bandwidth. +id --- on which node memory bandwidth to be set. +bandwidth --- the memory bandwidth percent to set. + +Signed-off-by: Bing Niu +Reviewed-by: John Ferlan +(cherry picked from commit 6956b7eedce4cb6dc2f95684fc3e10c163dfc6fc) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650 + +Signed-off-by: Pavel Hrdina +Message-Id: <3139e3b8f3c3d66891847b5a99bd9125ec01f00b.1555342313.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + docs/formatdomain.html.in | 39 +++- + docs/schemas/domaincommon.rng | 17 ++ + src/conf/domain_conf.c | 200 ++++++++++++++++++ + .../memorytune-colliding-allocs.xml | 30 +++ + .../memorytune-colliding-cachetune.xml | 32 +++ + tests/genericxml2xmlindata/memorytune.xml | 33 +++ + tests/genericxml2xmltest.c | 5 + + 7 files changed, 355 insertions(+), 1 deletion(-) + create mode 100644 tests/genericxml2xmlindata/memorytune-colliding-allocs.xml + create mode 100644 tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml + create mode 100644 tests/genericxml2xmlindata/memorytune.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 42acf7a828..8cf2c12524 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -757,6 +757,10 @@ + <cache id='0' level='3' type='both' size='3' unit='MiB'/> + <cache id='1' level='3' type='both' size='3' unit='MiB'/> + </cachetune> ++ <memorytune vcpus='0-3'> ++ <node id='0' bandwidth='60'/> ++ </memorytune> ++ + </cputune> + ... + </domain> +@@ -910,7 +914,9 @@ + size and required granularity are reported as well. The required + attribute vcpus specifies to which vCPUs this allocation + applies. A vCPU can only be member of one cachetune element +- allocations. Supported subelements are: ++ allocation. The vCPUs specified by cachetune can be identical with those ++ in memorytune, however they are not allowed to overlap. ++ Supported subelements are: +
+
cache
+
+@@ -950,7 +956,38 @@ +
+
+
++ + ++
memorytuneSince 4.7.0
++
++ Optional memorytune element can control allocations for ++ memory bandwidth using the resctrl on the host. Whether or not is this ++ supported can be gathered from capabilities where some limitations like ++ minimum bandwidth and required granularity are reported as well. The ++ required attribute vcpus specifies to which vCPUs this ++ allocation applies. A vCPU can only be member of one ++ memorytune element allocation. The vcpus specified ++ by memorytune can be identical to those specified by ++ cachetune. However they are not allowed to overlap each other. ++ Supported subelements are: ++
++
node
++
++ This element controls the allocation of CPU memory bandwidth and has the ++ following attributes: ++
++
id
++
++ Host node id from which to allocate memory bandwidth. ++
++
bandwidth
++
++ The memory bandwidth to allocate from this node. The value by default ++ is in percentage. ++
++
++
++
+
+ + +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index ac04af51a1..48f0637cad 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -983,6 +983,23 @@ + +
+ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + +
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 44bfd75b72..2f56c077a9 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19296,6 +19296,129 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + } + + ++static int ++virDomainMemorytuneDefParseMemory(xmlXPathContextPtr ctxt, ++ xmlNodePtr node, ++ virResctrlAllocPtr alloc) ++{ ++ xmlNodePtr oldnode = ctxt->node; ++ unsigned int id; ++ unsigned int bandwidth; ++ char *tmp = NULL; ++ int ret = -1; ++ ++ ctxt->node = node; ++ ++ tmp = virXMLPropString(node, "id"); ++ if (!tmp) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing memorytune attribute 'id'")); ++ goto cleanup; ++ } ++ if (virStrToLong_uip(tmp, NULL, 10, &id) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid memorytune attribute 'id' value '%s'"), ++ tmp); ++ goto cleanup; ++ } ++ VIR_FREE(tmp); ++ ++ tmp = virXMLPropString(node, "bandwidth"); ++ if (!tmp) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing memorytune attribute 'bandwidth'")); ++ goto cleanup; ++ } ++ if (virStrToLong_uip(tmp, NULL, 10, &bandwidth) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid memorytune attribute 'bandwidth' value '%s'"), ++ tmp); ++ goto cleanup; ++ } ++ VIR_FREE(tmp); ++ if (virResctrlAllocSetMemoryBandwidth(alloc, id, bandwidth) < 0) ++ goto cleanup; ++ ++ ret = 0; ++ cleanup: ++ ctxt->node = oldnode; ++ VIR_FREE(tmp); ++ return ret; ++} ++ ++ ++static int ++virDomainMemorytuneDefParse(virDomainDefPtr def, ++ xmlXPathContextPtr ctxt, ++ xmlNodePtr node, ++ unsigned int flags) ++{ ++ xmlNodePtr oldnode = ctxt->node; ++ xmlNodePtr *nodes = NULL; ++ virBitmapPtr vcpus = NULL; ++ virResctrlAllocPtr alloc = NULL; ++ ssize_t i = 0; ++ int n; ++ int ret = -1; ++ bool new_alloc = false; ++ ++ ctxt->node = node; ++ ++ if (virDomainResctrlParseVcpus(def, node, &vcpus) < 0) ++ goto cleanup; ++ ++ if (virBitmapIsAllClear(vcpus)) { ++ ret = 0; ++ goto cleanup; ++ } ++ ++ if ((n = virXPathNodeSet("./node", ctxt, &nodes)) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Cannot extract memory nodes under memorytune")); ++ goto cleanup; ++ } ++ ++ if (virDomainResctrlVcpuMatch(def, vcpus, &alloc) < 0) ++ goto cleanup; ++ ++ if (!alloc) { ++ alloc = virResctrlAllocNew(); ++ if (!alloc) ++ goto cleanup; ++ new_alloc = true; ++ } else { ++ alloc = virObjectRef(alloc); ++ } ++ ++ for (i = 0; i < n; i++) { ++ if (virDomainMemorytuneDefParseMemory(ctxt, nodes[i], alloc) < 0) ++ goto cleanup; ++ } ++ if (virResctrlAllocIsEmpty(alloc)) { ++ ret = 0; ++ goto cleanup; ++ } ++ /* ++ * If this is a new allocation, format ID and append to resctrl, otherwise ++ * just update the existing alloc information, which is done in above ++ * virDomainMemorytuneDefParseMemory */ ++ if (new_alloc) { ++ if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0) ++ goto cleanup; ++ vcpus = NULL; ++ alloc = NULL; ++ } ++ ++ ret = 0; ++ cleanup: ++ ctxt->node = oldnode; ++ virObjectUnref(alloc); ++ virBitmapFree(vcpus); ++ VIR_FREE(nodes); ++ return ret; ++} ++ ++ + static virDomainDefPtr + virDomainDefParseXML(xmlDocPtr xml, + xmlNodePtr root, +@@ -19856,6 +19979,18 @@ virDomainDefParseXML(xmlDocPtr xml, + } + VIR_FREE(nodes); + ++ if ((n = virXPathNodeSet("./cputune/memorytune", ctxt, &nodes)) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("cannot extract memorytune nodes")); ++ goto error; ++ } ++ ++ for (i = 0; i < n; i++) { ++ if (virDomainMemorytuneDefParse(def, ctxt, nodes[i], flags) < 0) ++ goto error; ++ } ++ VIR_FREE(nodes); ++ + if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu) < 0) + goto error; + +@@ -27162,6 +27297,68 @@ virDomainCachetuneDefFormat(virBufferPtr buf, + } + + ++static int ++virDomainMemorytuneDefFormatHelper(unsigned int id, ++ unsigned int bandwidth, ++ void *opaque) ++{ ++ virBufferPtr buf = opaque; ++ ++ virBufferAsprintf(buf, ++ "\n", ++ id, bandwidth); ++ return 0; ++} ++ ++ ++static int ++virDomainMemorytuneDefFormat(virBufferPtr buf, ++ virDomainResctrlDefPtr resctrl, ++ unsigned int flags) ++{ ++ virBuffer childrenBuf = VIR_BUFFER_INITIALIZER; ++ char *vcpus = NULL; ++ int ret = -1; ++ ++ virBufferSetChildIndent(&childrenBuf, buf); ++ if (virResctrlAllocForeachMemory(resctrl->alloc, ++ virDomainMemorytuneDefFormatHelper, ++ &childrenBuf) < 0) ++ goto cleanup; ++ ++ if (virBufferCheckError(&childrenBuf) < 0) ++ goto cleanup; ++ ++ if (!virBufferUse(&childrenBuf)) { ++ ret = 0; ++ goto cleanup; ++ } ++ ++ vcpus = virBitmapFormat(resctrl->vcpus); ++ if (!vcpus) ++ goto cleanup; ++ ++ virBufferAsprintf(buf, "alloc); ++ if (!alloc_id) ++ goto cleanup; ++ ++ virBufferAsprintf(buf, " id='%s'", alloc_id); ++ } ++ virBufferAddLit(buf, ">\n"); ++ ++ virBufferAddBuffer(buf, &childrenBuf); ++ virBufferAddLit(buf, "\n"); ++ ++ ret = 0; ++ cleanup: ++ virBufferFreeAndReset(&childrenBuf); ++ VIR_FREE(vcpus); ++ return ret; ++} ++ + static int + virDomainCputuneDefFormat(virBufferPtr buf, + virDomainDefPtr def, +@@ -27267,6 +27464,9 @@ virDomainCputuneDefFormat(virBufferPtr buf, + for (i = 0; i < def->nresctrls; i++) + virDomainCachetuneDefFormat(&childrenBuf, def->resctrls[i], flags); + ++ for (i = 0; i < def->nresctrls; i++) ++ virDomainMemorytuneDefFormat(&childrenBuf, def->resctrls[i], flags); ++ + if (virBufferCheckError(&childrenBuf) < 0) + return -1; + +diff --git a/tests/genericxml2xmlindata/memorytune-colliding-allocs.xml b/tests/genericxml2xmlindata/memorytune-colliding-allocs.xml +new file mode 100644 +index 0000000000..9b8ebaa084 +--- /dev/null ++++ b/tests/genericxml2xmlindata/memorytune-colliding-allocs.xml +@@ -0,0 +1,30 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 4 ++ ++ ++ ++ ++ ++ ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i686 ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml b/tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml +new file mode 100644 +index 0000000000..5416870de2 +--- /dev/null ++++ b/tests/genericxml2xmlindata/memorytune-colliding-cachetune.xml +@@ -0,0 +1,32 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 4 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i686 ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/genericxml2xmlindata/memorytune.xml b/tests/genericxml2xmlindata/memorytune.xml +new file mode 100644 +index 0000000000..ea03e22fc2 +--- /dev/null ++++ b/tests/genericxml2xmlindata/memorytune.xml +@@ -0,0 +1,33 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 4 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i686 ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c +index 7a4fc1eb7a..e6d4ef2a7f 100644 +--- a/tests/genericxml2xmltest.c ++++ b/tests/genericxml2xmltest.c +@@ -140,6 +140,11 @@ mymain(void) + TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); + DO_TEST_FULL("cachetune-colliding-types", false, true, + TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); ++ DO_TEST("memorytune"); ++ DO_TEST_FULL("memorytune-colliding-allocs", false, true, ++ TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); ++ DO_TEST_FULL("memorytune-colliding-cachetune", false, true, ++ TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE); + + DO_TEST("tseg"); + +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch new file mode 100644 index 0000000..ab7257b --- /dev/null +++ b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch @@ -0,0 +1,68 @@ +From bb9521f7e0e8a67f04b5776cccf8b458a16bc94b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 18 Apr 2019 18:43:10 +0200 +Subject: [PATCH] conf: Expose virDomainSCSIDriveAddressIsUsed + +https://bugzilla.redhat.com/show_bug.cgi?id=1692296 + +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: <79f85c93272ac232b81cb80f80d1ba396d557198.1555605741.git.mprivozn@redhat.com> +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 712efbb9f9..1096499831 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -4400,7 +4400,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 5e2f21dea3..390bd81aa0 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2785,6 +2785,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 3325b90535..3000d6ee0a 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-Factor-out-vcpus-overlapping-from-virDomainCachetuneDefParse.patch b/SOURCES/libvirt-conf-Factor-out-vcpus-overlapping-from-virDomainCachetuneDefParse.patch new file mode 100644 index 0000000..f46e7db --- /dev/null +++ b/SOURCES/libvirt-conf-Factor-out-vcpus-overlapping-from-virDomainCachetuneDefParse.patch @@ -0,0 +1,124 @@ +From c00106d41b74d86ee7357ed62399ea7ffb9cd393 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Bing Niu +Date: Mon, 15 Apr 2019 17:32:56 +0200 +Subject: [PATCH] conf: Factor out vcpus overlapping from + virDomainCachetuneDefParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Factor out vcpus overlapping detecting part from +virDomainCachetuneDefParse and introduce virDomainResctrlVcpuMatch. +Instead of allocating virResctrlAllocPtr by default, allocating +virResctrlAllocPtr after confirm vcpus not overlap with existing ones. +And virDomainResctrlVcpuMatch can be reused by other resource control +technologies. virDomainResctrlVcpuMatch can clarify old vcpus overlap +error whether an overlap or a redefinition. + +Signed-off-by: Bing Niu +Reviewed-by: John Ferlan +(cherry picked from commit e5cc7c0a0258530000aa9fd930c649b525b6f801) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 51 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 39 insertions(+), 12 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 07d21f8026..fb5adbcd10 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19077,6 +19077,31 @@ virDomainResctrlParseVcpus(virDomainDefPtr def, + } + + ++static int ++virDomainResctrlVcpuMatch(virDomainDefPtr def, ++ virBitmapPtr vcpus, ++ virResctrlAllocPtr *alloc) ++{ ++ ssize_t i = 0; ++ ++ for (i = 0; i < def->nresctrls; i++) { ++ /* vcpus group has been created, directly use the existing one. ++ * Just updating memory allocation information of that group ++ */ ++ if (virBitmapEqual(def->resctrls[i]->vcpus, vcpus)) { ++ *alloc = def->resctrls[i]->alloc; ++ break; ++ } ++ if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Overlapping vcpus in resctrls")); ++ return -1; ++ } ++ } ++ return 0; ++} ++ ++ + static int + virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt, + xmlNodePtr node, +@@ -19160,7 +19185,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + xmlNodePtr oldnode = ctxt->node; + xmlNodePtr *nodes = NULL; + virBitmapPtr vcpus = NULL; +- virResctrlAllocPtr alloc = virResctrlAllocNew(); ++ virResctrlAllocPtr alloc = NULL; + virDomainResctrlDefPtr tmp_resctrl = NULL; + char *tmp = NULL; + char *vcpus_str = NULL; +@@ -19171,9 +19196,6 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + + ctxt->node = node; + +- if (!alloc) +- goto cleanup; +- + if (VIR_ALLOC(tmp_resctrl) < 0) + goto cleanup; + +@@ -19191,6 +19213,19 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + goto cleanup; + } + ++ if (virDomainResctrlVcpuMatch(def, vcpus, &alloc) < 0) ++ goto cleanup; ++ ++ if (!alloc) { ++ alloc = virResctrlAllocNew(); ++ if (!alloc) ++ goto cleanup; ++ } else { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Identical vcpus in cachetunes found")); ++ goto cleanup; ++ } ++ + for (i = 0; i < n; i++) { + if (virDomainCachetuneDefParseCache(ctxt, nodes[i], alloc) < 0) + goto cleanup; +@@ -19201,14 +19236,6 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + goto cleanup; + } + +- for (i = 0; i < def->nresctrls; i++) { +- if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Overlapping vcpus in cachetunes")); +- goto cleanup; +- } +- } +- + /* We need to format it back because we need to be consistent in the naming + * even when users specify some "sub-optimal" string there. */ + VIR_FREE(vcpus_str); +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Factor-out-vcpus-parsing-part-from-virDomainCachetuneDefParse.patch b/SOURCES/libvirt-conf-Factor-out-vcpus-parsing-part-from-virDomainCachetuneDefParse.patch new file mode 100644 index 0000000..461216f --- /dev/null +++ b/SOURCES/libvirt-conf-Factor-out-vcpus-parsing-part-from-virDomainCachetuneDefParse.patch @@ -0,0 +1,99 @@ +From ca59034c25fe39acb246f82587c0c32ba04d6c89 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Bing Niu +Date: Mon, 15 Apr 2019 17:32:55 +0200 +Subject: [PATCH] conf: Factor out vcpus parsing part from + virDomainCachetuneDefParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Extract vcpus parsing part from virDomainCachetuneDefParse into one +function called virDomainResctrlParseVcpus. So that vcpus parsing logic +can be reused by other resource control technologies. Adjust error +message and use node->name so that the error message can fit to all +technologies. + +Signed-off-by: Bing Niu +Reviewed-by: John Ferlan +(cherry picked from commit 6021c3926ba62a2593f0db63e5413e9663c69a5f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650 + +Signed-off-by: Pavel Hrdina +Message-Id: <2f330b4bbface15dce23370d5f212b2240e031cd.1555342313.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 48 +++++++++++++++++++++++++++++------------- + 1 file changed, 33 insertions(+), 15 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 0c8afe78c6..07d21f8026 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19045,6 +19045,38 @@ virDomainDefParseBootOptions(virDomainDefPtr def, + } + + ++static int ++virDomainResctrlParseVcpus(virDomainDefPtr def, ++ xmlNodePtr node, ++ virBitmapPtr *vcpus) ++{ ++ char *vcpus_str = NULL; ++ int ret = -1; ++ ++ vcpus_str = virXMLPropString(node, "vcpus"); ++ if (!vcpus_str) { ++ virReportError(VIR_ERR_XML_ERROR, _("Missing %s attribute 'vcpus'"), ++ node->name); ++ goto cleanup; ++ } ++ if (virBitmapParse(vcpus_str, vcpus, VIR_DOMAIN_CPUMASK_LEN) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid %s attribute 'vcpus' value '%s'"), ++ node->name, vcpus_str); ++ goto cleanup; ++ } ++ ++ /* We need to limit the bitmap to number of vCPUs. If there's nothing left, ++ * then we can just clean up and return 0 immediately */ ++ virBitmapShrink(*vcpus, def->maxvcpus); ++ ++ ret = 0; ++ cleanup: ++ VIR_FREE(vcpus_str); ++ return ret; ++} ++ ++ + static int + virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt, + xmlNodePtr node, +@@ -19145,22 +19177,8 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + if (VIR_ALLOC(tmp_resctrl) < 0) + goto cleanup; + +- vcpus_str = virXMLPropString(node, "vcpus"); +- if (!vcpus_str) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Missing cachetune attribute 'vcpus'")); ++ if (virDomainResctrlParseVcpus(def, node, &vcpus) < 0) + goto cleanup; +- } +- if (virBitmapParse(vcpus_str, &vcpus, VIR_DOMAIN_CPUMASK_LEN) < 0) { +- virReportError(VIR_ERR_XML_ERROR, +- _("Invalid cachetune attribute 'vcpus' value '%s'"), +- vcpus_str); +- goto cleanup; +- } +- +- /* We need to limit the bitmap to number of vCPUs. If there's nothing left, +- * then we can just clean up and return 0 immediately */ +- virBitmapShrink(vcpus, def->maxvcpus); + + if (virBitmapIsAllClear(vcpus)) { + ret = 0; +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Factor-out-virDomainResctrlDef-update-from-virDomainCachetuneDefParse.patch b/SOURCES/libvirt-conf-Factor-out-virDomainResctrlDef-update-from-virDomainCachetuneDefParse.patch new file mode 100644 index 0000000..c8b844e --- /dev/null +++ b/SOURCES/libvirt-conf-Factor-out-virDomainResctrlDef-update-from-virDomainCachetuneDefParse.patch @@ -0,0 +1,164 @@ +From 7551c4a8b453278e7a27a8e7a722851af1f23efc Mon Sep 17 00:00:00 2001 +Message-Id: <7551c4a8b453278e7a27a8e7a722851af1f23efc@dist-git> +From: Bing Niu +Date: Mon, 15 Apr 2019 17:32:57 +0200 +Subject: [PATCH] conf: Factor out virDomainResctrlDef update from + virDomainCachetuneDefParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Factor out vcpus virDomainResctrlDef update from +virDomainCachetuneDefParse and introduce virDomainResctrlAppend. +virDomainResctrlAppend will format vcpus string and append a new +virDomainResctrlDef to virDomainDefPtr. So that this logic can +be reusable. + +Signed-off-by: Bing Niu +Reviewed-by: John Ferlan +(cherry picked from commit 72824f67cdb9c474034539e81fb03fb1bc94495f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 93 +++++++++++++++++++++++++----------------- + 1 file changed, 55 insertions(+), 38 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index fb5adbcd10..44bfd75b72 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19176,6 +19176,58 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt, + } + + ++static int ++virDomainResctrlAppend(virDomainDefPtr def, ++ xmlNodePtr node, ++ virResctrlAllocPtr alloc, ++ virBitmapPtr vcpus, ++ unsigned int flags) ++{ ++ char *vcpus_str = NULL; ++ char *alloc_id = NULL; ++ virDomainResctrlDefPtr tmp_resctrl = NULL; ++ int ret = -1; ++ ++ if (VIR_ALLOC(tmp_resctrl) < 0) ++ goto cleanup; ++ ++ /* We need to format it back because we need to be consistent in the naming ++ * even when users specify some "sub-optimal" string there. */ ++ vcpus_str = virBitmapFormat(vcpus); ++ if (!vcpus_str) ++ goto cleanup; ++ ++ if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) ++ alloc_id = virXMLPropString(node, "id"); ++ ++ if (!alloc_id) { ++ /* The number of allocations is limited and the directory structure is flat, ++ * not hierarchical, so we need to have all same allocations in one ++ * directory, so it's nice to have it named appropriately. For now it's ++ * 'vcpus_...' but it's designed in order for it to be changeable in the ++ * future (it's part of the status XML). */ ++ if (virAsprintf(&alloc_id, "vcpus_%s", vcpus_str) < 0) ++ goto cleanup; ++ } ++ ++ if (virResctrlAllocSetID(alloc, alloc_id) < 0) ++ goto cleanup; ++ ++ tmp_resctrl->vcpus = vcpus; ++ tmp_resctrl->alloc = alloc; ++ ++ if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, tmp_resctrl) < 0) ++ goto cleanup; ++ ++ ret = 0; ++ cleanup: ++ virDomainResctrlDefFree(tmp_resctrl); ++ VIR_FREE(alloc_id); ++ VIR_FREE(vcpus_str); ++ return ret; ++} ++ ++ + static int + virDomainCachetuneDefParse(virDomainDefPtr def, + xmlXPathContextPtr ctxt, +@@ -19186,19 +19238,12 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + xmlNodePtr *nodes = NULL; + virBitmapPtr vcpus = NULL; + virResctrlAllocPtr alloc = NULL; +- virDomainResctrlDefPtr tmp_resctrl = NULL; +- char *tmp = NULL; +- char *vcpus_str = NULL; +- char *alloc_id = NULL; + ssize_t i = 0; + int n; + int ret = -1; + + ctxt->node = node; + +- if (VIR_ALLOC(tmp_resctrl) < 0) +- goto cleanup; +- + if (virDomainResctrlParseVcpus(def, node, &vcpus) < 0) + goto cleanup; + +@@ -19236,45 +19281,17 @@ virDomainCachetuneDefParse(virDomainDefPtr def, + goto cleanup; + } + +- /* We need to format it back because we need to be consistent in the naming +- * even when users specify some "sub-optimal" string there. */ +- VIR_FREE(vcpus_str); +- vcpus_str = virBitmapFormat(vcpus); +- if (!vcpus_str) +- goto cleanup; +- +- if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) +- alloc_id = virXMLPropString(node, "id"); +- +- if (!alloc_id) { +- /* The number of allocations is limited and the directory structure is flat, +- * not hierarchical, so we need to have all same allocations in one +- * directory, so it's nice to have it named appropriately. For now it's +- * 'vcpus_...' but it's designed in order for it to be changeable in the +- * future (it's part of the status XML). */ +- if (virAsprintf(&alloc_id, "vcpus_%s", vcpus_str) < 0) +- goto cleanup; +- } +- +- if (virResctrlAllocSetID(alloc, alloc_id) < 0) +- goto cleanup; +- +- VIR_STEAL_PTR(tmp_resctrl->vcpus, vcpus); +- VIR_STEAL_PTR(tmp_resctrl->alloc, alloc); +- +- if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, tmp_resctrl) < 0) ++ if (virDomainResctrlAppend(def, node, alloc, vcpus, flags) < 0) + goto cleanup; ++ vcpus = NULL; ++ alloc = NULL; + + ret = 0; + cleanup: + ctxt->node = oldnode; +- virDomainResctrlDefFree(tmp_resctrl); + virObjectUnref(alloc); + virBitmapFree(vcpus); +- VIR_FREE(alloc_id); +- VIR_FREE(vcpus_str); + VIR_FREE(nodes); +- VIR_FREE(tmp); + return ret; + } + +-- +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..6aaabd5 --- /dev/null +++ b/SOURCES/libvirt-conf-Fix-a-error-msg-typo-in-virDomainVideoDefValidate.patch @@ -0,0 +1,35 @@ +From d10524fd3934bf539b38599eb928b26089d17b52 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-bug-in-finding-alloc-through-matching-vcpus.patch b/SOURCES/libvirt-conf-Fix-bug-in-finding-alloc-through-matching-vcpus.patch new file mode 100644 index 0000000..2d9f402 --- /dev/null +++ b/SOURCES/libvirt-conf-Fix-bug-in-finding-alloc-through-matching-vcpus.patch @@ -0,0 +1,52 @@ +From 408d9e217f05b6c68351804df56aa9c9af7db4e7 Mon Sep 17 00:00:00 2001 +Message-Id: <408d9e217f05b6c68351804df56aa9c9af7db4e7@dist-git> +From: Wang Huaqiang +Date: Mon, 15 Apr 2019 17:33:01 +0200 +Subject: [PATCH] conf: Fix bug in finding alloc through matching vcpus +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The @alloc object returned by virDomainResctrlVcpuMatch is not +properly referenced and un-referenced in virDomainCachetuneDefParse. + +This patch fixes this problem. + +Signed-off-by: Wang Huaqiang +Reviewed-by: John Ferlan +(cherry picked from commit 3a1cdb06fd9bc5e35230f6198e697d6ec03d1206) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1468650 + +Signed-off-by: Pavel Hrdina +Message-Id: <7049386040dc0d170193b5fbfc81f2a8335d0063.1555342313.git.phrdina@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 74781fe596..6af14cc06f 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -19089,7 +19089,7 @@ virDomainResctrlVcpuMatch(virDomainDefPtr def, + * Just updating memory allocation information of that group + */ + if (virBitmapEqual(def->resctrls[i]->vcpus, vcpus)) { +- *alloc = def->resctrls[i]->alloc; ++ *alloc = virObjectRef(def->resctrls[i]->alloc); + break; + } + if (virBitmapOverlaps(def->resctrls[i]->vcpus, vcpus)) { +@@ -19386,8 +19386,6 @@ virDomainMemorytuneDefParse(virDomainDefPtr def, + if (!alloc) + goto cleanup; + new_alloc = true; +- } else { +- alloc = virObjectRef(alloc); + } + + for (i = 0; i < n; i++) { +-- +2.21.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..8b03303 --- /dev/null +++ b/SOURCES/libvirt-conf-Fix-check-for-chardev-source-path.patch @@ -0,0 +1,112 @@ +From dc638f4d9fea8647a190dc9d2dabc4ce81ab2a3c Mon Sep 17 00:00:00 2001 +Message-Id: +From: Andrea Bolognani +Date: Wed, 3 Apr 2019 17:08:57 +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) +Signed-off-by: Andrea Bolognani +Message-Id: <20190403150857.20850-1-abologna@redhat.com> +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 eb4e9ac523..712efbb9f9 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -5531,11 +5531,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 d97dc0ea8d..7a731e2f40 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.21.0 + 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..5a7084e --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-new-hostdev-attribute-display.patch @@ -0,0 +1,416 @@ +From 2d16cb96407ed22af46b892e3319f04ac61924ed Mon Sep 17 00:00:00 2001 +Message-Id: <2d16cb96407ed22af46b892e3319f04ac61924ed@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 ++ ++ ++ ++ ++
++ ++ ++
++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++